12 Example Game

In this section there’s presented the code for the example game, I’ll be covering just those parts that are different to the Pygame example, which was explained in the previous chapter.

You can find the listing in the file Example Game.py which is available to download from the web site. In the game you control your player’s tank by pressing the left and right arrow keys, and the space bar is used to fire a shot. To quit, click the window’s close icon.

(The example game is a rewritten and simplified version of one called Aliens which comes with Pygame.)

#    1 Constants
PLAYERSPEED = 5
ALIENSPEED = 5
ALIENCOUNTDOWN = 80

The ALIENSPEED value of 5 is the number of pixels it moves each frame. ALIENCOUNTDOWN is the number of frames before a new alien is created, in this case 80 frames is equal to 2 seconds.

#    2 aliens variables
booNewAlienR= False
lolAliens = []
intAlienCountdown = ALIENCOUNTDOWN

booNewAlienR controls which side of the screen a new alien is created on. If this variable is True the alien starts on the right, if it’s False it begins on the left. lolAliens is a blank list, we will add items to it when each new alien is created. intAlienCountdown is a variable that controls how often new aliens are created.

#    3 misc variables
lolExplosions = []
intScore = 0
booShotActive = False
booKeepPlaying = True

lolExplosions is a blank list, we add items to it when an alien is destroyed. intScore is the player’s score, 1 point is given for each alien shot down. booShotActive indicates whether the player has fired a shot, only one shot can be fired at a time. booKeepPlaying controls the main loop, while it’s True the game keeps on rolling.

#    4 respond to key presses
keyInput = pygame.key.get_pressed()

if keyInput[K_RIGHT] and recPlayer.x < 560:
recPlayer.x += PLAYERSPEED
if keyInput[K_LEFT] and recPlayer.x > 0:
recPlayer.x -= PLAYERSPEED

The player moves horizontally left and right when the user presses the left and right arrow keys. We also check the player’s x coordinate to prevent movement beyond the edges of the display.

#    5 fire shot?

if keyInput[K_SPACE] and booShotActive==False:
booShotActive= True
recShot = Rect(recPlayer.x+50,380, surShot.get_width(), surShot.get_height())
sndShoot.play()

We create a new bullet if the user presses the space bar and a shot doesn’t already exist. First booShotActive is set to True and then we create a rectangle object for the shot to enable collision detection with the aliens. Finally a sound effect is played.

#    6 create alien?
intAlienCountdown -= 1
if intAlienCountdown == 0:
intAlienCountdown= ALIENCOUNTDOWN

if booNewAlienR == True:
recAlien = Rect(600,0, surAlien.get_width(), surAlien.get_height())
booAlienMoveR= False

else:
recAlien = Rect(0,0, surAlien.get_width(), surAlien.get_height())
booAlienMoveR= True

lolAliens.append ([booAlienMoveR,recAlien])

booNewAlienR = not booNewAlienR

We want to keep making new aliens appear at the top of the screen every couple of seconds. The countdown variable is decremented every frame, and once it reaches zero it’s time to create a new alien. First the countdown timer is reset to maximum, then there’s a test of booNewAlienR to decide on which side of the screen to create the alien (it alternates between left and right.) A rectangle object for the new alien is created, whose x horizontal coordinate depends on which side of the screen we want it to appear. Also booAlienMoveR is set according to the direction is should move. Finally, a new alien is added to the existing list of aliens, composed of a boolean variable and a rectangle object. Then booNewAlienR is reversed so that the next alien which is created starts on the opposite side of the display.

#    7 move player's shot
if booShotActive== True:
recShot.y -= 10
if recShot.y <= 0:
booShotActive = False

If a bullet exists then we want to move it up the screen. This is done by decreasing the y or vertical position by 10 pixels each frame. Once the y coordinate equals 0 which is the top of the screen, we want to destroy the bullet and this is done by changing the booShotActive status to False.

#    8 move alien
for lisAlien in lolAliens:
booAlienMoveR = lisAlien[0]

if booAlienMoveR:
lisAlien[1].x += ALIENSPEED
if (lisAlien[1].x >= 550):
lisAlien[0] = False
lisAlien[1].y += 50

if booAlienMoveR == False:
lisAlien[1].x -= ALIENSPEED
if (lisAlien[1].x <= 0):
lisAlien[0] = True
lisAlien[1].y += 50

We want the aliens to traverse horizontally across the display, and when they reach either edge to move them down the screen. We go through the list of aliens and get the booAlienMoveR variable which is index 0 in the list. If the alien is moving right then its horizontal x position is increased by ALIENSPEED. once it reaches the edge of the screen it’s moved downwards by adding 50 onto the vertical y coordinate, and booAlienMoveR is set to false to make it move in the opposite direction (left in this case.)

#    9 detect alien collision with player
for lisAlien in lolAliens:

if recPlayer.colliderect (lisAlien[1])==True:
booKeepPlaying = False
sndBoom.play()
surScreen.blit(surExplosion, (recPlayer.x,recPlayer.y))
pygame.display.flip()

We want to detect if there’s a collision between an alien and the player, if there is it’s game over, the player just has one life. We go through the list of aliens and test if there is a collision between the alien’s rectangle (a list index of 1) and the player’s rectangle. If there is then booKeepPlaying is set to False which ends the game. Also, a sound is played and an explosion drawn at the player’s position, which is displayed with the flip() function.

#    10 detect alien collision with player's shot
if booShotActive== True:

for lisAlien in lolAliens:

if recShot.colliderect (lisAlien[1])==True:
lolAliens.remove(lisAlien)
booShotActive = False
sndBoom.play()
intScore += 1
recExplosion = Rect (lisAlien[1].x,lisAlien[1].y, surExplosion.get_width(), surExplosion.get_height())
lolExplosions.append ([40,recExplosion])

break #exit the loop, therefore our shot can only kill 1 alien

Here we want to detect if the player’s bullet hits an alien, and if it does create an explosion and destroy the alien. First there’s a test to see if a bullet exists and if it does we go through the list of aliens to see if there’s a collision with it. If there is then the following happens: the alien is eliminated by removing it from the list, the bullet is destroyed by setting booShotActive to False, a sound effect is played and the player’s score is increased by 1. Next an explosion is created, which is made up of an integer (40) and a rectangle object, with the x and y coordinates taken from the alien that was destroyed (the explosion appears in place of the alien.) The number 40 is the number of frames for the duration of the explosion to last, 40 frames being 1 second. Finally there’s a break command which exits the for loop, meaning the bullet is only capable of destroying one alien.

#    11 countdown to removing explosions
for lisExplosion in lolExplosions:

lisExplosion[0] -= 1
if lisExplosion[0] == 0:
lolExplosions.remove (lisExplosion)

We want explosion graphics to appear for a short time and then be removed, not stay on the display indefinitely. This controls their removal after a certain time period. We go through the list of explosions and look at the 0 index which holds a value for how many frames the explosion should appear for. It is reduced by 1 each frame and when it equals 0 the explosion is removed from the list and won’t be displayed on the screen any longer.

Comic Relief
There’s a band called 1023 MB.
They haven’t had any gigs yet.

<– back to contents