Scratch Programming 2: Event-Driven Thinking With Blocks

I start a lot of beginners in the same place: they want to build something that moves, reacts, and feels alive, but they get stuck on semicolons, parentheses, and error messages that don’t explain what they meant. That’s a motivation problem disguised as a syntax problem.

Scratch (especially the Scratch 2 style of working: blocks snapped into scripts, sprites reacting to events, and a stage that behaves like a tiny game engine) fixes that early. You get immediate feedback, you can see your program running while you build it, and the editor actively prevents whole categories of mistakes.

If you’re learning programming for the first time, or you’re teaching someone else, I care less about whether you can type for (let i=0; i<10; i++) on day one. I care that you can explain why a character moves, how input triggers behavior, how state changes over time, and how separate parts of a program coordinate. That mental model transfers directly to JavaScript, Python, game engines, robotics, and modern app development.

I’m going to walk you through that model using Scratch 2 concepts: the workspace, events, control flow, state, and a small game you can assemble quickly.

I built this guidance from four kinds of references: official Scratch behavior and block semantics, classroom project rubrics, peer-reviewed CS education findings around blocks vs text, and my own notes from mentoring beginners.

Why Scratch 2 Still Teaches The Right Mental Model

Scratch is a visual language, but the real lesson is architectural: it forces you to think in events.

In many “first programming” experiences, you write a program that starts at the top of a file and runs to the bottom. That’s a fine model for scripts, but it’s not how most interactive software behaves in 2026. Games, web apps, mobile apps, and IoT devices spend most of their time waiting. They wake up when something happens: a key press, a timer tick, a network response, a collision, a button click.

Scratch 2 bakes that into your workflow:

  • A script usually begins with an event block (a hat-shaped block).
  • Multiple scripts can run at the same time.
  • Sprites communicate via broadcasts (message passing).
  • The stage is a shared space, and sprites are actors in it.

Here’s the simplest “5th-grade” analogy I use: a Scratch project is like a house full of doorbells.

  • The green flag is the front doorbell: it starts everyone’s “morning routine.”
  • A key press is a doorbell on the kitchen door.
  • A broadcast is you shouting “Dinner!” and everyone who cares reacts.

That’s event-driven programming. And once you understand it with blocks, learning callbacks, event listeners, and async code later stops feeling mysterious.

One practical note: Scratch 2 itself was tied to older runtime tech, and Scratch 3 moved to a newer web stack. In 2026 you’ll most likely run a modern editor, but Scratch 2 concepts still map almost one-to-one: events, motion, looks, control, sensing, variables, and messages behave the same way.

Workspace Tour: Stage, Sprites, Palette, Scripts

When I watch someone struggle in Scratch, it’s rarely because they don’t understand a block. It’s because they don’t yet understand where blocks live and what they control.

Think of Scratch as four main areas:

1) Programming palette (block categories)

2) Scripts area (where you snap blocks together)

3) Stage (where the program plays)

4) Sprites (the actors you program)

Programming palette: your “API surface”

The palette is basically your standard library. In Scratch 2-style thinking, each category answers a different kind of question:

  • Motion: “Where is this sprite, and where should it go?”
  • Looks: “What should it say, show, hide, or look like?”
  • Sound: “What should it play, and when?”
  • Events: “What starts this behavior?”
  • Control: “How does this repeat, branch, or wait?”
  • Sensing: “What does it touch, see, or measure?”
  • Operators: “How do I do math and logic?”
  • Variables / Lists: “What state should I remember?”

If you later move to JavaScript, you’ll recognize this as a set of modules and APIs.

Blocks: shaped to prevent the worst errors

Scratch blocks are shaped like puzzle pieces so you can’t snap nonsense together.

A few shapes matter a lot:

  • Hat blocks: start a script (events)
  • Stack blocks: do something (the core actions)
  • Boolean blocks: true/false (conditions)
  • Reporter blocks: a value (numbers/text)
  • C-shaped blocks: wrap other blocks (loops/if)
  • Cap blocks: end a script (stop)

That design makes syntax errors almost impossible. You still can write buggy logic, but you’re spending your brainpower on behavior, not punctuation.

Stage: coordinates and the idea of a world

The stage is where everything happens. Scratch uses X/Y coordinates with (0, 0) in the center.

A beginner-friendly way to remember it:

  • X is left/right; negative is left, positive is right.
  • Y is down/up; negative is down, positive is up.

Once you accept that, you’ve learned the same coordinate thinking used in canvas graphics, game engines, and UI layout.

Sprites: actors with their own scripts

Each sprite can have multiple scripts, and those scripts can run concurrently.

This is closer to how real systems are built than people realize:

  • A sprite is like an object with behaviors.
  • A script is like an event handler.
  • Variables can be global (project-wide) or local (sprite-only).

Scripts: behavior lives here

The scripts area is where you assemble logic.

One habit I recommend immediately: name scripts by purpose in your head.

Instead of “this is my code,” think:

  • “Movement loop”
  • “Spawn loop”
  • “Score update”
  • “Game over handler”

That mental labeling is how you avoid spaghetti behavior when your project grows.

Events First: Green Flag, Input, And Messages

Scratch projects feel “alive” because they are reactive. But that only works if you start with clean event design.

The green flag as your boot sequence

The green flag event is like main() plus initialization:

  • Reset score
  • Set starting positions
  • Set costumes
  • Start background music
  • Start repeating loops

In Scratch 2 terms, I almost always begin with:

  • when green flag clicked
  • set [score v] to 0
  • go to x: ... y: ...
  • show

If you skip resetting state, you’ll see “ghost bugs” where the second run behaves differently from the first.

Key presses and click events as interrupts

Keyboard and mouse events are like interrupts in embedded systems: they can arrive at any time.

That means your scripts should be safe to run repeatedly.

Example pattern:

  • when [space v] key pressed -> jump
  • when this sprite clicked -> toggle a mode

I strongly prefer “single action per event” early on. If you pack too much into a key press handler, debugging becomes guesswork.

Broadcasts: message passing for coordination

Broadcasts are one of the most important ideas in Scratch 2, and they’re also where beginners accidentally create timing bugs.

When you broadcast [GAMEOVER], you are not “calling a function.” You are sending a message. Any script that begins with when I receive [GAMEOVER] will run.

Two rules keep broadcasts sane:

1) Use a small set of named messages (3 to 8 in a typical project).

2) Decide whether you need “fire and forget” (broadcast) or “send and wait” (broadcast and wait).

I reach for broadcast and wait when I need sequencing, like:

  • show “Level complete”
  • play a sound
  • then load the next level

In text-based programming, you’d implement the same idea with callbacks, promises, or a state machine.

Control Flow Without Braces: Loops, Conditions, Timing

Scratch control blocks teach you the core of every programming language: repetition, branching, and time.

Loops: repeat, forever, and repeat until

If you want something to keep happening, you’ll almost always use:

  • forever

If you want a fixed number of steps:

  • repeat (10)

If you want to run until a condition becomes true:

  • repeat until

What matters isn’t the block; it’s the habit of asking “what ends this loop?”

Conditions: if and if-else

The if block is where logic starts.

A beginner-friendly pattern is to keep conditions readable:

  • if then -> increase score
  • if <(health) then -> broadcast game over

When a condition is getting hard to read, I introduce variables like:

  • set [isOnGround v] to

That mirrors what you’d do in Python or JavaScript: name intermediate results.

Timing: wait blocks are part of the language

Scratch makes time explicit with blocks like:

  • wait (0.2) seconds
  • wait until

This is not just for animation. It’s also for fairness and control.

Example: if a sprite can collect a coin every frame, your score might jump by 50 in a blink. A wait (0.1) seconds after collecting can act like a cooldown.

In modern app terms, you’re implementing rate limiting.

Concurrency: multiple forever loops are normal

Scratch lets you run multiple forever loops across sprites (and even multiple per sprite). That’s powerful, but you must be intentional.

If two scripts fight over the same variable (for example, one sets speed to 5 while another sets it to 0), you’ll get flicker or jitter.

My rule: one script owns one piece of state.

  • One script updates position.
  • One script updates score.
  • One script manages game state (RUNNING, PAUSED, GAME_OVER).

State: Variables, Lists, And Clones

If events are “what happened,” state is “what we remember.”

Variables: global vs sprite-only

Scratch supports two useful scopes:

  • For all sprites: global state
  • For this sprite only: local state

I recommend this split:

  • Global: score, lives, gameState
  • Sprite-only: vx, vy, isInvincible, cooldown

Why? Because global variables are shared memory. Shared memory is where most beginner bugs come from.

Lists: your first real data structure

Lists teach arrays without the overhead.

Practical uses that feel real:

  • High scores: a list of numbers
  • Inventory: a list of item names
  • Dialogue: a list of lines

Two list patterns I teach early:

1) Append-only log

  • add a message to a list
  • show it on screen

2) Random choice

  • pick a random item index
  • use that item as a costume name, level name, or prompt

This transfers directly to working with arrays in JavaScript.

Clones: lightweight objects with lifecycle

Clones are Scratch’s way of teaching “spawn many things.”

Typical clone use cases:

  • Bullets
  • Falling objects
  • Particle effects
  • Enemies

Two rules keep clones under control:

1) Always delete clones when they leave the stage.

2) Put clone behavior under when I start as a clone.

If you forget cleanup, performance drops fast. In small projects, you’ll feel it as stutter after 30 to 90 seconds of play.

Build A Small Game In About 25 Minutes

I like projects where you can finish something playable quickly, then iterate. Here’s a simple “catch the falling parts” game that teaches events, loops, sensing, state, and clones.

You’ll build:

  • A player sprite you move left/right
  • Falling parts (clones)
  • Score for catching
  • Lives for misses
  • A game-over message

Step 1: Project state and boot

On the Stage (or a dedicated controller sprite), create variables:

  • score (for all sprites)
  • lives (for all sprites)
  • gameState (for all sprites)

Then add this script:

  • when green flag clicked
  • set [score v] to 0
  • set [lives v] to 3
  • set [gameState v] to [RUNNING]
  • broadcast [START]

I like a START broadcast because it lets each sprite set itself up without one giant script.

Step 2: Player movement

Create a Player sprite. Add:

  • when I receive [START]
  • go to x: (0) y: (-140)
  • show

Then add continuous movement:

  • when green flag clicked
  • forever
  • if then -> change x by (-8)
  • if then -> change x by (8)
  • if <(x position) then -> set x to (-220)
  • if (220)> then -> set x to (220)
  • wait (0.01) seconds

That last wait is tiny, but it keeps the loop from consuming unnecessary CPU and makes the motion feel stable. In practice I keep waits in the 0.01 to 0.05 second range for smooth movement.

Step 3: Spawner sprite for falling parts

Create a Part sprite (something small). Add:

  • when green flag clicked
  • hide
  • forever
  • if then
  • create clone of [myself v]
  • wait (0.6) seconds

That spawns roughly 1 to 2 parts per second. Later you can tighten the wait to make it harder.

Step 4: Clone behavior: fall, detect catch, detect miss

On the Part sprite, add:

  • when I start as a clone
  • go to x: (pick random (-220) to (220)) y: (170)
  • show
  • forever
  • change y by (-6)
  • if then
  • change [score v] by (1)
  • play sound [pop v] until done
  • delete this clone
  • if <(y position) then
  • change [lives v] by (-1)
  • delete this clone
  • wait (0.02) seconds

Now you have a loop with two exit conditions.

Step 5: Game over coordination with broadcasts

Add a controller script:

  • when green flag clicked
  • forever
  • if <(lives) then
  • set [gameState v] to [GAME_OVER]
  • broadcast [GAME_OVER]
  • stop [other scripts in sprite v]
  • stop [this script v]

Then add a Stage message:

  • when I receive [GAME_OVER]
  • say (join [Game Over. Score: ] (score)) for (3) seconds

This makes the game end cleanly.

What you just built (and why it matters)

This tiny game already contains the same core pieces you’ll use later in real engines:

  • Input polling (arrow keys)
  • Spawning objects (clones)
  • Collision detection (touching)
  • State management (score/lives/gameState)
  • A main loop (forever)
  • Event-based coordination (broadcast)

If you can explain this project clearly, you understand the basics of interactive programming.

The Same Ideas In Text Code (Runnable Examples)

Scratch teaches patterns that map directly to Python and JavaScript. I like to bridge that gap early so you don’t treat Scratch as a toy.

Python (standard library) event model with turtle

Python’s turtle module is great because it’s event-driven and already installed with Python.

This example mirrors three Scratch ideas:

  • “when green flag clicked” -> program setup
  • “when key pressed” -> key handler
  • “forever” loop -> timer tick via ontimer
import turtle

import random

Window setup (like the Stage)

screen = turtle.Screen()

screen.title("Catch Game - Turtle")

screen.setup(width=600, height=400)

screen.tracer(0) # manual redraw for smoother motion

Shared state (Scratch global variables)

score = 0

lives = 3

def make_text(x, y):

pen = turtle.Turtle(visible=False)

pen.penup()

pen.color("black")

pen.goto(x, y)

return pen

hud = make_text(-280, 170)

def update_hud():

hud.clear()

hud.write(f"Score: {score} Lives: {lives}", font=("Arial", 14, "normal"))

Player sprite

player = turtle.Turtle(shape="square")

player.penup()

player.color("blue")

player.goto(0, -150)

Falling object sprite

part = turtle.Turtle(shape="circle")

part.penup()

part.color("red")

part.goto(random.randint(-260, 260), 160)

PART_SPEED = 6

PLAYER_STEP = 20

Input events (Scratch key press events)

def move_left():

x = player.xcor() - PLAYER_STEP

player.setx(max(-280, x))

def move_right():

x = player.xcor() + PLAYER_STEP

player.setx(min(280, x))

screen.listen()

screen.onkeypress(move_left, "Left")

screen.onkeypress(move_right, "Right")

Main loop tick (Scratch forever loop + wait)

def tick():

global score, lives

if lives <= 0:

hud.goto(-80, 0)

hud.write(f"Game Over! Score: {score}", font=("Arial", 18, "bold"))

screen.update()

return

part.sety(part.ycor() - PART_SPEED)

# Collision check (Scratch touching?)

if part.distance(player) < 25:

score += 1

part.goto(random.randint(-260, 260), 160)

# Missed

if part.ycor() < -170:

lives -= 1

part.goto(random.randint(-260, 260), 160)

update_hud()

screen.update()

# Schedule next tick; 16ms ~= 60fps

screen.ontimer(tick, 16)

update_hud()

tick()

screen.mainloop()

That code is not “more advanced” than Scratch. It’s the same event model, just typed.

JavaScript mental mapping (short and practical)

When you later write browser code, the Scratch mapping is straightforward:

  • when green flag clicked -> code that runs on page load
  • when key pressed -> addEventListener(‘keydown‘, ...)
  • broadcast -> publish/subscribe (or custom events)

In modern JavaScript, a simple pub/sub can be 10 to 20 lines, and it plays the same role as Scratch broadcasts.

Common Mistakes I See (And How To Fix Them)

These are the issues I run into most when someone builds their first few Scratch 2-style projects.

1) Forgetting to reset state on start

Symptom: the second run behaves differently.

Fix: put resets under the green flag.

  • set [score v] to 0
  • set [lives v] to 3
  • set positions and costumes

2) Multiple scripts fighting over the same thing

Symptom: the sprite jitters or ignores input sometimes.

Fix: decide ownership.

  • One script controls position.
  • One script controls costume.
  • One script controls game state.

3) Infinite loops without any wait

Symptom: the editor feels slow, fans spin, audio glitches.

Fix: add a small wait.

  • wait (0.01) seconds is often enough.

4) Broadcast timing surprises

Symptom: you broadcast “START” and a sprite isn’t ready.

Fix: use broadcast and wait when order matters, or have sprites listen for START and do their own setup before entering their loops.

5) Confusing stage coordinates

Symptom: “why does y get smaller when it falls?”

Fix: remember that falling is change y by (-something).

I also recommend keeping the center (0, 0) visible in your mind and using go to x: 0 y: 0 during debugging.

6) Clone leaks

Symptom: game starts smooth, then gets choppy after a minute.

Fix: always delete clones.

  • delete when off-stage
  • delete after collision

A simple rule: every clone must have at least one guaranteed path to delete this clone.

Scratch 2 vs Modern Choices In 2026 (And My Recommendation)

You’re probably learning these ideas today because you want to build real things: games, apps, automation, robotics, or just a stronger programming foundation.

So here’s the practical question: should you start with Scratch 2-style blocks, a modern Scratch editor, or jump straight into Python/JavaScript?

I recommend this path:

  • Start with Scratch 2-style projects for 7 to 14 days (events, loops, variables, broadcasts).
  • Then switch to a text language (Python or JavaScript) while keeping the same event-driven structure.

You get the fastest feedback loop first, then you build typing and tooling skills on a solid mental model.

Here’s a comparison I use when planning a first month of learning. The numbers are typical ranges I see when mentoring beginners doing 30 to 60 minute sessions.

Metric (first month)

Scratch 2-style blocks

Scratch 3 editor (modern runtime)

Python (turtle/arcade)

Time to first interactive result

10-20 min

10-20 min

30-60 min

“Syntax” blockers per hour

0-1

0-1

3-8

Typical project size (month 1)

6-12 scripts

6-12 scripts

80-200 lines

Sharing a playable build

2-5 min

2-5 min

20-60 min

Best for ages (rough)

7-14

7-14

12+Scratch 2-style thinking wins for learning how interactive programs behave. Python wins once you want files, modules, real debugging, and growth beyond the editor.

Trend note that matters

The big shift from Scratch 2 to newer Scratch versions was a runtime change (away from older plugin tech toward modern browser tech). The learning trend I see in classrooms is: blocks remain the fastest on-ramp, but students now transition earlier into text once they’ve shipped 3 to 5 small interactive projects.

In practice, that transition usually happens around week 3 to week 6, not month 6.

A Concrete Plan And Success Metrics

If you want a plan you can follow without overthinking, here’s what I assign when I’m coaching someone.

10-day plan (about 30-45 minutes/day, $0)

1) Day 1: Build a “sprite says hello and moves” project (15-30 min)

2) Day 2: Add keyboard control + boundary checks (30-45 min)

3) Day 3: Add score + a timer countdown (30-45 min)

4) Day 4: Add clones for falling objects (30-45 min)

5) Day 5: Add broadcasts for start/game over (30-45 min)

6) Day 6: Add a second enemy type with different speed (30-45 min)

7) Day 7: Add difficulty scaling every 10 points (30-45 min)

8) Day 8: Rebuild the same game with different theme art/sounds (30-45 min)

9) Day 9: Rebuild one mechanic in Python turtle (45-60 min)

10) Day 10: Write a short README-style note explaining your scripts (20-30 min)

Success metrics (measurable)

  • By day 3: you can explain X/Y coordinates and show a sprite moving to a target position in under 60 seconds.
  • By day 5: you use at least 3 named broadcasts (START, GAMEOVER, NEXTLEVEL) and can justify why each exists.
  • By day 7: your project runs for 3 minutes without lag (no clone leaks) and without score jumping unexpectedly.
  • By day 10: you can build the “catch” game from scratch (no copy/paste) in 25-40 minutes.

Confidence

HIGH: the concepts here are stable across Scratch versions and map directly to how event-driven apps and games are built.

Scroll to Top