Build a complete game that uses everything so far. Steer a ship through rocks, keep your lives, and beat your high score.
Asteroids, Flappy Bird and every endless runner are the same game underneath: things come at you, you dodge, and the longer you last the better you score.
Your ship sits on the left and moves up and down. Rocks fly in from the right. Touch one and you lose a life; survive and your score climbs. You will build it in three milestones, with less help each time.
You already know every idea it needs. Two blocks are new, and each comes with a Behind the code note when you need it.
Make your prediction first. Help opens once you've locked it in.

let rock: Sprite = null
scene.setBackgroundColor(15)
let ship = sprites.create(img`
8 8 . . . . . .
8 9 9 9 9 . . .
8 9 1 1 9 9 9 9
8 9 9 9 9 . . .
8 8 . . . . . .
`, SpriteKind.Player)
ship.setPosition(20, 60)
controller.moveSprite(ship, 0, 100)
ship.setStayInScreen(true)
game.onUpdateInterval(1000, function () {
rock = sprites.create(img`
. e e e .
e e d e e
e d e e e
. e e e .
`, SpriteKind.Enemy)
rock.setPosition(160, 60)
rock.vx = -50
})
The ship can only move up and down: moveSprite(ship, 0, 100) gives it no speed across.
Move with the up and down arrows (or W and S). Is it hard to dodge rocks that always come the same way?

let rock: Sprite = null
scene.setBackgroundColor(15)
let ship = sprites.create(img`
8 8 . . . . . .
8 9 9 9 9 . . .
8 9 1 1 9 9 9 9
8 9 9 9 9 . . .
8 8 . . . . . .
`, SpriteKind.Player)
ship.setPosition(20, 60)
controller.moveSprite(ship, 0, 100)
ship.setStayInScreen(true)
game.onUpdateInterval(1000, function () {
rock = sprites.create(img`
. e e e .
e e d e e
e d e e e
. e e e .
`, SpriteKind.Enemy)
rock.setPosition(160, 60)
rock.vx = -50
})
This is the working start of the game. Read it, and change numbers in the playground to test your answers.

let rock: Sprite = null
scene.setBackgroundColor(15)
let ship = sprites.create(img`
8 8 . . . . . .
8 9 9 9 9 . . .
8 9 1 1 9 9 9 9
8 9 9 9 9 . . .
8 8 . . . . . .
`, SpriteKind.Player)
ship.setPosition(20, 60)
controller.moveSprite(ship, 0, 100)
ship.setStayInScreen(true)
game.onUpdateInterval(1000, function () {
rock = sprites.create(img`
. e e e .
e e d e e
e d e e e
. e e e .
`, SpriteKind.Enemy)
rock.setPosition(160, 60)
rock.vx = -50
})
Match each block with its job.
The timer in Python:
def on_update_interval():
global rock
rock = sprites.create(img("""..."""), SpriteKind.enemy)
rock.set_position(160, 60)
rock.vx = -50
game.on_update_interval(1000, on_update_interval)
The timer becomes a def: a named job handed to the game, which runs it every second. Blocks write this for you. (Functions are the first lesson of Arcade advanced skills.)
Work it out from the numbers.
Watch a rock that misses the ship.

sprites.onOverlap(SpriteKind.Player, SpriteKind.Enemy, function (sprite, otherSprite) {
info.changeLifeBy(-1)
})
Match each block with its job in the game.
A rock starts at x 160 and moves 50 pixels left every second. The ship is at x 20. How many seconds does the rock take to reach the ship?
Behind the code: set rock auto destroy on (Sprites, the set flag block) tells the engine to remove the sprite as soon as it leaves the screen. Without it, every rock that missed the ship keeps flying forever.
In the timer, replace the 60 in set rock position with pick random 10 to 110 (from Math).
Drag set rock auto destroy (Sprites, set flag) into the timer, under set rock vx.
Each rock starts at a random height and is removed once it leaves the screen.
This ticks by itself when your blocks do what is asked.
Give the player 3 lives, and make a hit count:
Set life to 3 in on start. Then drag in on sprite of kind Player overlaps otherSprite of kind Enemy.
Inside the overlap: destroy otherSprite, then change life by -1.
Start with 3 lives; a rock that hits the ship is destroyed and takes one life.
This ticks by itself when your blocks do what is asked.
Behind the code: high score (in Info) is the best score so far in this browser. The game over screen shows it by itself; you can also use it in your blocks.
Finish the game:
Add a second on game update every 1000 ms. Inside it: change score by 1.
high score is in Info. Try: if score > high score, set the background to a new colour, so the player sees they are beating their best.
Score one point for every second survived, and use the high score in your game.
This ticks by itself when your blocks do what is asked.
The same game turned on its side: cars drive across, and the chick scores by reaching the top. Make it yours. Ideas: faster cars as the score goes up, cars from both sides, a second lane of logs, or a short effect when a car hits (Sprites › Effects).

sprites.onOverlap(SpriteKind.Player, SpriteKind.Enemy, function (sprite, otherSprite) {
otherSprite.destroy()
info.changeLifeBy(-1)
})
let car: Sprite = null
scene.setBackgroundColor(7)
let chick = sprites.create(img`
. 5 5 .
5 f 5 4
5 5 5 .
. 4 4 .
`, SpriteKind.Player)
chick.setPosition(80, 112)
controller.moveSprite(chick, 60, 60)
chick.setStayInScreen(true)
info.setLife(3)
game.onUpdateInterval(800, function () {
car = sprites.create(img`
2 2 2 2 2 .
2 9 2 2 9 2
2 2 2 2 2 2
. f . . f .
`, SpriteKind.Enemy)
car.setPosition(0, randint(25, 95))
car.vx = 60
car.setFlag(SpriteFlag.AutoDestroy, true)
})
game.onUpdate(function () {
if (chick.y < 10) {
info.changeScoreBy(1)
chick.setPosition(80, 112)
}
})
Students build a complete dodging game in three milestones, using a timer, random positions, velocity, overlaps, lives, score and the high score. About 60 minutes.
Open the teacher guide: answers, solutions, slides and a worksheet.
This lesson uses everything from the course, with only two new blocks: auto destroy (the set flag block in Sprites removes a sprite once it leaves the screen) and high score (in Info: the best score so far in this browser, shown on the game over screen by itself). The game: a timer (on game update every 1000 ms) makes a rock at the right edge, and a negative vx carries it left; an overlap event between Player and Enemy destroys the rock and takes a life; a second timer adds 1 to the score every second. The milestones fade the help: Milestone 1 gives nearly all the code, Milestone 2 an outline, Milestone 3 only goals. Play it yourself first. The core is Milestones 1 and 2; Milestone 3 and the road crossing finish the lesson for most students.
Combining a timer, velocity and overlaps in one game. Point them to the milestone they're on and ask them to get that part playing first.
Stretch: Make the rocks faster as the score grows: set rock vx to 0 - (50 + score), so a long game gets harder by itself.
Support: Pair students for Milestone 3: one reads the goals aloud while the other builds. A student who finishes Milestone 2 has a complete, playable game.
Course complete. Next: Arcade advanced skills (functions, gravity, levels and power-ups). For more practice building whole games, MakeCode's Beginner Skillmap (arcade.makecode.com/skillmaps) uses the same blocks. Class ideas: a class high-score board on the whiteboard; swap games with a partner and suggest one change that makes it fairer or harder.