← Objects with turtles

Many turtles

Make more turtles with Turtle(), give each one its own commands, and find out what a game with several stars costs in code.

Every game has many things moving at once: enemies, coins, bullets, clouds. Each one is an object with its own position and its own commands.

So far one turtle did everything. Turtle() makes another turtle. Each one is an object: a thing with its own position, heading and colour, that you give commands to by name.

PredictRead the code and say what it will do before you run anything. A wrong guess is fine: it shows you what to look for.

Predict

stars.py
from turtle import *

a = Turtle()
b = Turtle()
b.color("red")
a.forward(100)
b.left(90)
b.forward(50)

a = Turtle() makes a turtle and names it a. a.forward(100) gives the command to a only. Read the program: how many turtles will you see?

How many turtles are on the screen when it finishes?

RunRun it and compare the result with your prediction.

Run

A game: catch the falling stars. Press Run, click the picture, then use the left and right arrow keys. You are the turtle at the bottom: commands with no name in front (goto, xcor()) move you. Each star is its own turtle, s1, s2 and s3, and the score is written by a fourth, hidden turtle called pen.

stars.py
from turtle import *
import random

speed(0)
penup()
goto(0, -180)
left(90)
score = 0

pen = Turtle()
pen.hideturtle()
pen.penup()
pen.goto(-220, 200)

s1 = Turtle()
s1.shape("circle")
s1.color("gold")
s1.penup()
s1.goto(-120, 200)
s1.setheading(270)

s2 = Turtle()
s2.shape("circle")
s2.color("gold")
s2.penup()
s2.goto(0, 200)
s2.setheading(270)

s3 = Turtle()
s3.shape("circle")
s3.color("gold")
s3.penup()
s3.goto(120, 200)
s3.setheading(270)

def show_score():
    pen.clear()
    pen.write("Score: " + str(score), False, "left", ("Arial", 16, "normal"))

def go_left():
    goto(xcor() - 25, ycor())

def go_right():
    goto(xcor() + 25, ycor())

def tick():
    global score
    s1.forward(4)
    if s1.distance(xcor(), ycor()) < 25:
        score += 1
        s1.goto(random.randint(-200, 200), 200)
    if s1.ycor() < -220:
        s1.goto(random.randint(-200, 200), 200)
    s2.forward(6)
    if s2.distance(xcor(), ycor()) < 25:
        score += 1
        s2.goto(random.randint(-200, 200), 200)
    if s2.ycor() < -220:
        s2.goto(random.randint(-200, 200), 200)
    s3.forward(3)
    if s3.distance(xcor(), ycor()) < 25:
        score += 1
        s3.goto(random.randint(-200, 200), 200)
    if s3.ycor() < -220:
        s3.goto(random.randint(-200, 200), 200)
    show_score()
    ontimer(tick, 50)

onkey(go_left, "Left")
onkey(go_right, "Right")
listen()
show_score()
tick()
mainloop()
Try it yourselfYour edits are saved in this browser.

InvestigateTrace how each line of code connects to what you see.

Investigate

stars.py
from turtle import *
import random

speed(0)
penup()
goto(0, -180)
left(90)
score = 0

pen = Turtle()
pen.hideturtle()
pen.penup()
pen.goto(-220, 200)

s1 = Turtle()
s1.shape("circle")
s1.color("gold")
s1.penup()
s1.goto(-120, 200)
s1.setheading(270)

s2 = Turtle()
s2.shape("circle")
s2.color("gold")
s2.penup()
s2.goto(0, 200)
s2.setheading(270)

s3 = Turtle()
s3.shape("circle")
s3.color("gold")
s3.penup()
s3.goto(120, 200)
s3.setheading(270)

def show_score():
    pen.clear()
    pen.write("Score: " + str(score), False, "left", ("Arial", 16, "normal"))

def go_left():
    goto(xcor() - 25, ycor())

def go_right():
    goto(xcor() + 25, ycor())

def tick():
    global score
    s1.forward(4)
    if s1.distance(xcor(), ycor()) < 25:
        score += 1
        s1.goto(random.randint(-200, 200), 200)
    if s1.ycor() < -220:
        s1.goto(random.randint(-200, 200), 200)
    s2.forward(6)
    if s2.distance(xcor(), ycor()) < 25:
        score += 1
        s2.goto(random.randint(-200, 200), 200)
    if s2.ycor() < -220:
        s2.goto(random.randint(-200, 200), 200)
    s3.forward(3)
    if s3.distance(xcor(), ycor()) < 25:
        score += 1
        s3.goto(random.randint(-200, 200), 200)
    if s3.ycor() < -220:
        s3.goto(random.randint(-200, 200), 200)
    show_score()
    ontimer(tick, 50)

onkey(go_left, "Left")
onkey(go_right, "Right")
listen()
show_score()
tick()
mainloop()

Who does each line talk to?

How much code does one star cost?

A command that went to the wrong turtle.

Match each line with what it does.

s1 = Turtle()
s1.forward(4)
goto(xcor() - 25, ycor())
pen.write(...)

Count the lines that mention s1 (making it, moving it, catching it, sending it back to the top). How many are there?

This should draw a red line to the right and a blue line straight up. The blue line goes right instead, and a third turtle appears. Click the line that causes it.

ModifyChange the code on purpose and check the result.

Modify

Make s2 blue and faster than the others.

Need a hint?

s2's colour is set with s2.color(...). Its speed is the number in s2.forward(...) in tick.

Add a fourth star, s4. Count how many lines it took.

Need a hint?

Copy the six lines that make s3 and change every s3 to s4.

Another hint

Then copy s3's five lines in tick for s4.

Try it yourselfYour edits are saved in this browser.

Make the middle star (s2) blue and faster.

    Run your program. This ticks when your code does all of the above.

    Add a fourth star, s4.

      Run your program. This ticks when your code does all of the above.

      MakeBuild something new using what you have learned. Expect a few tries; that is normal.

      Make a rock

      Add a rock: a grey square (rock.shape("square")) that falls like a star but costs 3 points if it touches you. It needs its own lines to make it, move it, and check whether it touched you.

      Try it yourselfYour edits are saved in this browser.

      Add a falling grey square called rock that costs 3 points when it touches you.

        Run your program. This ticks when your code does all of the above.

        Info

        Where this leads

        Separate names work for three stars and break down for fifty. The rest of this course tidies the game step by step: a list of stars, then one dictionary per star, then a Star class of your own.

        A game needs 50 falling stars. What is the trouble with s1, s2, s3 … s50?

        For teachers

        Students make extra turtles with Turtle(), give each one commands by name, and play a catch-the-stars game built from three separate star variables, so they can count what each star costs in code. About 50 minutes.

        Open the teacher guide: answers, solutions, slides and a worksheet.

        Students will be able to

        Before class

        Read the unit primer first. a = Turtle() makes a new turtle; a.forward(100) moves only a. Commands with no name in front (forward, goto, xcor()) go to the default turtle, the one from the turtle course. As in real Python, the default turtle only appears once such a command uses it, which is why the Predict program shows two turtles, not three. In the game the student is the default turtle; the stars are s1, s2 and s3; pen is a hidden turtle that writes the score. Keys need the picture clicked first.

        Running the lesson

        1. Predict: most students say 3. Run it and ask where the third turtle went: nothing ever used it.
        2. Run: give two minutes to play. Then ask students to put a finger on every line about s1.
        3. Investigate: the count (11 lines per star) is the point of the lesson. Ask what 20 stars would cost.
        4. Bug task: a missing name sends the command to the default turtle, which then appears. Students meet this again in their own games.
        5. Make: the rock is a whole new block of lines. Ask how many lines it took, and keep the number for next lesson.

        The hard part (on purpose)

        Seeing that every command needs the turtle's name and a dot. When the wrong turtle moves, ask whose name is in front of that line.

        When students get stuck

        Stretch and support

        Stretch: Give the rock its own speed that increases a little every time it is sent back to the top.

        Support: Give students the six lines that make the rock, and ask them to add only its lines in tick.

        Where it leads

        Next lesson keeps the stars in lists, so one loop moves them all and adding a star is one number. Real games (Arcade sprites, microStudio, every game engine) are many objects like these, each with its own position and behaviour.

        What each step is for

        Now you can
        Next lesson2. Lists of starsKeep the stars in a list and their speeds and points in lists beside it, so one loop moves them all, and find out why lists side by side are fragile.