Learning Goals 3 min
By the end of this lesson you will be able to:
- Use two nested repeat loops — an outer loop for rows and an inner loop for columns — to spawn a rectangular grid of objects.
- Calculate a clone's position from row and col counter variables using arithmetic like ((col) * (50)) - (175) and ((row) * (20)) + (100).
- Use when I start as a clone to give every clone its own start-up script — moving to its assigned spot and showing itself.
Warm-Up — by hand vs by loop 7 min
Last lesson we drew the Breakout design map. The wall sits near the top of the Stage and is made of about forty rectangular bricks. Let us be honest: if you tried to draw forty separate brick sprites by hand, you would still be there at dinner time.
Predict puzzle. Look at this stack. How many bricks does it draw, and where do they end up?
when flag clicked
hide
repeat (8)
change x by (50)
create clone of (myself v)
end
Reveal the answer
This draws eight clones in a single horizontal row, 50 pixels apart. It works — but Breakout needs more than one row. We need rows and columns. That means a loop inside a loop: the outer loop counts rows (1, 2, 3, 4, 5) and the inner loop counts columns (1 to 8) for each row. Eight columns multiplied by five rows equals forty bricks, which is exactly the wall we sketched in L04-31.
Nested loops feel weird the first time. The trick is to read them top-down: "for every row, do all eight columns". A common Malaysian way to think about it: baris dulu, lepas tu lajur — pick a row, then walk along it.
New Concept — nested loops & a grid of clones 15 min
To draw a grid you need two pieces of information for every brick: which row am I on and which column am I on. Those become two variables, row and col. We update them as the loops run, and we use them in the position calculation.
The two loops
The outer loop says "do this five times — once per row". The inner loop says "do this eight times — once per column". Each time the inner loop finishes, the outer loop's counter ticks up by one, and the inner loop starts again from zero.
set [row v] to (0)
repeat (5)
set [col v] to (0)
repeat (8)
...spawn one brick here...
change [col v] by (1)
end
change [row v] by (1)
end
From row & col to x & y
Each brick is 40 pixels wide and 16 pixels tall. We want a gap between them, so we'll space the columns 50 pixels apart and the rows 20 pixels apart. The maths:
- x position = ((col) * (50)) - (175). The
* 50spaces the columns; the- 175shifts the whole row so it is centred on the Stage (column 0 lands at x = −175, column 7 at x = +175). - y position = ((row) * (20)) + (100). The
* 20spaces the rows; the+ 100pushes the wall up near the top of the Stage. Row 0 is at y = 100, row 4 at y = 180.
Why the original sprite hides
The brick sprite you draw in the costume editor is the template. We never want the template itself to be visible on the Stage — only its clones. So the very first line of the script is hide. Clones inherit that hidden state, so each clone has to show itself in its when I start as a clone script.
when I start as a clone
show
Scratch's clone limit
Scratch has a hard cap of 300 clones on the Stage at one time. Try to make a 301st and Scratch silently refuses — the create clone of (myself v) block does nothing. A 5-by-8 grid is 40 clones, which is well within the limit. If you ever decide to make a 10-by-30 grid (300 bricks) Scratch will exactly fill its cap. Anything bigger and you will need a different strategy.
Worked Example — building the 5×8 wall 12 min
Open Scratch. New project. We are going to build the entire Breakout wall in eight steps.
Step 1 — Make the brick sprite
Delete the cat. Paint a new sprite. Draw a rectangle roughly 40 by 16 pixels. Fill it red. Name the sprite Brick.
Step 2 — Create the variables
In the Variables palette, click Make a Variable twice. Make row and col. Both should be For this sprite only — they are bookkeeping for the Brick template, no other sprite needs to read them.
Step 3 — Hide the template & reset
Drop when ⚑ clicked followed by hide. Then a Control block delete this clone? No — that would delete the template! Instead, just hide. We also want a clean slate, so add set [row v] to (0).
Step 4 — The outer loop (rows)
Add repeat (5). Inside it, the very first block is set [col v] to (0) — reset the column counter every time a new row starts.
Step 5 — The inner loop (columns)
Inside the outer repeat, after the col reset, drop a repeat (8). This is the loop that places eight bricks across.
Step 6 — Position the brick
Inside the inner repeat, build the x and y. Use set x to (((col) * (50)) - (175)) and set y to (((row) * (20)) + (100)). These use the operators palette for the multiply and subtract.
Step 7 — Spawn the clone & advance the column
Below the position blocks (still inside the inner repeat), add create clone of (myself v). Then change [col v] by (1). The order matters — set position first, then clone, so the clone inherits the correct x and y.
Step 8 — Advance the row
After the inner repeat ends (but still inside the outer repeat), drop change [row v] by (1). Now the next row starts at row = 1, col = 0.
Don't forget the clone start-up script: drag out when I start as a clone and add show underneath it.
Click the flag. After a flash, you should see a 5-by-8 red brick wall sitting nicely across the top of the Stage. Forty bricks. One sprite.
The full assembled stack
when flag clicked
hide
set [row v] to (0)
repeat (5)
set [col v] to (0)
repeat (8)
set x to (((col) * (50)) - (175))
set y to (((row) * (20)) + (100))
create clone of (myself v)
change [col v] by (1)
end
change [row v] by (1)
end
when I start as a clone
show
What you just built: a procedurally generated game level. The wall is not drawn by hand — it is computed. If you change repeat (5) to repeat (10), you get a 10-row wall for free. Procedural content is how every Minecraft world, every Terraria map, every endless runner gets made. You just took your first step into that world.
Try It Yourself — three brick-wall drills 15 min
Goal: Change the wall from 5 rows by 8 columns to 3 rows by 10 columns. Only two numbers in the script need to change.
when flag clicked
hide
set [row v] to (0)
repeat (3)
set [col v] to (0)
repeat (10)
set x to (((col) * (50)) - (175))
set y to (((row) * (20)) + (100))
create clone of (myself v)
change [col v] by (1)
end
change [row v] by (1)
end
Think: The bricks at column 9 might run off the right edge of the Stage — column 9 sits at x = (9 × 50) − 175 = 275, and the Stage only reaches x = 240. The last brick of each row will be partially off-screen. How would you re-centre? Change the - 175.
Goal: Give the bricks different colours per row. The template brick has one red costume. Inside the clone start-up script, use set [color v] effect to (...) based on the row value the clone inherited. Hint: (row) * (30) gives 0, 30, 60, 90, 120 — five distinct shades.
when I start as a clone
show
set [color v] effect to ((row) * (30))
Think: Because row is For this sprite only, each clone gets its own snapshot. If it were For all sprites, every clone would see the same final value (5) and they would all be the same colour.
Goal: Make the bricks disappear when the mouse touches them. Inside the clone start-up, add a forever loop that watches for touching (mouse-pointer v)? and, when true, runs delete this clone. (Next lesson the ball will do this instead of the mouse, but the destruction logic is identical.)
when I start as a clone
show
forever
if <touching (mouse-pointer v) ?> then
delete this clone
end
end
Think: You have 40 forever loops running in parallel — one per clone. That sounds expensive but Scratch handles it fine. The clone limit (300) exists partly because of this: too many simultaneous scripts would slow the Stage.
Mini-Challenge — Hafiz's missing row 5 min
"Only the bottom row shows up"
Hafiz copied the wall script but only sees a single row of eight bricks at the bottom of the wall — y = 180, the top of the Stage. The other four rows never appear. Here is his script:
when flag clicked
hide
set [row v] to (0)
repeat (5)
set [col v] to (0)
repeat (8)
set x to (((col) * (50)) - (175))
set y to (((row) * (20)) + (100))
create clone of (myself v)
change [col v] by (1)
end
end
Reveal one valid solution
The line change [row v] by (1) at the bottom of the outer loop is missing. Without it, the row variable stays at 0 forever. The inner loop runs five times, but every time it computes y = (0 × 20) + 100 = 100 — same y for every brick — and writes a brick at the same row five times.
Why does Hafiz see bricks at y = 180 then, not y = 100? Because Scratch only displays the topmost clone at each spot, and there are five clones stacked at every position. The colour and z-order tricks make it look like a single row. The other 32 bricks are there — they are just hiding underneath each other.
The fix is one block:
when flag clicked
hide
set [row v] to (0)
repeat (5)
set [col v] to (0)
repeat (8)
set x to (((col) * (50)) - (175))
set y to (((row) * (20)) + (100))
create clone of (myself v)
change [col v] by (1)
end
change [row v] by (1)
end
The lesson: nested loops have two counters and two places to advance the counter. Forget either one and the grid collapses to a line. Always check both change blocks before you flag-click.
Recap 3 min
You built a 5-by-8 grid of forty brick clones from a single hidden template using two nested repeat loops. The outer loop counts rows, the inner loop counts columns, and the position of each clone is computed from those two counters using ((col) * (50)) - (175) and ((row) * (20)) + (100). Each clone's when I start as a clone script does the actual showing. Scratch's 300-clone limit is plenty for any reasonable Breakout wall.
- Nested loop
- A loop inside another loop. The inner loop runs all the way through for every single iteration of the outer loop. A 5-by-8 nested pair runs the inner body 5 × 8 = 40 times.
- Counter variable
- A variable you increment by one each loop pass to remember which iteration you are on. row and col are counters.
- Clone
- A live copy of a sprite created at runtime by create clone of (myself v). Clones inherit the template's costume, variables, and position at the moment of creation.
- For this sprite only
- A variable scope option. When checked, every clone gets its own independent copy of the variable. Essential for per-brick bookkeeping like "what row was I born on".
- Procedural generation
- Building game content using rules and loops instead of drawing every piece by hand. Today's wall is the smallest possible example.
- Clone limit
- Scratch will not create more than 300 clones at once. The 301st create clone of (myself v) silently does nothing — design with this in mind.
Homework 2 min
The Pyramid Wall. Today's wall was a rectangle. Tonight's challenge: make a pyramid wall instead — 1 brick on the top row, 2 on the second, 3 on the third, all the way down to 8 bricks on the bottom row. Total = 1+2+3+4+5+6+7+8 = 36 bricks.
- Start from today's project. Save a copy as
HW-L4-32-Pyramid.sb3. - The outer loop still counts rows — 8 rows this time.
- The inner loop's count must change each row. Hint: repeat ((row) + (1)).
- You will probably need to re-centre each row, because rows now have different widths. The maths trick: subtract ((row) * (25)) from each row's x positions.
- Test it. The wall should look like a stepped pyramid pointing up.
Bring back next class:
- The
.sb3file (or a screenshot of the Stage). - Your answer to: "How many clones does your pyramid use? Could you ever exceed Scratch's 300-clone limit with this design? At what row count?"
Heads up for next class: SCR-L04-33 brings the ball back. We will write the clever paddle-physics trick that makes the ball bounce off the paddle at an angle that depends on where it hit. Today's bricks just sit there; from next lesson onwards, the ball will start smashing them.