Stage 7: Make the Chaser Move
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.
simple chase movement
how direction and timer loops create motion
a chaser that slowly follows the player
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.
- 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
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.
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.
The player moves through the ship, collects tasks, and avoids the chaser. All playable shapes are drawn with Python Turtle code.
Build it
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.
Type, run, test
Need a hint?
Add the new code to the same Trinket project. Keep previous stage code unless the stage says to replace a function.
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.
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.
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
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
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)
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 the idea
- `towards(player)` finds the angle to the player.
- `forward(4)` moves only a little each loop.
- `ontimer` keeps the loop running without blocking key presses.
Understand 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
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
Try this
Three short experiments. Predict before you run, then test your guess.
Test your stage
- The chaser moves.
- The chaser follows the player.
- Arrow keys still work while the loop runs.