10. Tutorial: Shooting game

In this chapter we will build a shooting game together, step by step. The Python we will use is: conditionals, loops, lists and functions.

10.1. Step 1: Decide what Actors you will need

Our game will need these Actors, so we must create images for all of them and save them as .png files in the images folder.

variable name

image file name

image size

player

player.png

64x64

background

background.png

600x800

enemies (list)

enemy.png

64x64

bullets (list)

bullet.png

16x16

bombs (list)

bomb.png

16x16

The player and background variables will contain Actors. The others are lists which we initialize to the empty list []. Actors will be appended to the lists later.

Program 10.1 Shooter game part 1 of 4
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16

import random

WIDTH = 600
HEIGHT = 800
MAX_BULLETS = 3

level = 1
lives = 3
score = 0

background = Actor("background")
player = Actor("player", (200, 580))
enemies = []
bullets = []
bombs = []

10.2. Step 2: Draw your Actors

Every Pygame game needs an draw() function, and it should draw all the Actors we created above.

Program 10.2 Shooter game part 2 of 4
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12

def draw():
    screen.clear()
    background.draw()
    player.draw()
    for enemy in enemies:
        enemy.draw()
    for bullet in bullets:
        bullet.draw()
    for bomb in bombs:
        bomb.draw()
    draw_text()

10.3. Step 3: Move your Actors

Every Pygame game needs an update() function to move the Actors, check for collisions, etc.

Program 10.3 Shooter game part 3 of 4
1
2
3
4
5
6
7
8

def update(delta):
    move_player()
    move_bullets()
    move_enemies()
    create_bombs()
    move_bombs()
    check_for_end_of_level()

Exercise

Create the png image files (player.png, background.png, bullet.png, bomb.png, enemy.png). Type in program Program 10.1, Program 10.2 and Program 10.3 into a single file. Save the file. Why doesn’t it run?

10.4. Step 4: Define your functions

Python cannot call a function that has not yet been defined. Therefore we must at least provide empty, dummy versions of our functions that don’t do anything so we can fill them in later. However Python cannot define a completely empty function - it must contain at least one line. Therefore we use the pass keyword to create a line that doesn’t do anything.

Program 10.4 Shooter game part 4 of 4
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21

def move_player():
    pass

def move_enemies():
    pass

def move_bullets():
    pass

def create_bombs():
    pass

def move_bombs():
    pass

def check_for_end_of_level():
    pass

def draw_text():
    pass

Exercise

Add listing Program 10.4 to the end of the file. Verify the game now runs and you can see the player at the bottom of the screen. (He can’t move yet.)

10.5. Create enemies

Add this new function to the end of the program, and then call it immediately. It uses a loop within a loop to create enemy Actors and put them in the enemies list. The reason we put this in a function is we will need to call it again at the start of each level.

def create_enemies():
    for x in range(0, 600, 60):
        for y in range(0, 200, 60):
            enemy = Actor("enemy", (x, y))
            enemy.vx = level * 2
            enemies.append(enemy)


create_enemies()

10.6. Move the player

Replace the move_player() dummy function definition with this. Remember there can only be one function with a given name. There cannot be two ``move_player()`` function definitions.

def move_player():
    if keyboard.right:
        player.x = player.x + 5
    if keyboard.left:
        player.x = player.x - 5
    if player.x > WIDTH:
        player.x = WIDTH
    if player.x < 0:
        player.x = 0

10.7. Move the enemies

Replace the move_enemies() dummy function definition with this:

def move_enemies():
    global score
    for enemy in enemies:
        enemy.x = enemy.x + enemy.vx
        if enemy.x > WIDTH or enemy.x < 0:
            enemy.vx = -enemy.vx
            animate(enemy, duration=0.1, y=enemy.y + 60)
        for bullet in bullets:
            if bullet.colliderect(enemy):
                enemies.remove(enemy)
                bullets.remove(bullet)
                score = score + 1
        if enemy.colliderect(player):
            exit()

10.8. Draw text on the screen

Replace the draw_text() dummy function definition with this:

def draw_text():
    screen.draw.text("Level " + str(level), (0, 0), color="red")
    screen.draw.text("Score " + str(score), (100, 0), color="red")
    screen.draw.text("Lives " + str(lives), (200, 0), color="red")

10.9. Player bullets

Add this new function to the end of the program. Pygame will call it for us automatically when a key is pressed.

def on_key_down(key):
    if key == keys.SPACE and len(bullets) < MAX_BULLETS:
        bullet = Actor("bullet", pos=(player.x, player.y))
        bullets.append(bullet)

Replace the move_bullets() dummy function definition with this:

def move_bullets():
    for bullet in bullets:
        bullet.y = bullet.y - 6
        if bullet.y < 0:
            bullets.remove(bullet)

10.10. Enemy bombs

Replace the create_bombs() dummy function definition with this:

def create_bombs():
    if random.randint(0, 100 - level * 6) == 0:
        enemy = random.choice(enemies)
        bomb = Actor("bomb", enemy.pos)
        bombs.append(bomb)

Replace the move_bombs() dummy function definition with this:

def move_bombs():
    global lives
    for bomb in bombs:
        bomb.y = bomb.y + 10
        if bomb.colliderect(player):
            bombs.remove(bomb)
            lives = lives - 1
            if lives == 0:
                exit()

10.11. Check for end of level

Replace the check_for_end_of_level() dummy function definition with this:

def check_for_end_of_level():
    global level
    if len(enemies) == 0:
        level = level + 1
        create_enemies()

10.12. Ideas for extension

  • Draw an explosion image and create an explosion Actor every time an alien dies.

  • Make the explosion Actor disappear after a short time.

  • Draw several explosion images, put them in a list and make the Actor animate displaying each of them in order.

  • The player can only fire 3 bullets at a time. Create a powerup that allows him to fire additional bullets.

  • Add music and sound effects.