Pong in Python vs. Pong in JavaScript: Battle of Introductory Game Dev Tutorials

Battle of the introductory game dev tutorials by myself and my student “Squitato” =>

# Copyright (c) 2018 Peter Kwak (Edited by Chris Pedersen)
# This is free and unencumbered software released into the public domain.
# For more information, please refer to <http://unlicense.org/>
import turtle
# Create Game Window
screen = turtle.Screen()
# screen.setup(500, 400)
screen.screensize(500, 500, "black")
screen.bgcolor("black")
# screen.addshape("Paddle.jpg")
# Create Ping Pong Ball
ball = turtle.Turtle()
ball.penup()
ball.speed(0)
ball.shape("circle")
ball.color("white")
# Create Left Ping Pong Paddle
paddle1 = turtle.Turtle()
paddle1.penup()
paddle1.speed(0)
paddle1.setx(-200)
paddle1.shape("square")
paddle1.shapesize(4.5, 1, 0)
paddle1.fillcolor("white")
# Create Right Ping Pong Paddle
paddle2 = turtle.Turtle()
paddle2.penup()
paddle2.speed(0)
paddle2.setx(200)
paddle2.shape("square")
paddle2.shapesize(4.5, 1, 0)
paddle2.fillcolor("white")
# Create Scoreboard
scoreWriter = turtle.Turtle()
scoreWriter.penup()
scoreWriter.speed(0)
scoreWriter.hideturtle()
scoreWriter.color("white")
# Set Ball Trajectory
rise = 3
run = 3
# Set Score
score1 = 0
score2 = 0
# Create Function Which Will Move Player 1's Paddle Up
def up1():
paddle1.sety(paddle1.ycor() + 50)
# Create Function Which Will Move Player 1's Paddle Down
def down1():
paddle1.sety(paddle1.ycor() - 50)
# Create Function Which Will Move Player 2's Paddle Up
def up2():
paddle2.sety(paddle2.ycor() + 50)
# Create Function Which Will Move Player 2's Paddle Down
def down2():
paddle2.sety(paddle2.ycor() - 50)
# Create Function To Update Scoreboard
def updateScoreboard():
global scoreWriter
global score1
global score2
global ball
scoreWriter.clear()
myFont = ("Arial", 40, "bold")
scoreWriter.goto(-100, 150)
scoreWriter.write(score1, font=myFont)
scoreWriter.goto(100, 150)
scoreWriter.write(score2, font=myFont)
ball.goto(0, 0)
# Set Event Listeners
# These event listeners will listen for button presses (up, down, etc.)
screen.onkey(up1, "w")
screen.onkey(down1, "s")
screen.onkey(up2, "Up")
screen.onkey(down2, "Down")
screen.listen()
# Create Main Game Loop (Simulates Time, Keeps Game Running)
while True:
# Move Ball
ball.goto(ball.xcor() + run, ball.ycor() + rise)
# Detect Top or Bottom Boundary Strike
# (Reverses the Ball's Direction of Travel)
if ball.ycor() > 200 or ball.ycor() < -200:
rise = -rise
# Detect Paddle Strike (Player 1)
# (Also Reverses the Ball's Direction of Travel)
if abs(paddle1.xcor() - ball.xcor()) < 15:
if abs(paddle1.ycor() - ball.ycor()) < 50:
run = -run
# Detect Paddle Strike (Player 2)
# (Also Reverses the Ball's Direction of Travel)
if abs(paddle2.xcor() - ball.xcor()) < 15:
if abs(paddle2.ycor() - ball.ycor()) < 50:
run = -run
# Detect When A Player Scores a Point
if ball.xcor() > 250:
# Increment player1's score by 1 point when his ball
# travels past the paddle of his opponent, player 2.
score1 = score1 + 1
updateScoreboard()
ball.goto(0, 0)
elif ball.xcor() < -250:
# Increment player2's score by 1 point when his ball
# travels past the paddle of his opponent, player 1.
score2 = score2 + 1
updateScoreboard()
ball.goto(0, 0)
# Christine, My Super Sweet AI Goes HERE...
if ball.ycor() > paddle2.ycor() + 25:
paddle2.sety(paddle2.ycor() + 15)
elif ball.ycor() < paddle2.ycor() - 25:
paddle2.sety(paddle2.ycor() - 15)
view raw pong.py hosted with ❤ by GitHub

NOTE: For the PongJS demo, you will need to manually install p5.play.js as it is not available via CDN =>

<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>
<!-- NOTE: Must Download and Install p5.play.js Manually, it is not available via CDN -->
<script src="p5.play.js"></script>
</head>
<body>
<script src="pong.js"></script>
</body>
</html>
view raw pong.html hosted with ❤ by GitHub
//pong clone
//mouse to control both paddles
var paddleA, paddleB, ball, wallTop, wallBottom;
var MAX_SPEED = 10;
function setup() {
createCanvas(800, 400);
//frameRate(6);
paddleA = createSprite(30, height/2, 10, 100);
paddleA.immovable = true;
paddleB = createSprite(width-28, height/2, 10, 100);
paddleB.immovable = true;
wallTop = createSprite(width/2, -30/2, width, 30);
wallTop.immovable = true;
wallBottom = createSprite(width/2, height+30/2, width, 30);
wallBottom.immovable = true;
ball = createSprite(width/2, height/2, 10, 10);
ball.maxSpeed = MAX_SPEED;
paddleA.shapeColor = paddleB.shapeColor =ball.shapeColor = color(255, 255, 255);
ball.setSpeed(MAX_SPEED, -180);
}
function draw() {
background(0);
paddleA.position.y = constrain(mouseY, paddleA.height/2, height-paddleA.height/2);
paddleB.position.y = constrain(mouseY, paddleA.height/2, height-paddleA.height/2);
ball.bounce(wallTop);
ball.bounce(wallBottom);
var swing;
if(ball.bounce(paddleA)) {
swing = (ball.position.y-paddleA.position.y)/3;
ball.setSpeed(MAX_SPEED, ball.getDirection()+swing);
}
if(ball.bounce(paddleB)) {
swing = (ball.position.y-paddleB.position.y)/3;
ball.setSpeed(MAX_SPEED, ball.getDirection()-swing);
}
if(ball.position.x<0) {
ball.position.x = width/2;
ball.position.y = height/2;
ball.setSpeed(MAX_SPEED, 0);
}
if(ball.position.x>width) {
ball.position.x = width/2;
ball.position.y = height/2;
ball.setSpeed(MAX_SPEED, 180);
}
drawSprites();
}
view raw pong.js hosted with ❤ by GitHub
 

ModuleNotFoundError: No module named ‘Tkinter’

This dev tip is brought to you by the developer of MoneyPhone: Personal Expense Tracking for Android and iOS. Consistently spend less than you earn each month and get your finances under control when you start monitoring your expenses with MoneyPhone!

Fret not dear pythoneer, all you need to do to fix this is change Tkinter to tkinter as the name of the module has changed in Python 3. Whoops! Also, make sure to change

print "stuff"
to
print("stuff")
and all will be well!

from tkinter import *
class Application(Frame):
def say_hi(self):
print("hi there, everyone!")
def createWidgets(self):
self.QUIT = Button(self)
self.QUIT["text"] = "QUIT"
self.QUIT["fg"] = "red"
self.QUIT["command"] = self.quit
self.QUIT.pack({"side": "left"})
self.hi_there = Button(self)
self.hi_there["text"] = "Hello",
self.hi_there["command"] = self.say_hi
self.hi_there.pack({"side": "left"})
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
self.createWidgets()
root = Tk()
app = Application(master=root)
app.mainloop()
root.destroy()
view raw hello_tkinter.py hosted with ❤ by GitHub
 

Deal or no Deal? by Alex W.

My Student Alex W just finished up his first app, Deal or No Deal. If you’d like to check it out, you can download the .apk to your Android phone by clicking the SourceForge download button below. Great work Alex!

Download DealOrNoDeal

NOTE: Please make sure to enable installation of apps from unknown sources on your Android device prior to downloading.

Settings > Security > Allow installation of apps from unknown sources

 

Roblox Scripting Lesson 0

Quick little blog post here on how to get started with scripting in Roblox Studio. These two example scripts should be added under the ServerScriptService and the variable names should match the baseplate and part added to your blank starter project =>

local basePlate = game.Workspace.Baseplate
while true do
basePlate.BrickColor = BrickColor.new(1.0, 0.08, 0.58) --hot pink
wait(0.25)
basePlate.BrickColor = BrickColor.new(0.0, 1.0, 0.0) --lime green
wait(0.25)
basePlate.BrickColor = BrickColor.new(0.0, 1.0, 1.0) --aqua
wait(0.25)
basePlate.BrickColor = BrickColor.new(0.0, 1.0, 1.0) --purple
wait(0.25)
basePlate.BrickColor = BrickColor.new(1.0, 1.0, 0.0) --yellow
end
local practicePart = game.Workspace.PracticePart
while true do
practicePart.BrickColor = BrickColor.new(1.0, 0.08, 0.58) --hot pink
wait(0.25)
practicePart.BrickColor = BrickColor.new(0.0, 1.0, 0.0) --lime green
wait(0.25)
practicePart.BrickColor = BrickColor.new(0.0, 1.0, 1.0) --aqua
wait(0.25)
practicePart.BrickColor = BrickColor.new(0.0, 1.0, 1.0) --purple
wait(0.25)
practicePart.BrickColor = BrickColor.new(1.0, 1.0, 0.0) --yellow
end
view raw ChangePartColor.lua hosted with ❤ by GitHub
 

Hello, World Tutorial with Turbolinks by topherPedersen & jaxatax

Really simple two page tutorial on adding Turbolinks magic to your traditional webapp in order to achieve a SPA (singe page application) feel without having to learn a complicated framework like React, Angular or Vue. Simply import Turbolinks, then call Turbolinks.visit() to load your pages in the background with Turbolinks & AJAX =>

<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/turbolinks/5.2.0/turbolinks.js"></script>
<style>
body {
background-color: blue;
}
a {
color: white;
}
</style>
</head>
<body>
<button onclick="Turbolinks.visit('mylink.html');">click me</button>
</body>
</html>
view raw index.html hosted with ❤ by GitHub
view raw mylink.html hosted with ❤ by GitHub
 

Adobe PhoneGap Hello, World APK

I’ve been experimenting at work with Apache-Cordova/Adobe-PhoneGap and am trying to find an easy way to distribute APKS generated using Adobe’s build service. Setting up development machines is probably too much work for the kids I teach, so just wanted to see if I can post an APK easily on my WordPress blog. So without futher ado… My Adobe PhoneGap Build Service Hello World APK =>

Download AdobePhoneGapHelloWorld

 

Wrapping up my Multiplayer PhaserJS/Socket.io Project, and Moving on to Photon

Just finished up with the multiplayer PhaserJS/Socket.io tutorial that I’ve been following along with and using in one of my classes that I teach. If you want to check out the finished project it’s hosted here => http://multiplayerdemo.xyz

I personally was really excited about playing around with NodeJS & Express & Socket.io, but my student happens to be really good at Unity3D and has happened to find a serverless platform-as-a-service style option for multiplayer called Photon that he really likes so… looks like it’s time to learn Photon!

I still don’t know exactly what all of our options are as far as multiplayer client-server options go, but apparently people have a lot of good things to say about Photon Unity 3D Networking (PUN).

 

12 Tutorials on How to Deploy an ExpressJS App to Production Using NGINX

  1. Configure Nginx as a web server and reverse proxy for Nodejs application on AWS Ubuntu 16.04 server
  2. Deploying Express.js website to VPS with Nginx, PM2 and Ubuntu 18.04
  3. Setting up Express with nginx and pm2
  4. How to run node.js server with Nginx
  5. How To Set Up a Node.js Application for Production on Ubuntu 16.04
  6. Production best practices: performance and reliability
  7. Deploying NodeJS using Express with NginX and Let’s Encrypt
  8. Installing Express/Nginx app with SSL using Certbot on Ubuntu 18.04
  9. Node.js Express Nginx

Working with the most advanced student at our school tomorrow and need to post a few references for our lesson, deploying an expressjs app to production. While the above 9 tutorials are pretty good, it looks like this 10th and 11th tutorials from DigitalOcean is probably the best:

And one last tutorial you’ll need to get NGINX setup and configured properly:

 

Smooth Turtle Graphics in Python

My coworker John has been doing some really nice projects with smooth graphics in python using the turtle graphics library lately, so I just wanted to bookmark this series of blog posts I stumbled upon which demonstrates how to smooth out your animations in turtle =>

 

How to turn your Python Script into a Windows Executable (.exe)

Quick little tutorial on how to turn your python script into a real program:

  1. Install PyInstaller using pip
  2. Navigate to the directory containing your python script.
  3. Run PyInstaller
  4. Double click your newly created .exe file located in the dist subdirectory and enjoy!
$ pip install pyinstaller
# make cool python program
$ cd Desktop/PythonPlayground
$ pyinstaller --onefile cool_python_program.py
# double click cool_python_program.py in Desktop/PythonPlayground/dist directory