Learning Goals 3 min
By the end of this lesson you will be able to:
- Gate enemy behaviour with if <> then else chains on the (level) variable so one sprite acts differently on level 1, level 2, and level 3.
- Scale the number of enemies per level using repeat (level) + create clone of [myself v].
- Use point towards (Player v) + set rotation style [don't rotate v] to build a chasing enemy for the hardest level without the sprite flipping upside-down.
Warm-Up — the one enemy that's wrong on every level 7 min
In L04-19 you added one Enemy sprite per backdrop, positioned by when backdrop switches to. But every enemy moves the same boring way:
when flag clicked
forever
move (2) steps
if <touching [edge v] ?> then
turn cw (180) degrees
end
end
Predict — if the player can already dodge this on level 1, what should happen on level 3 to keep the game interesting?
Reveal the answer
Make it harder. The same enemy should move faster, or chase the player, or multiply, or all three. Reusing one sprite with different behaviour per level is way less work than building three separate enemy sprites — and it keeps your project clean.
Today: one Enemy sprite, three personalities. Slow patrol on level 1. Fast patrol + a jumper on level 2. Chasers that follow you on level 3. All gated by the (level) variable.
New Concept — gating behaviour with the level number 15 min
You already know if <> then else (L02-07) and you know how to compare numbers with () = () (L02-08). Today we chain them. A chain of if-else-if is how one script picks one behaviour out of many, based on a single number.
The level-gate pattern
if <(level) = (1)> then
move (2) steps
else
if <(level) = (2)> then
move (5) steps
else
point towards (Player v)
move (4) steps
end
end
Read it top-down. Scratch checks (level) = (1) first. If true, slow move. If false, drop into the else and check the next question. If that's also false, fall through to the last branch — the chaser.
Scaling enemy count with repeat
Different number of enemies per level too. Level 1: 1 enemy. Level 2: 2. Level 3: 3. The (level) variable is the count we want:
when backdrop switches to [level1 v]
delete this clone
when I receive (spawn-enemies v)
repeat (level)
create clone of [myself v]
end
The chaser — point towards plus don't rotate
point towards (Player v) turns the sprite to face the player. Add move (4) steps in a forever loop and it slowly homes in. Problem: by default the enemy tilts to face the player — it'll be upside-down half the time. Fix with set rotation style [don't rotate v] at the top of the sprite's flag-click.
when flag clicked
set rotation style [don't rotate v]
Worked Example — the three-personality Lipan 12 min
We'll turn the Enemy into a Lipan (centipede). Slow on the forest floor, fast in the cave, swarming chasers in the sky.
Step 1 — Sprite + rotation style
Rename the Enemy sprite to Lipan. Add one flag-click hat:
when flag clicked
set rotation style [don't rotate v]
hide
Step 2 — Spawn on level start
One hat per level. Each one clears old clones, then spawns the right number:
when backdrop switches to [level1 v]
broadcast (clear-enemies v)
repeat (level)
create clone of [myself v]
end
Step 3 — Clones wipe themselves
when I receive (clear-enemies v)
delete this clone
Step 4 — Clone's first moments
when I start as a clone
go to x: (pick random (-150) to (150)) y: (-100)
show
Step 5 — The level-gated behaviour loop
when I start as a clone
forever
if <(level) = (1)> then
move (2) steps
if <touching [edge v] ?> then
turn cw (180) degrees
end
else
if <(level) = (2)> then
move (5) steps
if <touching [edge v] ?> then
turn cw (180) degrees
end
else
point towards (Player v)
move (4) steps
end
end
end
Step 6 — The level-2 jumper
Level 2 also has a jumper. Easy add to the level-2 branch — give a small upward boost on a timer:
when I start as a clone
forever
if <(level) = (2)> then
change y by (8)
wait (0.3) seconds
change y by (-8)
wait (0.3) seconds
end
end
Step 7 — Test the chase
Flip to level 3 (via your NextLevelButton from L04-19). Three clones spawn, each turns toward the cat, each crawls slowly forward. Now move the Player — every clone tracks you. The faster you move, the more obvious the homing is.
Step 8 — Tune the difficulty
Numbers to tweak after testing: chase speed (move (4) — try 3 for easier, 6 for brutal), clone count cap, jumper wait time, patrol speed. Stay under the L4 stack cap of 30 blocks per script — if a script grows past 30, split it into a my-block (L03-15).
What you just built: a difficulty curve. One sprite, one variable, three feels. Add level 4? Add an else-if branch. No new sprites needed.
Try It Yourself — three behaviour drills 15 min
Goal: On level 1, change the Lipan's colour every two seconds so it pulses gently. On levels 2 and 3, no pulse. Use a second forever loop on the clone, gated by (level) = (1).
when I start as a clone
forever
if <(level) = (1)> then
change [color v] effect by (25)
wait (2) seconds
end
end
Think: The pulse adds personality without changing difficulty. Visual flavour is per-level too — not just numbers.
Goal: On level 3 only, make every chaser say its distance from the player as it moves. Use the distance reporter distance to (Player v) from Sensing inside say.
when I start as a clone
forever
if <(level) = (3)> then
say (distance to (Player v))
end
end
Think: Speech bubbles in a chaser tell the player who's closest. Could become a real gameplay clue — the nearest enemy says BOO! when distance drops below 30.
Goal: Add a level-4 boss preview. Only one clone spawns. The boss has its own behaviour branch in the gate — moves slowly toward the player but stops when distance < 50, then says Wait your turn!.
when I start as a clone
forever
if <(level) = (4)> then
if <(distance to (Player v)) > (50)> then
point towards (Player v)
move (2) steps
else
say [Wait your turn!]
end
end
end
Think: A boss is just an enemy with a different gate branch. As your platformer grows, every new enemy type is one more else-if. Beyond level 4, refactor the chain into a my-block (L03-15) so you don't outgrow 30 blocks.
Mini-Challenge — the cave enemy that never stops 5 min
"Hakim's overlapping behaviours"
Hakim wrote two scripts on his Lipan clone — one for patrol, one for chase. He thought the chase would only fire on level 3. It fires on every level.
when I start as a clone
forever
move (2) steps
if <touching [edge v] ?> then
turn cw (180) degrees
end
end
when I start as a clone
forever
point towards (Player v)
move (4) steps
end
What did he forget, and what's the smallest fix?
Reveal one valid solution
Both when I start as a clone hats fire on every clone, every time, on every level. There's no gate. The patrol script moves 2 steps and the chase script moves 4 steps — so the clone does both, drifting toward the player at random speed. Looks buggy.
Fix: wrap each forever's inside in a level gate:
when I start as a clone
forever
if <(level) < (3)> then
move (2) steps
if <touching [edge v] ?> then
turn cw (180) degrees
end
end
end
when I start as a clone
forever
if <(level) = (3)> then
point towards (Player v)
move (4) steps
end
end
Lesson: when you have two scripts that should be mutually exclusive, both have to know about it. Splitting behaviour across two scripts is fine — but each script still needs its own gate.
Recap 3 min
You turned one enemy sprite into three. The pattern is the level gate: an if <> then else chain that picks one behaviour based on the (level) variable. Number of enemies scales with the level number using repeat (level). The chaser uses point towards with set rotation style [don't rotate v] so the picture stays upright while the motion direction tracks the player. Same sprite. Same script structure. Different difficulty per biome.
- Level gate
- An if <> then else chain that runs different code depending on the (level) variable. The pattern that makes one sprite behave like many.
- Chase
- A movement style where the sprite faces the player every frame and steps forward. Built with point towards (Player v) + move () steps inside a forever.
- Rotation style
- How a sprite handles being pointed in a new direction. All around tilts the picture; left-right mirrors it; don't rotate keeps it upright. Set with set rotation style [...].
- Spawn count
- The number of enemies that exist at once. Scaled by repeat (level) + create clone of [myself v] — level 3 spawns 3 enemies, level 7 would spawn 7.
- Mutually exclusive
- Two pieces of code that should never run at the same time. In a level gate, only one branch fires per level — the others are skipped.
Homework 2 min
The Three-Personality Lipan. Continue last lesson's project. Replace the boring shared enemy with a properly gated one.
- One Enemy sprite called
Lipan. Hidden original, clones visible. - Three when backdrop switches to hats — one per level — each broadcasts
clear-enemiesthen spawns repeat (level) clones. - One when I receive (clear-enemies v) + delete this clone.
- One when I start as a clone with the level-gate forever from the worked example — slow on level 1, fast on level 2, chase on level 3.
- Add the level-2 jumper: a second clone-forever that only does anything when (level) = (2).
- Test by clicking the NextLevelButton: level 1 = one slow Lipan; level 2 = two fast hopping Lipans; level 3 = three chasers.
Save as HW-L4-20-Lipan-Personalities.sb3.
Bring back next class:
- The
.sb3file. - Your answer to: "You can already 'die' if a Lipan touches the cat. On level 3 with three chasers, dying sends you back to the start of the level — which feels brutal. What would feel fair instead?" (Hint: that's exactly L04-21.)
Heads up for next class: SCR-L04-21 adds checkpoints — a flag at the level midpoint that saves your position so dying only kicks you back to the checkpoint, not the start of the whole level.