Session 2: Dodge Meteors
Your spaceship drifts in the dark of space while meteors come down from above. Dodge them, or lose a life. The longer you survive, the faster they go. And this time you also build Dojo Defender: the bigger project that grows every session.
What you’ll learn today
- Using lists to keep track of several objects
- Spawning (creating) and removing objects
- Keeping track of lives and showing a game-over screen
- Dojo Defender: adding your own spaceship to the bigger project
Step 0: Setup
- Open Thonny.
- Download the starter via this link, unpack the ZIP and open
main.py. - Click Run. You see your spaceship at the bottom, but no meteors are falling yet.
- Problems? Take a look at Installing Thonny.
Step 1: Let meteors spawn
Fill in the spawn_meteor() function. A meteor is an Actor that starts at the top of the screen at a random x position:
import random
def spawn_meteor():
rock = Actor('meteor')
rock.x = 0
rock.y = random.randint(30, WIDTH - 30)
meteors.append(rock)Call the function in update(), but not every frame, otherwise the screen fills up straight away. The update() function runs 60 times per second. Use that to keep a counter:
See below how fast a meteor moves at different speeds and how many pixels that is per second:
Use a counter:
# at the top, outside the functions:
timer = 0
def update():
global timer
timer += 1
if timer % 60 == 0: # every second (60 frames)
spawn_meteor()Click Run. After a second the first meteor appears, but it doesn’t move yet.
Step 2: ✅ Basic: let meteors fall and disappear
Let all the meteors in the list drop, and remove them when they fall off the screen:
def update():
global timer
timer += 1
if timer % 60 == 0:
spawn_meteor()
for rock in meteors[:]: # [:] = copy so you can remove safely
rock.y += 4
if rock.y > HEIGHT + 30:
meteors.remove(rock)Detecting collisions: If a meteor hits the ship, you lose a life. Add this in the loop:
if rock.colliderect(ship):
meteors.remove(rock)
global lives
lives -= 1
if lives <= 0:
# TODO: game over (step 3)
passStep 3: ⭐ Stretch: game over and speeding up
Game over: Add a variable game_over = False at the top. If lives == 0, set game_over = True. In draw(), show text when game_over is True:
if game_over:
screen.draw.text(
"GAME OVER",
center=(WIDTH / 2, HEIGHT / 2),
color="red",
fontsize=60,
)Stop the movement in update() when game_over is True:
def update():
if game_over:
return
...Raising the speed: Make meteors go faster as the score rises:
snelheid = 3 + score // 5 # every 5 points, +1 speed
rock.y += snelheidStep 4: 🔥 Expert: score and several meteor sizes
Score: Every second you survive, +1 point. Add global score and raise it in update():
if timer % 60 == 0:
global score
score += 1
spawn_meteor()Several sizes: Make small, medium and large meteors. Use a schaal variable and adjust the hitbox:
def spawn_meteor():
rock = Actor('meteor')
rock.x = random.randint(30, WIDTH - 30)
rock.y = 0
rock.schaal = random.choice([0.5, 1.0, 1.5])
meteors.append(rock)Smaller meteors move faster; bigger ones are harder to dodge but give more points.
Dojo Defender
Download the Dojo Defender starter for today. This is the base of the project that grows every session. Today you add your spaceship and make it move with the arrow keys.
Were you not there last time? No problem — download the solution from last time and you can join in straight away.
The complete Dojo Defender worksheet is on the Dojo Defender page.
Showcase
Show your game to a coach and a buddy. How long do you survive? Who gets the highest score?
See you next time!
“Next time: your own spaceship SHOOTS BACK. Enemies in formation, and you blast them away.”
Take it home
- Easy: change the background colour to deep purple or dark green.
- Medium: add a sound when a meteor hits the ship (
sounds/hit.wav). - Hard: make meteors faster as there are more of them on the screen (not just the score).
- Very hard: add power-ups: a golden star that gives you an extra life when you touch it.