Skip to main content

Stage 7: Make the Chaser Move

Course progressStage 7 of 10
~70 min
One game, one Trinket

Keep building in the workspace on the right.

This stage is part of the same Crewmate Task Dash project you started in Setup. Type each new code block into the Trinket rail and keep building on the last stage.

Build

simple chase movement

Learn

how direction and timer loops create motion

Ship

a chaser that slowly follows the player

Before you start

Make sure you finished Stage 6: Spawn the Chaser. Your Trinket project should already have a chaser Turtle drawn on the ship in a different color from the player. Open the same file you used last stage and keep building from there.

The big idea

The chaser does not need advanced AI. It can point toward the player, move forward a little, and repeat.

New words
timer loop
a function that asks Turtle to run again after a delay
towards
a Turtle method that finds the angle to a point or Turtle
heading
the direction a Turtle faces
AI
game logic that makes a computer-controlled actor seem smart

Python concept

Trace it

Methods

What it means: A method is a function that belongs to an object. You call it with a dot.

Tiny Python example:

player.forward(20)
screen.listen()

In this game: `chaser.forward(4)`, `chaser.setheading(...)`, and `screen.ontimer(...)` are methods.

Why it matters: Methods tell a specific object to do something. `chaser.forward(4)` moves the chaser, not every Turtle.

Think first

Check: Methods

In `chaser.forward(4)`, what is the object and what is the method?

Check your thinking

`chaser` is the object. `forward` is the method.

Finished game target
Tasks 2/4Score 80
Crewmate playerTask stationShadow chaser

The player moves through the ship, collects tasks, and avoids the chaser. All playable shapes are drawn with Python Turtle code.

Build it

Think first

Timer loop vs forever loop

Why use `ontimer` instead of a `while True` loop in this Turtle game?

Check your thinking

`ontimer` lets Turtle keep responding to key presses between loop runs.

Your turn

Type, run, test

Read the code aloud before you run it. The goal is to understand what changed in the game.
Need a hint?

Add the new code to the same Trinket project. Keep previous stage code unless the stage says to replace a function.

Your turn

Step 1 - Add a game-on switch

`game_on = True` is a flag that means the round is currently playable. Later, the win and lose code will flip it to `False`, and `move_player` and `move_chaser` will both check it before doing anything. One variable, two systems quieted at once.

game_on = True

You should see — nothing visible changes from this line. The flag is a promise to the rest of the code — its real effect shows up in Stage 8 when an ending sets `game_on = False` and movement stops.

Need a hint?

Type and run one step at a time. If this step breaks, fix it before adding the next one.

Your turn

Step 2 - Point the chaser toward the player

`towards(player)` calculates the angle from the chaser to the player. `setheading(...)` then turns the chaser to face that angle. Splitting the work this way makes the AI line read like English: figure out where the player is, then face them.

You should see — once the loop is running in Step 3, the chaser's heading updates every frame. Move the player and the chaser swivels — if you stand still, the chaser arrives in a straight line.

Your turn

Step 3 - Schedule the loop again

`screen.ontimer(game_loop, 80)` tells Turtle to run `game_loop` again 80 milliseconds from now. The function returns, Turtle handles keyboard events, then runs the loop again. A `while True` here would freeze the keyboard out entirely.

You should see — the chaser drifts steadily toward the player while the arrow keys still work. That is the whole reason to use `ontimer` instead of an endless loop — both systems get their turn.

Active coding checkpoint

Your turn

Point the chaser at the player

Complete the missing method call so the chaser turns toward the player before moving.

angle = chaser.towards(player)
chaser.________________(angle)
chaser.forward(4)
Need a hint?

Try this before opening the solution. Type the starter code, then fill in or fix the missing part yourself.

Stuck? Compare carefully
Answer check
Debug compare only

main.py

`towards(player)` calculates the angle. `setheading(angle)` turns the chaser to face that direction.

angle = chaser.towards(player)
chaser.setheading(angle)
chaser.forward(4)
Python code task
Full stage code

main.py

Use this as the stage target after you understand the smaller steps. Add it to your current Trinket file.

game_on = True

def move_chaser():
if not game_on:
return
chaser.setheading(chaser.towards(player))
chaser.forward(4)
draw_chaser()

def game_loop():
check_tasks()
move_chaser()
screen.ontimer(game_loop, 80)

game_loop()
Trace it

Trace the idea

  1. `towards(player)` finds the angle to the player.
  2. `forward(4)` moves only a little each loop.
  3. `ontimer` keeps the loop running without blocking key presses.

Understand it

Trace it

Why this code works

  • This is simple AI: face the player, move forward, repeat. It is not smart, but it creates pressure.
  • The loop does several jobs in order: check tasks, move the chaser, then schedule the next frame.
  • The number `80` is milliseconds. Smaller numbers update more often; larger numbers update less often.

If it breaks

Trace it

Troubleshooting wisdom

If the game freezes the moment it starts — no key works and the chaser does not move — somewhere a `while True` loop is running forever with nothing handing control back to Turtle. Replace the `while` with the `screen.ontimer(game_loop, 80)` pattern. The keyboard wakes up the instant the loop becomes timer-based.

If the chaser moves once and then stops cold, `screen.ontimer(game_loop, 80)` is sitting outside the function. It has to be the last line inside `game_loop`, so each run schedules the next one. Without that, the loop fires exactly once and nothing reschedules it.

If the chaser leaves a trail of old purple stamps behind it, `draw_chaser()` is not wiping the previous frame. Add `chaser.clear()` at the top of the function — that erases the previous stamps before the new ones go down. If Python prints any error along the way, lean on the traceback primer from Stage 3.

Try this

Learning beat

Try this

Three short experiments. Predict before you run, then test your guess.

Predict first
Change `forward(4)` to `forward(12)`. Predict whether the game becomes fair or unfair.
Compare
Try timer delays 40, 80, and 140. Which feels smooth but still controllable?
Connect
How is a timer loop like an animation frame in other games?

Test your stage

  • The chaser moves.
  • The chaser follows the player.
  • Arrow keys still work while the loop runs.