← Teacher guide

Power-ups

The second half of the final challenge. Students add lives, a status bar, a gold turtle worth 5 and an upgrade bought with points, then invent a power-up of their own.

Python functions and events · Final challenge: Catch the turtle · about 60 minutes · Open the student lesson

Classroom resources

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.

Students will be able to

Timing

Predict, Run and Investigate 15 min · Status bar 10 min · Gold turtle 10 min · Upgrade 10 min · Your own power-up 15 min

Before class

This lesson mixes both directions students could take next. The user interface is what the player sees and uses (the status bar, the buttons); the rules decide what each event means (losing a life, gold is worth 5, an upgrade costs 5). The Investigate task sorts parts into the two kinds. Try the upgrade task yourself: it uses a variable delay instead of the fixed 1000 milliseconds.

Running the lesson

  1. Predict: each miss takes a life; at 0 lives the game stops. Point to the line that ends the game.
  2. Investigate: discuss the match before checking it. 'Both' (a button that costs points) is the interesting one.
  3. Status bar: one function, label(x, y, name, value), called three times. Ask what the alternative would be (copying six lines three times).
  4. Gold turtle: every third spot is gold, using % from Every other. The gold circle is drawn under the turtle.
  5. Upgrade: the button only works if score >= 5. Ask what happens without that check (scores go negative).
  6. Your own power-up: students write one sentence at the top explaining why its cost is fair. Share a few.

The hard part (on purpose)

Separating the rules from the display, and the check before buying. Ask what must be true before the player can buy, before they write the if.

When students get stuck

What you will seeA question to askThe fix
The upgrade can be bought with 0 points and the score goes negative.What should be true before the player can buy it?Add score >= 5 to the if that checks the button.
The gold circle stays on screen after the turtle moves on.When is the gold circle drawn, and what clears it?Draw it only when showing and gold are both True, and redraw (draw_scene) after a catch or a hide.
The upgrade button seems to do nothing.Does hop() use delay, or still the number 1000?Use ontimer(hop, delay) and ontimer(hide, delay - 300).

Answers to the checks

  1. Predict: You start a game and miss three turtles in a row. What happens?
    Each miss takes a life. At 0, playing becomes False, so hop stops and the Start button is drawn again.
  2. Investigate: Each part of a game is user interface, a game rule, or both. Match them.
    The status bar showing score, lives and time → A. user interface: shows the state; The Start button → E. user interface: the player acts; Losing a life when a turtle escapes → C. game rule: what an event means; A gold turtle worth 5 points → D. game rule: a reward; A button that costs 5 points to use → B. both: a control that follows a rule
    Apps are mostly user interface around some rules; games are mostly rules with some user interface. You are building both.

Solutions

One possible solution for each task. Other correct programs are fine.

Add the power-ups › Status bar

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
lives = 3
showing = False
time_left = 30
playing = False


def label(x, y, name, value):
    goto(x, y)
    write(name, False, "left", ("Arial", 14, "normal"))
    goto(x + 55, y)
    write(value, False, "left", ("Arial", 14, "bold"))


def draw_scene():
    clear()
    label(-190, 160, "Score", score)
    label(-50, 160, "Lives", lives)
    label(90, 160, "Time", time_left)
    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, lives, playing
    if showing:
        lives = lives - 1
        showing = False
        hideturtle()
        if lives == 0:
            playing = False
        draw_scene()


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, lives, time_left, playing, place
    score = 0
    lives = 3
    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()

Add the power-ups › Gold turtle

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
lives = 3
showing = False
gold = False
time_left = 30
playing = False


def label(x, y, name, value):
    goto(x, y)
    write(name, False, "left", ("Arial", 14, "normal"))
    goto(x + 55, y)
    write(value, False, "left", ("Arial", 14, "bold"))


def draw_scene():
    clear()
    label(-190, 160, "Score", score)
    label(-50, 160, "Lives", lives)
    label(90, 160, "Time", time_left)
    if playing == False:
        draw_button(-60, -180, 120, 40, "Start")
    if showing and gold:
        goto(tx, ty)
        dot(50, "gold")
    goto(tx, ty)


def hop():
    global place, tx, ty, showing, gold
    if playing:
        tx = xs[place]
        ty = ys[place]
        place = (place + 1) % len(xs)
        if place % 3 == 0:
            gold = True
        else:
            gold = False
        showing = True
        draw_scene()
        showturtle()
        ontimer(hide, 700)
        ontimer(hop, 1000)


def hide():
    global showing, lives, playing
    if showing:
        lives = lives - 1
        showing = False
        hideturtle()
        if lives == 0:
            playing = False
        draw_scene()


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, lives, time_left, playing, place
    score = 0
    lives = 3
    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):
        if gold:
            score = score + 5
        else:
            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()

Add the power-ups › Upgrade button

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
lives = 3
showing = False
gold = False
time_left = 30
playing = False
delay = 1000


def label(x, y, name, value):
    goto(x, y)
    write(name, False, "left", ("Arial", 14, "normal"))
    goto(x + 55, y)
    write(value, False, "left", ("Arial", 14, "bold"))


def draw_scene():
    clear()
    label(-190, 160, "Score", score)
    label(-50, 160, "Lives", lives)
    label(90, 160, "Time", time_left)
    if playing:
        draw_button(-60, -180, 120, 40, "Slow (5)")
    else:
        draw_button(-60, -180, 120, 40, "Start")
    if showing and gold:
        goto(tx, ty)
        dot(50, "gold")
    goto(tx, ty)


def hop():
    global place, tx, ty, showing, gold
    if playing:
        tx = xs[place]
        ty = ys[place]
        place = (place + 1) % len(xs)
        if place % 3 == 0:
            gold = True
        else:
            gold = False
        showing = True
        draw_scene()
        showturtle()
        ontimer(hide, delay - 300)
        ontimer(hop, delay)


def hide():
    global showing, lives, playing
    if showing:
        lives = lives - 1
        showing = False
        hideturtle()
        if lives == 0:
            playing = False
        draw_scene()


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, lives, time_left, playing, place, delay
    score = 0
    lives = 3
    delay = 1000
    time_left = 30
    place = 0
    playing = True
    draw_scene()
    hop()
    ontimer(tick, 1000)


def clicked(x, y):
    global score, showing, delay
    if playing and showing and inside(x, y, tx - 20, ty - 20, 40, 40):
        if gold:
            score = score + 5
        else:
            score = score + 1
        showing = False
        hideturtle()
        draw_scene()
    if playing and score >= 5 and inside(x, y, -60, -180, 120, 40):
        score = score - 5
        delay = delay + 200
        draw_scene()
    if playing == False and inside(x, y, -60, -180, 120, 40):
        start()


draw_scene()
onscreenclick(clicked)
listen()
mainloop()

your own power-up

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
lives = 3
showing = False
gold = False
time_left = 30
playing = False
delay = 1000
# My power-up: More time costs 10 points and adds 5 seconds.
# Fair because 10 points is about two gold turtles, and 5 seconds can win them back.


def label(x, y, name, value):
    goto(x, y)
    write(name, False, "left", ("Arial", 14, "normal"))
    goto(x + 55, y)
    write(value, False, "left", ("Arial", 14, "bold"))


def draw_scene():
    clear()
    label(-190, 160, "Score", score)
    label(-50, 160, "Lives", lives)
    label(90, 160, "Time", time_left)
    if playing:
        draw_button(-130, -180, 120, 40, "Slow (5)")
        draw_button(10, -180, 120, 40, "Time (10)")
    else:
        draw_button(-60, -180, 120, 40, "Start")
    if showing and gold:
        goto(tx, ty)
        dot(50, "gold")
    goto(tx, ty)


def hop():
    global place, tx, ty, showing, gold
    if playing:
        tx = xs[place]
        ty = ys[place]
        place = (place + 1) % len(xs)
        if place % 3 == 0:
            gold = True
        else:
            gold = False
        showing = True
        draw_scene()
        showturtle()
        ontimer(hide, delay - 300)
        ontimer(hop, delay)


def hide():
    global showing, lives, playing
    if showing:
        lives = lives - 1
        showing = False
        hideturtle()
        if lives == 0:
            playing = False
        draw_scene()


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, lives, time_left, playing, place, delay
    score = 0
    lives = 3
    delay = 1000
    time_left = 30
    place = 0
    playing = True
    draw_scene()
    hop()
    ontimer(tick, 1000)


def clicked(x, y):
    global score, showing, delay, time_left
    if playing and showing and inside(x, y, tx - 20, ty - 20, 40, 40):
        if gold:
            score = score + 5
        else:
            score = score + 1
        showing = False
        hideturtle()
        draw_scene()
    if playing and score >= 10 and inside(x, y, 10, -180, 120, 40):
        score = score - 10
        time_left = time_left + 5
        draw_scene()
    if playing and score >= 5 and inside(x, y, -130, -180, 120, 40):
        score = score - 5
        delay = delay + 200
        draw_scene()
    if playing == False and inside(x, y, -60, -180, 120, 40):
        start()


draw_scene()
onscreenclick(clicked)
listen()
mainloop()

Stretch and support

Stretch: Add a power-up that makes the catch box bigger for 10 seconds, then switches back by itself (a timer).

Support: Do the status bar together, then let students choose either the gold turtle or the upgrade rather than both.

Exit ticket

Name one part of your game that is user interface and one that is a game rule.

For example: the status bar is user interface (it shows the state); losing a life on a miss is a game rule.

What each step is for

Where it leads

Completing this and Catch the turtle marks the course Challenge complete. Optional next: Control panel (user interface, towards Gradio and web pages) or Game levels (games, towards MakeCode Arcade and microStudio).