Learning Goals 3 min
By the end of this lesson you will be able to:
- Combine two variables —
scoreandlives— that work together in a single game loop, each tracking a different thing. - Wire when this sprite clicked to change [score v] by (1) for hits, and a missed-window pattern to change [lives v] by (-1) for misses.
- End the game with if <(lives) = (0)> then → stop [all v] — a game-over check that runs every frame inside the forever loop.
Warm-Up — what would a complete tiny game look like? 7 min
For the last three lessons, you've practiced variables one piece at a time — making them, naming them, picking scope, resetting them. Today we glue all of it together into something a friend could actually play.
The game is Tap-the-Cat. Rules:
- The cat appears at a random spot on the Stage every 2 seconds.
- If you click the cat before it moves, you score 1 point.
- If the cat moves away before you click it, you lose 1 life.
- You start with 3 lives. When lives hit 0, the game stops.
That's it. Tiny game. But notice what it needs:
- Two variables —
scoregoes up,livesgoes down. - A reset at the start so each new flag click is a clean game.
- A random-position loop with a 2-second wait.
- A click handler that runs in parallel with the random-position loop.
- A game-over check that runs every frame.
- Watcher widgets on the Stage so the player can see
scoreandlives.
Reveal — what's new today, what's review
Almost every piece of this game is something you've already met. Random position (L01), wait blocks (L01), set/change (L02-32), reset stacks (L02-35), if-then (L02-06), stop-all (L02-07-ish), when this sprite clicked (L01). The new thing is gluing them all together — and getting two parallel scripts (the move-loop and the click-handler) to cooperate. That's the whole skill of "making a game" from "writing snippets".
New Concept — variables working in pairs 15 min
Until now, every project you've built has touched one variable at a time. Real games have several variables that react to each other — score goes up when you do well, lives go down when you do badly, level goes up when score reaches a threshold. Today you'll wire two of them together.
Two variables, two directions
In Tap-the-Cat, score and lives point in opposite directions:
scorestarts at 0, goes up when good things happen. change [score v] by (1).livesstarts at 3, goes down when bad things happen. change [lives v] by (-1).
Both are global (every sprite shares them — but in this game, the cat is the only sprite, so it doesn't matter much). Both get reset at the top of the flag-click stack.
Watcher widgets — telling the player
A variable nobody can see is no fun. Open the Variables palette and tick the checkbox next to score and lives. Two little boxes appear on the Stage showing the live value. Drag them where you want. Right-click a watcher for display options — normal readout, large readout, or slider. For games, use normal readout.
Parallel scripts — two hats, one sprite
A sprite can have multiple hat blocks, and Scratch runs them all at the same time. The cat sprite in this game has:
- A when ⚑ clicked hat that resets variables, then loops forever — move to random spot, wait 2 seconds, lose a life. This is the move-loop.
- A when this sprite clicked hat that fires whenever the user actually clicks the cat — add 1 to score. This is the click-handler.
These two scripts run in parallel. The move-loop is busy waiting and moving, regardless of what the player does. The click-handler sits silent until the player clicks — then it fires once and goes back to sleep. They share the same two variables.
The game-over check
Inside the move-loop's forever, after every life-losing event, check if lives have run out:
if <(lives) = (0)> then
stop [all v]
end
Notice the equality operator () = () with lives on the left and 0 on the right. The check has to run after the change [lives v] by (-1), otherwise lives could go negative before anyone notices.
Worked Example — Tap-the-Cat from empty project to playable 12 min
Open Scratch. Eight steps to a complete game.
Step 1 — Start fresh
New project. Keep the default cat. That's our only sprite. Resize it down to about 70% so it's a slightly trickier target — drag the resize handle in the corner of the costume, or use the size box in the sprite info panel.
Step 2 — Make the two variables
Variables palette → Make a Variable. Name score, leave For all sprites ticked, OK. Repeat for lives. Tick the checkbox next to each so the watchers show on the Stage. Drag score to the top-left corner of the Stage, lives to the top-right.
Step 3 — Build the reset + move-loop
On the cat, build this stack:
when flag clicked
set [score v] to (0)
set [lives v] to (3)
forever
go to x: (pick random (-200) to (200)) y: (pick random (-150) to (150))
wait (2) seconds
change [lives v] by (-1)
if <(lives) = (0)> then
stop [all v]
end
end
Step 4 — Test the move-loop alone
Click the flag. The cat teleports around the Stage every 2 seconds. lives drops: 3, 2, 1, 0. At 0, everything stops. Game over fires correctly — but there's no way to score yet, because we haven't built the click-handler.
Step 5 — Build the click-handler
On the same cat, build a second stack (separate from the first):
when this sprite clicked
change [score v] by (1)
Step 6 — Click the flag and play
Cat teleports. Click it before it moves — score goes up by 1. Don't click it — wait 2 seconds and lives drops by 1. Lose all 3 lives and the game stops. You just made a game.
Step 7 — Add a "game over" message
Before the stop [all v] in the move-loop, sneak in a say [Game over!] for (2) seconds so the player knows why everything stopped. Tiny change, huge polish.
Step 8 — Adjust difficulty
Too easy? Drop the wait from 2 to 1 second. Cat moves twice as fast. Too hard? Boost the starting lives from 3 to 5. Make a friend playtest and adjust until they get a score of around 10 before game-over — that's good game-design balance.
The full assembled stacks
when flag clicked
set [score v] to (0)
set [lives v] to (3)
forever
go to x: (pick random (-200) to (200)) y: (pick random (-150) to (150))
wait (2) seconds
change [lives v] by (-1)
if <(lives) = (0)> then
say [Game over!] for (2) seconds
stop [all v]
end
end
when this sprite clicked
change [score v] by (1)
What you just built: a complete arcade-style game. It has a start (reset), middle (loop with score and lives), and end (game over). It uses two variables that cooperate — one going up, one going down, both being watched, both reacting to player input. This is the template for every clicker, catcher, and dodger you'll build in Levels 3 and 4.
Try It Yourself — three remix drills 15 min
Goal: Take the finished Tap-the-Cat game and add a bonus score: clicking the cat awards 1 point as usual, but if you click within the first 0.5 seconds of it appearing, you should get 2 points instead. (Hint: use timer, but for this Easy version just change the click-handler to give 2 always — call it Tap-the-Cat Easy Mode.)
when this sprite clicked
change [score v] by (2)
score climbs.Think: One number changed (1 → 2) completely rebalances the game. Daniel found this when his test player got to 40 in thirty seconds — too easy. Game design is mostly tiny number tweaks.
Goal: Add a third variable, high score. Don't reset it on flag — let it survive across games. Each frame in the move-loop, if score beats high score, copy it over. Show a watcher for it on the Stage so the player can chase a personal best.
when flag clicked
set [score v] to (0)
set [lives v] to (3)
forever
go to x: (pick random (-200) to (200)) y: (pick random (-150) to (150))
wait (2) seconds
change [lives v] by (-1)
if <(score) > (high score)> then
set [high score v] to (score)
end
if <(lives) = (0)> then
stop [all v]
end
end
high score is deliberately not in the reset stack at the top.Think: Three variables, three behaviours. score resets every game. lives resets every game. high score does not. The reset block is where you announce your design choice.
Goal: Add a second cat sprite (right-click → duplicate). Both cats teleport independently. Clicking either cat scores 1 point. Both contribute to the same global lives if they're not clicked in time. Two sprites, two move-loops, one shared score and lives. (Both score and lives are global — that's why the cats can share them.)
when flag clicked
forever
go to x: (pick random (-200) to (200)) y: (pick random (-150) to (150))
wait (2) seconds
change [lives v] by (-1)
if <(lives) = (0)> then
stop [all v]
end
end
Think: The reset only happens on Cat 1. Cat 2 just contributes to the same global pool. This is how cluster F (the variable cluster) bridges into cluster G (broadcasts and coordination) — sprites cooperating around shared state.
Mini-Challenge — the cat that won't die 5 min
"Priya's invincible cat"
Priya built Tap-the-Cat and the score works fine — but the cat never runs out of lives. She watches lives on the Stage. It drops to 2, then 1, then 0… then -1, then -2, then -3, and the game keeps going forever. Here's her move-loop:
when flag clicked
set [score v] to (0)
set [lives v] to (3)
forever
go to x: (pick random (-200) to (200)) y: (pick random (-150) to (150))
wait (2) seconds
if <(lives) = (0)> then
stop [all v]
end
change [lives v] by (-1)
end
Why does lives sail past 0 into negative numbers without the game ever stopping?
Reveal one valid solution
The game-over check runs before the change [lives v] by (-1), not after. So the sequence each frame is: wait, check if lives is 0 (it's not — still 1), decrement to 0, loop. Next frame: wait, check if lives is 0 (it is!) — but we already waited, and we're about to decrement again before stopping... no, wait, the stop should fire. Actually the bug is subtler — by the time lives is at 0 at the top of the loop, we've just waited 2 seconds with lives = 0 visible on screen, then we decrement to -1, then loop. The check happens at the wrong time, so it never quite catches lives at 0.
The fix is to put the check after the decrement:
when flag clicked
set [score v] to (0)
set [lives v] to (3)
forever
go to x: (pick random (-200) to (200)) y: (pick random (-150) to (150))
wait (2) seconds
change [lives v] by (-1)
if <(lives) = (0)> then
stop [all v]
end
end
Now the order is: move, wait, lose a life, check if dead, repeat. The check runs immediately after the decrement that caused it. The order of blocks inside the forever is the timing of your game. Swap two blocks and you change the rules.
Recap 3 min
You built a complete tiny game. The recipe was: two variables (one going up, one going down), a reset stack at the top of the flag-click script, a forever loop with random movement and a timed wait, a separate click-handler that fires in parallel, a game-over check immediately after the decrement, and watcher widgets on the Stage so the player can see what's happening. This is the entire skeleton of the Score & Lives HUD arc — every block you've learned in lessons 31 through 35 working together. Every clicker, catcher, dodger, racer, and shooter you build from here on will be a fancier version of this exact pattern.
- Game loop
- The main forever inside a game that handles movement, scoring, and the game-over check. Every frame: do, react, check.
- Click-handler
- A second hat-block stack (usually when this sprite clicked) that runs in parallel with the main game loop. Lets the player interact while the game keeps running.
- Watcher widget
- The little box on the Stage that shows a variable's live value. Tick the checkbox next to a variable name in the Variables palette to show it.
- Game-over check
- An if-then inside the game loop that watches for a losing condition (often (lives) = (0)) and runs stop [all v] when it fires.
- stop all
- stop [all v] — halts every script on every sprite in the project. The polite way to end a game.
- Parallel scripts
- Two or more hat blocks on the same sprite that all run at the same time. Each script does its own thing; they cooperate by sharing variables.
Homework 2 min
The Reskin. Take the finished Tap-the-Cat game and turn it into something else. Same skeleton, different theme.
- Open your finished Tap-the-Cat project. Save a copy as
HW-L2-36-MyGame.sb3. - Replace the cat sprite with anything else from the library (a star, a balloon, a piece of kuih, a teh-tarik glass — your choice).
- Change the backdrop to match your theme. Aisyah might use a night sky for catch-the-star. Daniel might use a kitchen for catch-the-kuih.
- Tune the difficulty: pick a wait time between 1 and 3 seconds, and a starting lives between 3 and 7. Playtest until you can score around 10 before losing.
- Add one polish touch from this list: a sound when scoring (play sound [pop v] until done in the click-handler), a costume change on game-over, or a different colour effect at low lives.
- Make sure your two variables, your reset stack, your game-over check, and your watchers are all in place. This is a cluster-F audit.
Save and bring it to class.
Bring back next class:
- Your reskinned
HW-L2-36-MyGame.sb3file. - The high score you reached on your own game.
- Your answer to: "What variable would you add to make this game more interesting? (Examples: a
combocounter, alevelthat speeds things up, amultiplier.) You don't have to build it — just describe."
Heads up for next class: SCR-L02-37 opens cluster G with a new game pattern — falling objects. You'll meet pick random () to () again, this time for a sprite's x coordinate, and you'll build apples that fall from the top of the Stage at random positions.