- Learnt30 min · tile at, four corners, landing on the grid
- Basic25 min · a knight you can walk and jump
- Challenge 1–327 min · what’s underfoot, a sprint, a cell cursor
- Extrabonus · a giant three rows tall
Review — Tile Maker 5 min
- A level is a list called
level: 12 rows, each a string of 16 letters.#is a brick,.is floor,Sis the start. - The Tile sprite has one 30 × 30 costume per letter, named by its letter.
load level :: customadds the twelve rows;draw level :: customgoes to every cell withgo to cell (c) (r) :: customand stamps. - A save code is the 12 rows joined: 192 letters.
make code :: custompacks one,unpack code :: customcuts one back into rows.
Quick-fire
Tile Maker II found the cell under the mouse like this. Column is floor((x + 240) ÷ 30) + 1. Row is floor((180 − y) ÷ 30) + 1. Which cell is the point (−100, 50) in?
Reveal the answer
Column 5, row 5. (−100 + 240) ÷ 30 = 4.67, rounded down is 4, plus 1 is 5. (180 − 50) ÷ 30 = 4.33, rounded down is 4, plus 1 is 5. Today that sum becomes a My Block.
Today’s Topic 3 min
- A
tile at (x) (y) :: customMy Block: a point becomes a cell, and the cell gives a letter - Walls and floors by grid maths, not by colour
- Four corners: the knight’s feet, head and sides
- Landing exactly on top of a tile
Learning outcome
By the end of this lesson you will be able to:
- Turn any point on the Stage into a column, a row and the letter stored there.
- Make a knight walk, fall and land on a stamped tile map.
- Explain why reading the map beats touching a colour.
Learnt — a knight that reads the map 30 min
1 · The map is a list
Here is the castle floor we use today. On the left is the list. On the Stage is what draw level :: custom stamps from it.
row 1 #..............# row 2 #..............# row 3 #..............# row 4 #..............# row 5 #..............# row 6 #..............# row 7 #..........##### row 8 #..............# row 9 #......###.....# row 10 #...........##.# row 11 #S...#......##.# row 12 ################
This is your Tile sprite from Tile Maker: the same nine costumes, named by their letters, and the same My Blocks. It loads the list, then stamps it:
define load level
delete all of [level v]
add [#..............#] to [level v]
add [#..............#] to [level v]
add [#..............#] to [level v]
add [#..............#] to [level v]
add [#..............#] to [level v]
add [#..............#] to [level v]
add [#..........#####] to [level v]
add [#..............#] to [level v]
add [#......###.....#] to [level v]
add [#...........##.#] to [level v]
add [#S...#......##.#] to [level v]
add [################] to [level v]
define draw level
erase all
show
set [r v] to (1)
repeat (12)
set [c v] to (1)
repeat (16)
go to cell (c) (r) :: custom
switch costume to (letter (c) of (item (r) of [level v]))
stamp
change [c v] by (1)
end
change [r v] by (1)
end
hide
when flag clicked
hide
load level :: custom
draw level :: custom
broadcast [play v]
2 · Point → cell → letter
The knight needs to ask one question, over and over: what is at this point? Tile Maker’s cursor asked it about the mouse. Now we ask it about any point, in three steps.
- Column. Move the point so the left edge is 0: add 240. Divide by 30 and round down. Add 1, because columns start at 1.
- Row. Rows count down from the top, so start with 180 − y. Divide by 30, round down, add 1.
- Letter. Take that row out of the list. Take that letter out of the row.
define tile at (x) (y)
set [col v] to (([floor v] of (((x) + (240)) / (30))) + (1))
set [row v] to (([floor v] of (((180) - (y)) / (30))) + (1))
set [tile v] to (letter (col) of (item (row) of [level v]))
x and y. Tick Run without screen refresh. It answers in three variables.| Point | col | row | tile |
|---|---|---|---|
| (−100, 50) | 5 | 5 | . — empty |
| (15, −80) | 9 | 9 | # — the ledge |
| (−195, −160) | 2 | 12 | # — the floor |
| (−195, −135) | 2 | 11 | S — the start |
How to use this: Click the green flag, then move the mouse pointer over the map. The crosshair says the column, the row and the letter under it.
([floor v] of (4.67)) rounds down, to 4. That is why a point anywhere inside a cell gives the same column — even right on its left edge.
3 · Why not touching colour?
In Jump Quest the floor was one flat green, and <touching color [#3FA34D]?> did the landing. A tile map can do better.
| Touching colour | Grid maths | |
|---|---|---|
| What the tiles may look like | One flat rule colour each | Anything at all — the brick tile is five colours |
| A coin and a key, both gold | The same colour, so the same thing | * and K — two different letters |
| Where the floor’s top edge is | Feel for it, one pixel at a time | Worked out from the row number |
| Changing the level | Paint a new backdrop | Change one letter in a list |
4 · Four corners
A knight is not a point. We check it at four corners: 8 pixels left and right, 11 pixels up and down. corner (dx) (dy) :: custom checks one of them and counts a hit if it is in a brick.
define corner (dx) (dy)
tile at ((x position) + (dx)) ((y position) + (dy)) :: custom
if <(tile) = [#]> then
change [hits v] by (1)
end
define check box
set [hits v] to (0)
corner (-8) (-11) :: custom
corner (8) (-11) :: custom
corner (-8) (11) :: custom
corner (8) (11) :: custom
hits is 0 when the knight is clear.5 · Falling, and landing on the grid
Gravity is Jump Quest’s: take 1 off y velocity, then move by it. The new part is what happens when the box ends up in a brick.
- Falling (
y velocitybelow 0): the feet went into a row. The top of rowris aty = 210 − 30 × r. Stand 12 above it. - Going up: the head went into a row. Its bottom is at
y = 180 − 30 × r. Stop 12 below it.
define fall
change [y velocity v] by (-1)
change y by (y velocity)
set [on ground v] to (0)
check box :: custom
if <(hits) > (0)> then
if <(y velocity) < (0)> then
tile at (x position) ((y position) - (11)) :: custom
set y to (((210) - ((30) * (row))) + (12))
set [on ground v] to (1)
else
tile at (x position) ((y position) + (11)) :: custom
set y to (((180) - ((30) * (row))) - (12))
end
set [y velocity v] to (0)
end
How to use this: Click the green flag to start it. Nothing else to press — the knight drops onto the floor, then jumps under the ledge.
6 · Walls
Walking is Cheese Maze’s move, ask, undo. Step sideways. If the box is now in a brick, step straight back.
define walk (speed)
change x by (speed)
check box :: custom
if <(hits) > (0)> then
change x by ((0) - (speed))
end
walk (4) :: custom for right and walk (-4) :: custom for left.How to use this: Click the green flag to start it. Nothing else to press — watch the knight walk into the step, jump it, then climb the tower.
Basic — a knight on your map 25 min
Build the knight from the Learnt yourself, on the map above or on your own.
Step 1 — the map
- Start a new project and add the Pen extension. Bring your Tile sprite across: in Tile Maker, right-click it and choose export; here, use Upload Sprite. Or make it again from Tile Maker I with our tile files.
- Keep
load level :: custom,go to cell (c) (r) :: customanddraw level :: custom. Type today’s twelve rows intoload level, or keep a level of your own. - Make
randcfor this sprite only, and use them indraw level. If yours ends with the brush’s ghost effect, putshowandhideback, as in part 1. - End the Tile green-flag script with
broadcast [play v].
Step 2 — the knight
- Click Choose a Sprite, search for
Knight, and add it. - Make six variables for all sprites:
col,row,tile,hits,y velocity,on ground.
Step 3 — the My Blocks
- Make
tile at (x) (y) :: custom, thencorner (dx) (dy) :: custom, thencheck box :: custom. - Make
walk (speed) :: customandfall :: custom. - Tick Run without screen refresh on all five.
Step 4 — the game loop
- Start with
when I receive [play v]. The knight waits until the map is there. - Set it up: left-right, size 18, at the S (−195, −135).
- In a forever: the arrow keys, the jump, then fall.
- Click the green flag. Walk into the step. Jump onto the tower. Bump the ledge.
when I receive [play v]
set rotation style [left-right v]
set size to (18) %
point in direction (90)
go to x: (-195) y: (-135)
set [y velocity v] to (0)
forever
if <key (right arrow v) pressed?> then
point in direction (90)
walk (4) :: custom
end
if <key (left arrow v) pressed?> then
point in direction (-90)
walk (-4) :: custom
end
if <<key (space v) pressed?> and <(on ground) = (1)>> then
set [y velocity v] to (12)
end
fall :: custom
end
How to use this: Click the green flag, then click the stage once. Hold ← or → to walk the knight and press the space bar to jump.
The knight falls straight through the floor.
tile at (x) (y) :: custom is reading an empty list. Check the list is called level in both sprites, and that the map was built before play was broadcast.
The knight shakes up and down while standing still.
The landing uses + 11. It must be + 12, one more than the corners.
The knight walks through walls.
In walk (speed) :: custom, the check must come after the change x by (speed), and the undo uses ((0) - (speed)).
The knight can jump again in mid-air.
The jump needs <(on ground) = (1)>, and fall :: custom must set on ground to 0 before it checks.
What am I standing on?
Make the knight say the letter just under its feet, all the time.
- On a brick it says
On: #. - In the air it says
On: .
How to use this: Click the green flag, then click the stage once. Hold ← or → to walk the knight and press the space bar to jump.
# on every brick you stand on and . at the top of every jump.Teacher reveal
tile at (x position) ((y position) - (20)) :: custom
say (join [On: ] (tile))
At the end of the forever, after the fall. Standing, the feet are 12 above the floor’s top, so 20 below the middle is 8 into the brick. Pupils who try 12 get the empty row above it half the time.
Sprint, with no gap
Step back from a wall and the knight can stop up to 3 pixels short. At double speed that is 7.
- Hold Z and the knight walks at 8 instead of 4.
- When it walks into a wall, it stops touching the wall — no gap, at any speed.
How to use this: Click the green flag, then click the stage once. Hold ← or → to walk the knight, hold Z as well to sprint, and press the space bar to jump.
Teacher reveal
define walk (speed)
change x by (speed)
check box :: custom
if <(hits) > (0)> then
if <(speed) > (0)> then
tile at ((x position) + (8)) (y position) :: custom
set x to (((-240) + ((30) * ((col) - (1)))) - (9))
else
tile at ((x position) - (8)) (y position) :: custom
set x to (((-240) + ((30) * (col))) + (9))
end
end
Cell to edge: the left edge of column c is −240 + 30 × (c − 1). The right corner is 8 from the middle, so the middle goes 9 short of the edge. The main loop sets a speed variable to 8 or 4 with <key (z v) pressed?>.
A cell cursor
Tile Maker II’s cursor did its own sums. Build it again from tile at (x) (y) :: custom, so one My Block does the point-to-cell work for the knight and the cursor alike.
- Your Cursor sprite from Tile Maker II, or a new 30 × 30 frame, empty in the middle.
- It sits exactly on the cell under the mouse, never between two cells.
- The
col,rowandtilemonitors show that cell.
How to use this: Click the green flag, then move the mouse pointer slowly over the map.
Teacher reveal
when I receive [play v]
forever
tile at (mouse x) (mouse y) :: custom
go to x: ((-225) + ((30) * ((col) - (1)))) y: ((165) - ((30) * ((row) - (1))))
end
A round trip: point to cell with tile at (x) (y) :: custom, then cell back to centre with go to cell’s formula. The cursor needs its own copy of the My Block — My Blocks belong to one sprite. Drag it onto the cursor in the sprite list to copy it.
A giant knight
Set the knight to size 50. Now it is about 68 pixels tall — more than two rows.
- Build two corridors, each with one brick hanging at the giant’s waist (the map below).
- With four corners, the giant walks straight through that brick. Find out why.
- Fix it, so the giant is stopped by the brick.
How to use this: Click the green flag to start it. Nothing else to press — two giants walk right, one with four corners, one with six points.
Teacher reveal
define check box
set [hits v] to (0)
corner (-14) (-33) :: custom
corner (14) (-33) :: custom
corner (-14) (33) :: custom
corner (14) (33) :: custom
corner (-14) (0) :: custom
corner (14) (0) :: custom
Corners at ±14 and ±33, plus a middle point on each side. Points 33 apart are never more than 30 from the next. The landing becomes + 34, and the head − 34.
Summary 5 min
- The list is the level. The picture is drawn from it, and the knight reads the list, not the picture.
tile at (x) (y) :: customturns a point into a column, a row and a letter.- Four corners say whether the knight is in a brick.
- The row number says exactly where to land: 12 above the top of that row.
- Grid maths
- Working out a cell from a position, or a position from a cell.
- Cell
- One square of the map: one column, one row, one letter.
- Floor (rounding)
- Rounding down to a whole number: 4.67 becomes 4.
- Hitbox
- The box a game checks instead of the picture. Ours is four corners.
- Snap
- Putting a sprite exactly on an edge, worked out from the grid.
Hand in
Save your Castle Climb. Next lesson the castle gets three floors, an exit up to the next one, and spikes.