Bring the Star class from Objects with turtles into a game engine: each star moves itself in update() and draws itself in draw(). Change colours and numbers, then add a class of your own.
Your falling-stars game from the turtle course, rebuilt in a game engine: same class, same methods, smoother and faster.
In Objects with turtles each star was an object with its own turtle, speed and move() method. A game engine has no turtles, so a star keeps its own position in self.x and self.y, and gets a draw() method that paints it where it is. Everything else is what you already know.
Make your prediction first. Help opens once you've locked it in.
class Star:
def __init__(self, x):
self.x = x
self.y = 100
stars = []
for i in range(4):
stars.append(Star(-60 + i * 40))
print(stars[2].x)
Which i made stars[2]?
Put this game in a new microStudio project (or replace your code) and run it. Each frame, update() tells every star to move, and draw() tells every star to draw itself.
import random
class Star:
def __init__(self, x):
self.x = x
self.y = 100
self.speed = random.randint(5, 15) / 10
def move(self):
self.y -= self.speed
if self.y < -100:
self.y = 100
self.x = random.randint(-90, 90)
def draw(self):
screen.fillRound(self.x, self.y, 8, 8, "rgb(255,210,0)")
def init():
global stars
stars = []
for i in range(4):
stars.append(Star(-60 + i * 40))
def update():
for star in stars:
star.move()
def draw():
screen.clear("rgb(10,10,40)")
for star in stars:
star.draw()
import random
class Star:
def __init__(self, x):
self.x = x
self.y = 100
self.speed = random.randint(5, 15) / 10
def move(self):
self.y -= self.speed
if self.y < -100:
self.y = 100
self.x = random.randint(-90, 90)
def draw(self):
screen.fillRound(self.x, self.y, 8, 8, "rgb(255,210,0)")
def init():
global stars
stars = []
for i in range(4):
stars.append(Star(-60 + i * 40))
def update():
for star in stars:
star.move()
def draw():
screen.clear("rgb(10,10,40)")
for star in stars:
star.draw()
The turtle version, from Objects with turtles:
class Star:
def __init__(self, x):
self.turtle = Turtle()
self.turtle.goto(x, 200)
self.speed = random.randint(3, 7)
def move(self):
self.turtle.forward(self.speed)
Who does what.
A star that cannot move.
Match each line with what it does.
This stops with an error: cannot access local variable 'y'. Click the line that causes it.
import random
class Star:
def __init__(self, x):
self.x = x
self.y = 100
self.speed = random.randint(5, 15) / 10
def move(self):
self.y -= self.speed
if self.y < -100:
self.y = 100
self.x = random.randint(-90, 90)
def draw(self):
screen.fillRound(self.x, self.y, 8, 8, "rgb(255,210,0)")
def init():
global stars
stars = []
for i in range(4):
stars.append(Star(-60 + i * 40))
def update():
for star in stars:
star.move()
def draw():
screen.clear("rgb(10,10,40)")
for star in stars:
star.draw()
Give each star its own colour, picked at random when it is made. The game on this page does.
Store a colour in init: self.colour = random.choice([...]) with two or three colours.
In draw(), use self.colour instead of "rgb(255,210,0)".
Make 8 stars, spread across the screen.
range(4) makes 4 stars. Change it to range(8).
Space them out: -84 + i * 24 fits 8 stars across.
Add a class of your own, with its own __init__, move() and draw(): clouds that drift sideways, snowflakes that wobble, a moon that grows. Keep its objects in their own list, and move and draw them in update() and draw(). The game on this page adds slow clouds behind the stars.
import random
class Star:
def __init__(self, x):
self.x = x
self.y = 100
self.speed = random.randint(5, 15) / 10
def move(self):
self.y -= self.speed
if self.y < -100:
self.y = 100
self.x = random.randint(-90, 90)
def draw(self):
screen.fillRound(self.x, self.y, 8, 8, "rgb(255,210,0)")
def init():
global stars
stars = []
for i in range(4):
stars.append(Star(-60 + i * 40))
def update():
for star in stars:
star.move()
def draw():
screen.clear("rgb(10,10,40)")
for star in stars:
star.draw()
# Your own class: something else on the screen with its own move and draw methods.
Real game engines are built this way: every enemy, bullet and cloud is an object with its own update and draw. Next: a paddle that catches the stars, with a score.
Students bring the Star class from Objects with turtles into microStudio, where each star keeps self.x and self.y and draws itself, fix a method that forgets self, give each star its own colour, make 8 stars, and add a class of their own. About 50 minutes.
Open the teacher guide: answers, solutions, slides and a worksheet.
Read the unit primer first. This lesson leans on Objects with turtles (classes, self, methods, a list of objects); the only new idea is that a star keeps its own x and y and paints itself in draw(), since there are no turtles. random works in microStudio's Python as usual. print() writes in microStudio's console, under the game. The bug task is the forgotten self from Objects with turtles, in a method this time.
Moving from turtles to drawing by position: a star is now just numbers, painted each frame. Compare the two versions side by side.
Stretch: Give stars a size as well as a colour, or make some stars twinkle by changing their size in move().
Support: Give students the Cloud class's __init__ and ask them only for move() and draw().
Next lesson: catching stars with the paddle and keeping score, which is the turtle course's Catch the turtle in a game engine.