The final challenge. Students build a game in three milestones, each with less help, using everything from the course; the turtle hops along a path and players catch it before it hides.
Load these into Waypoints Prepare: choose Load URL and paste the copied address, or download the file and import it. In Prepare, the worksheet's Teacher edition shows the answers; the student copy hides them.
Predict, Run and Investigate 15 min · Milestone 1 10 min · Milestone 2 15 min · Milestone 3 15 min · Path or random 5 min
Play the finished game (the Milestone 3 solution below) for a minute, then read the three milestone starters. Milestone 1 gives most of the code, milestone 2 an outline, milestone 3 only the goals: that fading support is deliberate. The two new words are True and False: a variable like showing remembers whether the turtle is on screen right now. Finishing this lesson and Power-ups marks the course "Challenge complete".
Every variable a function changes needs global, and % wraps the path. When the score doesn't change, ask which variables the function changes.
| What you will see | A question to ask | The fix |
|---|---|---|
| The score never changes, or an error says a name has no value. | Which variables does this function change? Are they all in its global line? | Every variable a function changes must be listed after global at the top of that function. |
| Clicking right on the turtle does not score. | Where does the box around the turtle start? | The box starts at (tx - 20, ty - 20) and is 40 by 40, so it is centred on the turtle. |
| After pressing Start twice quickly, the turtle hops twice as fast. | How many hop loops might be running? | Each Start begins a new hop loop. Only start one when playing is False (the solution checks this). |
One possible solution for each task. Other correct programs are fine.
from turtle import *
from ui import inside
speed(0)
penup()
xs = [-120, 0, 120, 120, 0, -120]
ys = [60, 110, 60, -50, -100, -50]
place = 0
tx = 0
ty = 0
score = 0
def hop():
global place, tx, ty
tx = xs[place]
ty = ys[place]
place = (place + 1) % len(xs)
goto(tx, ty)
ontimer(hop, 1000)
def show_score():
clear()
goto(-190, 160)
write(score, False, "left", ("Arial", 20, "normal"))
goto(tx, ty)
def clicked(x, y):
global score
if inside(x, y, tx - 20, ty - 20, 40, 40):
score = score + 1
show_score()
hop()
show_score()
onscreenclick(clicked)
listen()
mainloop()
from turtle import *
from ui import inside, draw_button
speed(0)
penup()
hideturtle()
xs = [-120, 0, 120, 120, 0, -120]
ys = [60, 110, 60, -50, -100, -50]
place = 0
tx = 0
ty = 0
score = 0
misses = 0
showing = False
def hop():
global place, tx, ty, showing
tx = xs[place]
ty = ys[place]
place = (place + 1) % len(xs)
goto(tx, ty)
showturtle()
showing = True
ontimer(hide, 700)
ontimer(hop, 1000)
def hide():
global showing, misses
if showing:
misses = misses + 1
showing = False
hideturtle()
def show_score():
clear()
goto(-190, 160)
write(score, False, "left", ("Arial", 20, "normal"))
goto(tx, ty)
def clicked(x, y):
global score, showing
if showing and inside(x, y, tx - 20, ty - 20, 40, 40):
score = score + 1
showing = False
hideturtle()
show_score()
hop()
show_score()
onscreenclick(clicked)
listen()
mainloop()
from turtle import *
from ui import inside, draw_button
speed(0)
penup()
hideturtle()
xs = [-120, 0, 120, 120, 0, -120]
ys = [60, 110, 60, -50, -100, -50]
place = 0
tx = 0
ty = 0
score = 0
misses = 0
showing = False
time_left = 30
playing = False
def draw_scene():
clear()
goto(-190, 160)
write(score, False, "left", ("Arial", 20, "normal"))
goto(150, 160)
write(time_left, False, "left", ("Arial", 20, "normal"))
if playing == False:
draw_button(-60, -180, 120, 40, "Start")
goto(tx, ty)
def hop():
global place, tx, ty, showing
if playing:
tx = xs[place]
ty = ys[place]
place = (place + 1) % len(xs)
goto(tx, ty)
showturtle()
showing = True
ontimer(hide, 700)
ontimer(hop, 1000)
def hide():
global showing, misses
if showing:
misses = misses + 1
showing = False
hideturtle()
def tick():
global time_left, playing
if playing:
time_left = time_left - 1
if time_left == 0:
playing = False
hideturtle()
else:
ontimer(tick, 1000)
draw_scene()
def start():
global score, misses, time_left, playing, place
score = 0
misses = 0
time_left = 30
place = 0
playing = True
draw_scene()
hop()
ontimer(tick, 1000)
def clicked(x, y):
global score, showing
if playing and showing and inside(x, y, tx - 20, ty - 20, 40, 40):
score = score + 1
showing = False
hideturtle()
draw_scene()
if playing == False and inside(x, y, -60, -180, 120, 40):
start()
draw_scene()
onscreenclick(clicked)
listen()
mainloop()
Stretch: Make the path draw a picture (each spot a corner of a shape) and reveal it with the pen down at game over.
Support: Pair students for Milestone 3, one reading the goals and the other typing, swapping after each goal.
A catch game scores a click with if showing and inside(x, y):, where showing is True only while the turtle is on screen. Why check showing as well as inside?
So a click only scores while the turtle is visible. After it hides, clicking its old spot should not count.
Power-ups (next) adds lives, a status bar, a gold turtle and an upgrade. Then two optional lessons: Control panel (towards Gradio and web pages) and Game levels (towards MakeCode Arcade and microStudio). Creative option: students design their own path, such as their initials.