Learning LibraryGame Development LibraryKids

Score and lives: the numbers that make it a game

Moving shapes are a toy. Add a score and it becomes a game, because now there's something to beat. Add lives and there's something to lose.

The big idea

The scoreboard, called game, holds numbers like game.score and game.lives. The rules change them, and write() shows them.

See it in code

1Start simple

Set a score on the scoreboard, add to it when something good happens, and write it on the screen in draw():

python
basket = Thing(x=320, y=420, width=100, height=24, color="teal")
start_y = -20
cupcake = Thing(x=320, y=start_y, size=40, color="orchid", shape="circle")
game.score = 0
points_per_catch = 10

def play():
    cupcake.y = cupcake.y + 5
    if cupcake.touches(basket):
        game.score = game.score + points_per_catch
        cupcake.y = start_y

def draw():
    paper("misty rose")
    rect(x=320, y=455, width=640, height=50, color="burlywood")
    basket.draw()
    cupcake.draw()
    write(f"Score: {game.score}", x=320, y=30, color="sienna")
Two catches, ten points each:
A bakery scene with a teal basket, a falling purple cupcake, and "Score: 20" written at the top.

write() goes at the end of draw(), so the words sit on top of everything else. The f lets the score drop right into the text.

2A step further

Lives work the other way: they count down. Here a cupcake that slips past the bottom costs one. A loop draws a heart for each life left:

python
basket = Thing(x=200, y=420, width=100, height=24, color="teal")
start_y = -20
cupcake = Thing(x=480, y=start_y, size=40, color="orchid", shape="circle")
game.lives = 3
heart_start = 290
heart_gap = 30

def play():
    cupcake.y = cupcake.y + 6
    if cupcake.top > HEIGHT:
        game.lives = game.lives - 1
        cupcake.y = start_y

def draw():
    paper("misty rose")
    rect(x=320, y=455, width=640, height=50, color="burlywood")
    basket.draw()
    cupcake.draw()
    for count in range(game.lives):
        heart(x=heart_start + count * heart_gap, y=30, size=24, color="red")
One cupcake got past, so two hearts are left:
A bakery scene with a teal basket on the left, a cupcake falling on the right where it can't be caught, and two red hearts at the top showing two lives left.

range(game.lives) runs once for each life, so the row of hearts always matches the number. Lose a life and a heart is gone on the very next frame.

3In the arcade

Put them together. Catches add points, misses cost lives, and the game stops at zero lives. A second number, game.best, remembers the top score:

python
basket = Thing(x=320, y=420, width=140, height=24, color="teal")
start_y = -20
cupcake = Thing(x=320, y=start_y, size=40, color="orchid", shape="circle")
game.score = 0
game.lives = 3
game.best = 0
game.over = False
points_per_catch = 10

def new_cupcake():
    cupcake.y = start_y
    cupcake.x = random_number(60, 580)

def play():
    if game.over:
        return
    cupcake.y = cupcake.y + 8
    if cupcake.touches(basket):
        game.score = game.score + points_per_catch
        new_cupcake()
    if cupcake.top > HEIGHT:
        game.lives = game.lives - 1
        new_cupcake()
    if game.lives == 0:
        game.over = True
        if game.score > game.best:
            game.best = game.score

def draw():
    paper("misty rose")
    rect(x=320, y=455, width=640, height=50, color="burlywood")
    basket.draw()
    cupcake.draw()
    write(f"Score: {game.score}", x=110, y=30, color="sienna")
    write(f"Best: {game.best}", x=530, y=30, color="sienna")
    for count in range(game.lives):
        heart(x=290 + count * 30, y=30, size=24, color="red")
    if game.over:
        box(x=320, y=240, width=380, height=90, color="sienna", corner=16)
        write("Game over!", x=320, y=240, size=52, color="white")
The basket never moved, so the game soon ended:
A bakery scene showing a score, a best score, no hearts left, and a brown panel reading "Game over!" in the middle of the screen.

The best score only changes when it's beaten: if game.score > game.best. A lower score next time will leave it alone.

The same idea, everywhere

Every game counts something. Bricks broken, gates passed, rocks zapped, seconds survived. The scoreboard is where a game keeps what matters.

Try it yourself

Make each catch worth more than the last. Put the points on the scoreboard with game.points = 10, and use game.points for the catch. Then add game.points = game.points + 5 after each one.

The common mistake

Getting the sign wrong. game.lives = game.lives + 1 on a miss means missing earns lives, and the game never ends. Counting down needs a minus.

What it unlocks

Points are usually earned when pieces touch. Running out of lives changes the game state. And a score is a running total that grows as you play.