## Sunday, 6 September 2015

### Pygame Zero - Pong

I wanted to explore Pygame Zero so I gave myself a challenge of creating a version of Pong.

My first piece of learning from the experience just reconfirms something I already knew - games development is hard!  Pygame Zero takes some of the pain and is certainly a lot easier to get started with than Pygame, but there is still a lot of work to do for game like Pong.

The second thing I learnt is that I didn't know how Pong worked! This page which describes how the balls reacts when it hits a paddle is really useful.

You will find all the code on github https://github.com/martinohanlon/pgzero-pong.

You control the paddles with Q A (player 1) and K M (player 2).

Its very much unfinished and is missing features like:
• Time limit - the game continues forever
• Scores - the score should be displayed on the screen
• 1 player mode - artificial intelligent 2nd player
Does anyone fancy picking it up?

Code
```from math import sin, cos, radians
from time import sleep

#setup the constants
WIDTH = 500
HEIGHT = 300
BALLSPEED = 10
MAXBOUNCEANGLE = 75

def reset_game(angle):

#setup ball properties
ball.pos = WIDTH / 2, HEIGHT / 2
ball.x_float = float(ball.x)
ball.y_float = float(ball.y)
ball.angle = angle

pad1.pos = 10, HEIGHT / 2
pad2.pos = WIDTH - 10, HEIGHT / 2

#create a rectangle of the playing area
screenRect = Rect(10,0,WIDTH - 10,HEIGHT)

#create ball
ball = Actor('ball')

#reset the game
reset_game(180)

#setup the goals
goals = [0, 0]

def draw():
screen.clear()
ball.draw()

def update():

if keyboard.q:
if keyboard.a:
if keyboard.k:
if keyboard.m:

#move the ball
ball_old_x = ball.x_float
ball_old_y = ball.y_float

ball.x_float = ball.x_float + ball.x_vel
ball.y_float = ball.y_float + ball.y_vel
ball.x = int(round(ball.x_float))
ball.y = int(round(ball.y_float))

#move the ball back to where it was?
reset_ball = False

#has the ball left the screen?
if not screenRect.contains(ball):

#did it hit the top or bottom?
if ball.top < 0 or ball.bottom > HEIGHT:
ball.y_vel *= -1
reset_ball = True

#it must have hit the side
else:
if ball.left < 10:
print("Player 2 goal")
goals += 1
reset_game(180)
sleep(2)
print("Score {} : {}".format(goals, goals))

elif ball.right > WIDTH - 10:
print("player 1 goal")
goals += 1
reset_game(0)
sleep(2)
print("Score {} : {}".format(goals, goals))

#has the ball hit a paddle
#work out the bounce angle
ball.angle = max(0 - MAXBOUNCEANGLE, min(MAXBOUNCEANGLE, bounce_angle))
#work out the ball velocity

reset_ball = True

bounce_angle = 180 - (((ball.y - pad2.y) / (pad2.height / 2)) * MAXBOUNCEANGLE)
ball.angle = max(180 - MAXBOUNCEANGLE, min(180 + MAXBOUNCEANGLE, bounce_angle))

reset_ball = True

if reset_ball:
ball.x_float = ball_old_x
ball.y_float = ball_old_y
ball.x = int(round(ball.x_float))
ball.y = int(round(ball.y_float))```

1. Hi
Trevor Appleton has code for the AI paddle on his page, using Pygame.
I'm working on adding a second player to his code.

http://trevorappleton.blogspot.ie/2014/04/writing-pong-using-python-and-pygame.html

2. Thanks for the game code Martin. I am a teacher trying to use it with my Python class. As a non-programmer I am puzzled by the fact that you set properties such as x_vel and y_vel that do not seem to be defined anywhere. Does the Actor class have such properties built-in?

1. I appeared as "unknown" so have replied this time properly logged in :-)

2. I am using a feature of Python which allows you to create properties of an object at run time, this is a convenient way for me to associate data which relates to the ball (i.e. its velocity in x and y) to the object itself rather than using global variables which are 'a bit dirty' (imho).

3. Properties you can define at runtime! Fantastic! Loving discovering Python. Thanks (Thanks also for your Minecraft book which I own)