Instructor Notes — Week 10
Theme: Arrays
Focus Concept: Arrays, indexing and multi‑object updates
Mini‑Project: Crashy Bird (scrolling obstacle game built in stages)
Learning Objectives
By the end of this session, participants should be able to:
- Explain that an array/list is one variable that stores many values in order.
- Use a position/index to select a value from an array.
- Describe how a game can use an array to track multiple obstacle sprites.
- Build and test a scrolling game that uses arrays and loops together.
Session Flow (≈ 80 min)
- Starter & Recap (10 min) — quick recap of variables and random numbers.
- Part A – Arrays with Words (10–15 min) — random chooser using an array of strings.
- Part B – Rock–Paper–Scissors with Arrays (15–20 min) — demo using an array of images.
- Part C – Crashy Bird Build (30–35 min) — full game build using arrays and loops.
- Reflection & Extensions (5–10 min) — connect arrays to other games and to concepts from the term.
Part A – Arrays with Words
Aim
Give children an intuitive feel for arrays using a simple list of text options before they see arrays inside a game.
Short project:
- Random Activity Chooser — array of strings.
Conceptual Focus
- An array can store many related items under one variable name.
- Each item has a position called an index (starting at 0).
- We use a random index to pick a random element from the array.
Pseudocode (Blocks-style)
WHEN program starts DO
SET activities TO ["PE with Joe", "watch a movie", "play a board game", "tidy our rooms", "learn a song", "bake a cake"]
END WHEN
WHEN button A is pressed DO
SET index TO [random number from 0 to (length of activities - 1)]
SET choice TO activities[index]
SHOW TEXT choice
END WHEN
Blocks version (MakeCode)
Teaching Notes (Part A)
How to introduce it
- Start with a spoken list: “pizza, pasta, salad, soup…”.
Draw a row of boxes on the board labelled 0, 1, 2, 3 and write one item in each box.
Ask: “If I say index 0, which one is it? What about index 2?” - Then say:
“An array in code is like these labelled boxes: one variable, many slots. Each slot has a position number called an index.”
Key points while building
- Make it clear that
activitiesis one array variable that holds all the strings, not six separate variables. - When choosing, the program does not choose the word directly. It chooses a number (
index), then uses that number to look up the word in the array. - Explicitly talk through
length - 1: if there are 6 items, valid indexes are0to5.
You can ask: “What might go wrong if we picked random 0 to 6?” → off‑by‑one error.
Checks and common issues
- If nothing appears when A is pressed:
- Check that
show stringis using the variablechoiceand not a hard‑coded string. - Check that
length of activitiesis set correctly.
- Check that
- If learners think the array “remembers” the last index forever, show that each button press picks a new random index.
Questions to ask learners
- “What exactly does
indexstore — the word or the position?” - “If we add another activity to the array, what happens to the length and the last index?”
- “Could we use the same pattern to choose a random sound or a random speed later on?”
Part B – Rock–Paper–Scissors with Arrays
Aim
Show that arrays can hold images/icons as well as text, and that the random‑index pattern is exactly the same.
Conceptual Focus
- Arrays can store images, not just words or numbers.
- We again pick a random index, then read the item at that position.
- This mirrors what we will later do with rows and obstacle sprites in Crashy Bird.
Pseudocode (Blocks-style)
WHEN program starts DO
SET icons TO [rock_image, paper_image, scissors_image]
END WHEN
WHEN shake detected DO
SET index TO [random number from 0 to 2]
SHOW LEDs icons[index]
END WHEN
Blocks version (MakeCode)
Teaching Notes (Part B)
How to frame it
- Tell participants:
“We’re going to reuse the same idea, but instead of a list of words, our array will store pictures.”
- Show the three icons (rock, paper, scissors) on the projector or board.
Underneath them, write the indexes 0, 1, 2 to keep the index idea alive.
While coding
- Link each line of pseudocode to the blocks:
- “make array icons” → array variable of type image.
- “set index to random 0 to 2” → random block that returns a number.
- “show leds icons at index” → get‑at‑index block feeding into
show leds.
- Keep repeating:
“The array holds the images. The random block picks a position. Then we ask the array for the image at that position.”
Reasoning prompts
- “What exactly happens when the random index is 1?”
(We show the second image: paper.) - “If we added two more gestures (e.g. lizard and Spock), where should we change the random range?”
Common misconceptions
- Thinking that the random function chooses between rock, paper and scissors directly.
Gently correct: randomness always gives a number, and we use that number to access the array. - Confusing “index = 1” with “first item”. Emphasise again: first item has index 0.
Part C – Crashy Bird Build
Aim
Use arrays and loops in a meaningful context: a scrolling‑obstacle game.
The build should connect back to earlier weeks (movement, loops, collisions), with arrays as the new concept tying everything together.
Conceptual Focus
- Arrays: one variable storing many obstacle sprites.
- Indexing: the array keeps order; we can talk about “the first obstacle” as
obstacles[0]. - Iteration: a loop can update every obstacle on each cycle of the game loop.
- Game loop: the
foreverblock is the “engine” that repeatedly updates the game state. - Collision: a hit occurs when an obstacle sprite and the bird share the same (x, y) position.
Pseudocode Overview (Blocks-style, aligned to MakeCode)
WHEN program starts DO
SET bird TO NEW SPRITE AT (0, 2)
SET blink_of_bird TO 300 ms
SET obstacles TO empty array
SET ticks TO 0
END WHEN
WHEN button A is pressed DO
CHANGE bird y BY -1
END WHEN
WHEN button B is pressed DO
CHANGE bird y BY +1
END WHEN
FOREVER DO
# 1. Remove obstacles that have left the screen
WHILE [length of obstacles] > 0
AND [x position of obstacles[0]] = 0 DO
DELETE SPRITE obstacles[0]
REMOVE element at index 0 FROM obstacles
END WHILE
# 2. Move all obstacles left
FOR EACH obstacle IN obstacles DO
CHANGE obstacle x BY -1
END FOR
# 3. Sometimes spawn a new column of obstacles
IF [remainder of (ticks / 3)] = 0 THEN
SET gap_row TO [random number from 0 to 4]
FOR row FROM 0 TO 4 DO
IF row ≠ gap_row THEN
SET new_obstacle TO NEW SPRITE AT (4, row)
ADD new_obstacle TO obstacles
END IF
END FOR
END IF
# 4. Check for collisions
FOR EACH obstacle IN obstacles DO
IF [x position of obstacle] = [x position of bird]
AND [y position of obstacle] = [y position of bird] THEN
GAME OVER
END IF
END FOR
# 5. Timing
CHANGE ticks BY 1
PAUSE 1000 ms
END FOREVER
Blocks version (Crashy Bird reference)
Step-by-Step Build Notes (Verbose)
Step 1 – Initialise Bird, Array and Timer
WHEN program starts DO
SET bird TO NEW SPRITE AT (0, 2)
SET blink_of_bird TO 300 ms
SET obstacles TO empty array
SET ticks TO 0
END WHEN
What this does
- Runs once at the very start of the program.
- Creates the bird sprite at the left‑middle of the LED grid (x = 0, y = 2).
- Uses the set blink property block to make the bird blink every 300 ms so it is easier to see.
- Creates an empty array called
obstacles— this will later hold many obstacle sprites. - Sets
ticksto 0, ready to act as a simple loop counter / timer.
How to explain it to participants
- Compare
obstaclesto an empty container which will soon hold many obstacle sprites.“Right now the array is empty, but as the game runs, we’ll keep adding obstacle sprites into it.”
- Emphasise that no obstacles exist yet; we are just preparing the structures we need before the game starts.
Things to check
- Bird appears at the left and blinks steadily.
- No errors on download, even though
obstaclesis empty.
Step 2 – Player Controls (Up / Down)
WHEN button A is pressed DO
CHANGE bird y BY -1
END WHEN
WHEN button B is pressed DO
CHANGE bird y BY +1
END WHEN
What this does
- Button A moves the bird up one row.
- Button B moves the bird down one row.
- This mirrors earlier weeks’ control schemes, so it should feel familiar.
How to explain it
- Re‑draw the 5×5 grid and mark y positions 0 (top) to 4 (bottom).
- Ask: “If the bird is at y = 2 and we press A, what does y become?” → 1.
-
Connect this to coordinates used in previous projects:
“x is left–right, y is up–down. Here we only change y, so the bird slides in a vertical line.”
Things to check
- Bird moves exactly one step per press.
- If it goes off‑screen (y < 0 or y > 4), that is OK for now — the main focus is on the array logic later.
Step 3 – The Game Loop (forever)
From now on, all the “game logic” lives inside the forever loop.
You can explain it like this:
“The
foreverloop is the game engine. Every time it runs, it:
1) cleans up old obstacles,
2) moves all current obstacles,
3) maybe spawns new ones,
4) checks for collisions, and
5) waits a bit before the next cycle.”
3a – Remove Off‑Screen Obstacles
WHILE [length of obstacles] > 0
AND [x position of obstacles[0]] = 0 DO
DELETE SPRITE obstacles[0]
REMOVE element at index 0 FROM obstacles
END WHILE
What this does
- Looks at the first obstacle in the array (
obstacles[0]). - If:
- the array is not empty, and
- the x‑position of that first obstacle is 0 (left edge),
then that obstacle is about to leave the screen on the next move.
- The code:
- deletes the sprite so it disappears from the LEDs, and
- removes the reference from the
obstaclesarray.
- The
whileloop repeats in case more than one obstacle at the front of the array has x = 0 (for example, in a full column of obstacles).
How to explain it
- Draw a column of obstacle sprites moving left across the screen.
- Mark the leftmost as
obstacles[0], next asobstacles[1], and so on. - Explain:
“When the first obstacle reaches the left edge, we don’t want to keep tracking it forever. We delete it from the screen and remove it from the array so the game stays tidy and fast.”
Common mistakes
- Using
ifinstead ofwhile→ only one obstacle is removed even if an entire column has reached x = 0. - Forgetting to call both:
delete sprite obstacles[0], andremove element at index 0 from obstacles→ this leaves “ghost” entries in the array that no longer exist on screen.
Debugging tip
- Temporarily show
length of obstacleson the display or in the console.
If the length keeps increasing even when obstacles leave the grid, the clean‑up code isn’t working correctly.
3b – Move All Obstacles Left
FOR EACH obstacle IN obstacles DO
CHANGE obstacle x BY -1
END FOR
What this does
- Loops through every obstacle sprite stored in the array.
- Moves each one one step left (towards the bird).
- Works the same whether there are 0, 3 or 20 obstacles in the array.
How to explain it
-
Link back to Part A and B:
“Before, we looped through every word or every image in an array.
Now we loop through an array of sprites and move each sprite one step.” -
Emphasise the power of arrays:
“Instead of writing separate code for obstacle 1, obstacle 2, obstacle 3… we have a single array and a single loop that handles them all.”
Common mistakes
- Accidentally changing
yinstead ofx(obstacles move up/down instead of sideways). - Forgetting this step completely, which makes newly‑spawned obstacles appear but never move.
Good discussion question
- “What would the game feel like if we removed this loop? Would it still be a scrolling game?”
Let learners describe the behaviour: static obstacles suddenly appearing on the right and never moving.
3c – Spawn New Obstacles
IF [remainder of (ticks / 3)] = 0 THEN
SET gap_row TO [random number from 0 to 4]
FOR row FROM 0 TO 4 DO
IF row ≠ gap_row THEN
SET new_obstacle TO NEW SPRITE AT (4, row)
ADD new_obstacle TO obstacles
END IF
END FOR
END IF
What this does
- Uses
ticksas a basic timer: each cycle offoreveradds 1 toticks. - The MakeCode-style block remainder of (ticks / 3) gives the remainder when you divide
ticksby 3. - The condition
remainder of (ticks / 3) = 0means:“Do this when ticks is a multiple of 3: 0, 3, 6, 9, 12, …”
- When that happens:
- Choose a gap row randomly between 0 and 4.
- Loop over each row
0, 1, 2, 3, 4. - For every row that is not the gap row, create a new obstacle sprite at (4, row) and add it to the
obstaclesarray. - The result is a “wall” of obstacles with one missing LED — that missing LED is the tunnel for the bird.
How to explain it
-
Connect to maths explicitly:
“The remainder is what is left after division.
If ticks = 7 and we divide by 3, we get 2 remainder 1.
Only when the remainder is 0 (like 0, 3, 6, 9, …) do we create new obstacles.” -
Relate this to gameplay:
“Every few moments, a new wall of obstacles appears on the right. One random row in that wall is left empty, so the bird has somewhere to fly.”
Things they can safely tweak
- Change the divisor in
remainder of (ticks / something)and see how often new obstacles appear. - Use two gap rows instead of one to make the game easier (e.g. allow both
gapRowandgapRow + 1to be empty, if still within 0–4).
Common mistakes
- Forgetting to add each newly created obstacle to the
obstaclesarray → the sprite appears once but never moves or collides. - Using an incorrect random range (for example,
random 1 to 4), which means some rows never become the gap.
3d – Detect Collisions
FOR EACH obstacle IN obstacles DO
IF [x position of obstacle] = [x position of bird]
AND [y position of obstacle] = [y position of bird] THEN
GAME OVER
END IF
END FOR
What this does
- Loops through every obstacle sprite in the array.
- Compares its (x, y) position to the bird’s position.
- If both x and y match, a collision is detected and the game ends.
How to explain it
-
Re‑use the coordinate grid from earlier:
“Imagine writing the bird’s coordinates as (x, y).
A collision happens when an obstacle has exactly the same pair: same x and same y.
That means they are on the same LED.” -
Link back to previous games (e.g. Space Invaders‑style projects) where collisions were also based on coordinates.
Common mistakes
- Only comparing x or only comparing y, not both → collisions trigger early or not at all.
- Checking only a single obstacle and forgetting to loop through the entire array.
Simple test
- Ask a learner to intentionally fly into an obstacle and confirm that the game ends as soon as they overlap.
3e – Timing with ticks and pause
CHANGE ticks BY 1
PAUSE 1000 ms
What this does
ticksgoes up by 1 on every pass throughforever.pause 1000 msmakes the program wait about one second before starting the next cycle.- Because the spawn logic depends on
ticks, changing the pause or the remainder condition changes how challenging the game feels.
How to explain it
-
Clarify that
ticksis just a counter, not “seconds”:“ticks is a number that increases every time the loop runs.
We use it with the remainder rule to decide when to create new obstacles.” -
Illustrate with a short table:
ticks remainder of (ticks / 3) spawn? 0 0 yes 1 1 no 2 2 no 3 0 yes
Extension ideas
- Let learners try:
pause 500 ms(faster game), orpause 200 ms(very fast, harder to survive).
- Ask: “What changes if we use remainder of (ticks / 4) instead of 3?” (Obstacles appear less often.)
Instructor Tips
- Keep repeating the core idea:
“One array holds all the obstacles. One loop lets us update them all in one go.”
- When supporting debugging, help learners decide which part is going wrong:
- removal, movement, spawning, collision, or timing.
- Encourage them to refer to the pseudocode as a map while they work on their blocks.
Common Misconceptions & Fixes
- “Arrays start at 1.”
- Re‑draw the index boxes from Part A: first element is index 0.
- “Arrays only store numbers.”
- Remind them of Part B (images) and Part C (sprites). Arrays store many types, as long as each array is consistent.
- “Obstacles disappear automatically when they leave the grid.”
- Demonstrate what happens when the removal code is disabled: the array grows and the game slows.
- “You only need to check one obstacle for collisions.”
- Show a case with two obstacles in the same column; only checking one would miss the closer one.
Differentiation
Support
- Provide a starter project with:
- bird created and blinking,
- up/down controls working,
- an empty
foreverloop already in place.
- Let less‑confident participants focus on:
- movement,
- basic spawning, and
- simple collision,
rather than every optimisation.
Extend
- Add a score that increases each cycle while the player is still alive.
- Speed up the game over time by:
- reducing the
pause, or - changing the spawn remainder from 3 to 2 after a certain number of ticks.
- reducing the
- Add sound:
- a flap sound when the bird moves,
- a crash sound on game over.
- Experiment with patterns:
- double gaps,
- moving gaps,
- “bonus” rows with extra points.
Reflection Questions
Use these for whole-class discussion or at the end of the session:
- “In your own words, what is an array?”
- “Why is an array useful in Crashy Bird instead of using lots of separate variables?”
- “Where in your game do you loop through every obstacle?”
- “What would happen if we never removed off-screen obstacles from the array?”