- Learnt30 min · replace a row, rebuild a row, a brush, a palette
- Basic25 min · the click-to-paint editor
- Challenge 1–327 min · a new room, one start only, undo
- Extrabonus · mirror painting
Review — Tile Maker II 5 min
go to cellturns a column and row into an x and y.- Column = floor((x + 240) ÷ 30) + 1. Row = floor((180 − y) ÷ 30) + 1.
- The cursor snaps to the square under the mouse, and reads its letter.
Quick-fire
The mouse is at x 100. Which column is it in?
Reveal the answer
Column 12. 100 + 240 = 340. 340 ÷ 30 = 11.33. Floor gives 11, plus 1 is 12.
Today’s Topic 3 min
replace item (7) of [level v] with [thing]— a whole row at once- Changing one letter: build the row again with a loop of joins
- The Tile sprite as a see-through brush that paints where you click
- A palette of nine tiles on the ← and → keys
Learning outcome
By the end of this lesson you will be able to:
- Change one letter inside a text, using a loop.
- Change one square of a level and redraw only that square.
- Build an editor that paints tiles with the mouse.
Learnt — painting the level 30 min
1 · A whole row at once
Lists have a block that swaps one item for another: replace item (7) of [level v] with [thing]. Each item is a row, so it swaps a whole row.
when flag clicked
load level :: custom
draw level :: custom
wait (1.5) seconds
replace item (7) of [level v] with [#.*.*.*.*.*.*.*#]
draw level :: custom
How to use this: Click the green flag to start it. Nothing else to press — watch row 7 change after a moment.
2 · One letter — build the row again
An editor changes one square. That means one letter inside a row. And here is the catch: Scratch has no block that changes one letter of a text.
So build the row again. Start with an empty text called new row. Go along the old row, letter by letter, joining each one on. At column c, join the new letter instead of the old one. Then put new row back with replace item.
old row 7 #..............# column 9 ↓ new row 7 #.......K......#
Put it in a My Block, set tile, with three inputs: the column c, the row r, and the new letter. At the end it stamps the new tile on that one square. Every tile is a whole square, floor and all, so the new stamp covers the old one completely — no need to draw the level again.
define set tile (c) (r) (new)
set [new row v] to []
set [i v] to (1)
repeat (16)
if <(i) = (c)> then
set [new row v] to (join (new row) (new))
else
set [new row v] to (join (new row) (letter (i) of (item (r) of [level v])))
end
change [i v] by (1)
wait (0.2) seconds
end
replace item (r) of [level v] with (new row)
go to cell (c) (r) :: custom
switch costume to (new)
stamp
when flag clicked
load level :: custom
draw level :: custom
wait (1) seconds
set tile (9) (7) [K] :: custom
new row grow. The Basic’s version has neither.How to use this: Click the green flag to start it. Nothing else to press — watch the new row readout grow, then a key appears.
3 · The Tile sprite becomes the brush
Last lesson the Cursor followed the mouse. Now the Tile sprite does it, and it wears the tile it is about to paint, see-through, so you can see the square under it.
set [ghost v] effect to (40)makes it see-through.- A stamp copies the ghost effect too — faded tiles. So
draw levelandset tileswitch the ghost to 0 for the stamp, and back to 40 after. - Only paint if the square is not that tile already. Otherwise holding the button still rebuilds the same row thirty times a second.
when flag clicked
load level :: custom
set [brush v] to [#]
draw level :: custom
go to [front v] layer
forever
set [mouse col v] to (([floor v] of (((mouse x) + (240)) / (30))) + (1))
set [mouse row v] to (([floor v] of (((180) - (mouse y)) / (30))) + (1))
go to cell (mouse col) (mouse row) :: custom
switch costume to (brush)
if <mouse down?> then
if <not <(letter (mouse col) of (item (mouse row) of [level v])) = (brush)>> then
set tile (mouse col) (mouse row) (brush) :: custom
end
end
end
How to use this: Click the green flag, then hold the mouse button down on a floor square and drag to paint bricks.
4 · A palette
The nine letters, in order, are one text: .#^*KDCSE. A variable pick counts from 1 to 9, and (letter (pick) of [.#^*KDCSE]) is the tile you are holding.
→ adds 1 to pick, ← takes 1 away. Past 9 it goes back to 1; below 1 it goes round to 9.
Basic — the click-to-paint editor 25 min
Open your Tile Maker project. The Cursor sprite from last lesson can be deleted — the Tile sprite is the cursor now.
Step 1 — set tile
- Make the variables
new row,i,brushandpick. Keepmouse colandmouse row. - In the Tile sprite, make a Block called
set tilewith three inputs:c,randnew. Tick Run without screen refresh. - Build it as in the stack below — no wait in the loop.
Step 2 — a see-through brush
- In
draw level, swap theshowat the top forset [ghost v] effect to (0). - Swap the
hideat the bottom forset [ghost v] effect to (40).
Step 3 — the brush loop
- Copy the Cursor’s forever loop into the Tile sprite’s green-flag script, after
draw level. - Add
switch costume to (brush)and the twoifblocks from Learnt part 3.
Step 4 — the palette
- Before the forever, set
pickto 2 andbrushto(letter (pick) of [.#^*KDCSE]). - Add the two arrow-key scripts. Tick
brushso it shows on the Stage. - Click the green flag. Choose a tile, then paint.
when flag clicked
load level :: custom
set [pick v] to (2)
set [brush v] to (letter (pick) of [.#^*KDCSE])
draw level :: custom
go to [front v] layer
forever
set [mouse col v] to (([floor v] of (((mouse x) + (240)) / (30))) + (1))
set [mouse row v] to (([floor v] of (((180) - (mouse y)) / (30))) + (1))
go to cell (mouse col) (mouse row) :: custom
switch costume to (brush)
if <mouse down?> then
if <not <(letter (mouse col) of (item (mouse row) of [level v])) = (brush)>> then
set tile (mouse col) (mouse row) (brush) :: custom
end
end
end
when [right arrow v] key pressed
change [pick v] by (1)
if <(pick) > (9)> then
set [pick v] to (1)
end
set [brush v] to (letter (pick) of [.#^*KDCSE])
when [left arrow v] key pressed
change [pick v] by (-1)
if <(pick) < (1)> then
set [pick v] to (9)
end
set [brush v] to (letter (pick) of [.#^*KDCSE])
define set tile (c) (r) (new)
set [new row v] to []
set [i v] to (1)
repeat (16)
if <(i) = (c)> then
set [new row v] to (join (new row) (new))
else
set [new row v] to (join (new row) (letter (i) of (item (r) of [level v])))
end
change [i v] by (1)
end
replace item (r) of [level v] with (new row)
go to cell (c) (r) :: custom
switch costume to (new)
set [ghost v] effect to (0)
stamp
set [ghost v] effect to (40)
How to use this: Click the green flag, then click the stage once. Press ← or → to choose a tile, then hold the mouse button down on a square to paint it.
Painted tiles come out faded.
The ghost effect is still 40 when the stamp happens. Set it to 0 just before stamp, and back to 40 just after.
The tile lands in the right column but the wrong row.
Check the inputs of set tile are in the order column, row — the same order as go to cell.
Painting turns the whole row into the new tile.
The two halves of the if / else are swapped. The new letter goes in the top half, where <(i) = (c)> is true.
The palette jumps to a blank brush.
pick went to 0 or 10. Check the two if blocks wrap it round: past 9 back to 1, below 1 to 9.
A new, empty room
Starting a level from Level A every time gets old. Give the editor a blank page.
- Press N and the level becomes an empty room: bricks round the edge, floor inside.
- Then you paint on it as usual.
How to use this: Click the green flag, then click the stage once and press N for an empty room. Choose tiles with ← and → and paint with the mouse button.
Teacher reveal
define empty room
delete all of [level v]
add [################] to [level v]
repeat (10)
add [#..............#] to [level v]
end
add [################] to [level v]
when [n v] key pressed
empty room :: custom
draw level :: custom
The ten middle rows are the same, so a loop adds them.
Only one start
A level with two starts makes no sense. Make the editor keep just one.
- Paint an S, and any S already in the level turns into floor.
- Every other tile paints as before.
How to use this: Click the green flag, then hold the mouse button down on any floor square to paint a start there. Watch the old start disappear.
Teacher reveal
define clear old start
set [row v] to (1)
repeat (12)
set [col v] to (1)
repeat (16)
if <(letter (col) of (item (row) of [level v])) = [S]> then
set tile (col) (row) [.] :: custom
end
change [col v] by (1)
end
change [row v] by (1)
end
Run without screen refresh ticked. In the brush loop, just before set tile:
if <(brush) = [S]> then
clear old start :: custom
end
Undo
Everybody paints the wrong square sometimes. Give the editor an undo key.
- Press Z and the last tile you painted goes back to what it was.
- Every other tile stays as it is.
How to use this: Click the green flag, then click the stage once. Paint a few squares with the mouse button, then press Z to take the last one back.
Teacher reveal
A second list, undo. Just before each tile is painted, the level is copied into it; Z copies it back.
define save undo
delete all of [undo v]
set [row v] to (1)
repeat (12)
add (item (row) of [level v]) to [undo v]
change [row v] by (1)
end
define undo
delete all of [level v]
set [row v] to (1)
repeat (12)
add (item (row) of [undo v]) to [level v]
change [row v] by (1)
end
when [z v] key pressed
if <(length of [undo v]) = (12)> then
undo :: custom
draw level :: custom
end
And save undo :: custom just before set tile in the brush loop. The length check matters: press Z before painting anything and an empty undo list would be copied over the level, wiping it. A drag paints many tiles, so Z takes back only the last of them — a good thing to ask a fast pupil to improve.
Mirror painting
Sketch Pad had a mirror brush. Give the editor one: every tile you paint appears twice, once on each side, so the level is the same left and right.
How to use this: Click the green flag, then click the stage once. Choose a tile with ← or →, then hold the mouse button down on a square to paint it on both sides.
Teacher reveal
In the brush loop, paint the mirror square first, then the square itself:
if <mouse down?> then
if <not <(letter (mouse col) of (item (mouse row) of [level v])) = (brush)>> then
set tile ((17) - (mouse col)) (mouse row) (brush) :: custom
set tile (mouse col) (mouse row) (brush) :: custom
end
end
Mirror square first, because set tile moves the brush. Painted second, the brush would end on the far side for a frame.
Summary 5 min
replace itemswaps a whole row. Scratch cannot change one letter of a text.- To change one letter, build the row again with joins, and drop the new letter in at its column.
- Change the list first, then stamp the one square. Every tile is a full square, so the stamp covers what was there.
- A ghosted brush shows what you will paint. Turn the ghost off to stamp.
- Editor
- A program for making and changing something — here, levels.
- Palette
- The set of tiles you can choose from.
- Join
- Sticks two texts together, end to end.
- Undo
- Taking back the last change.
Hand in
Save your project, then press the green flag — your painted level is gone, back to Level A. Next lesson fixes that with save codes, and a ladybug test-plays what you made.