Give the player lives, make a hit cost one, and let the engine end the game.
Three hearts in the corner and a game that can end: that is what turns moving sprites into a game you can win or lose.
Last lesson the score went up and down, but the game never ended. Arcade's Info blocks keep a score and lives (hearts) at the top of the screen, and they end the game by themselves.
Make your prediction first. Help opens once you've locked it in.

info.setLife(3)
let mySprite = sprites.create(img`
. 4 4 .
4 4 4 4
. 8 8 .
. 8 8 .
`, SpriteKind.Player)
mySprite.setPosition(20, 60)
let rock = sprites.create(img`
. e e .
e e e e
e e e e
`, SpriteKind.Enemy)
rock.setPosition(160, 60)
rock.vx = -50
let rock2 = sprites.create(img`
. e e .
e e e e
e e e e
`, SpriteKind.Enemy)
rock2.setPosition(240, 60)
rock2.vx = -50
let rock3 = sprites.create(img`
. e e .
e e e e
e e e e
`, SpriteKind.Enemy)
rock3.setPosition(320, 60)
rock3.vx = -50
sprites.onOverlap(SpriteKind.Player, SpriteKind.Enemy, function (sprite, otherSprite) {
info.changeLifeBy(-1)
otherSprite.destroy()
})
There is no game over block in this program. Lock in what you think happens.
Watch the hearts at the top of the screen. Use the restart button under the simulator to play again.

info.setLife(3)
let mySprite = sprites.create(img`
. 4 4 .
4 4 4 4
. 8 8 .
. 8 8 .
`, SpriteKind.Player)
mySprite.setPosition(20, 60)
let rock = sprites.create(img`
. e e .
e e e e
e e e e
`, SpriteKind.Enemy)
rock.setPosition(160, 60)
rock.vx = -50
let rock2 = sprites.create(img`
. e e .
e e e e
e e e e
`, SpriteKind.Enemy)
rock2.setPosition(240, 60)
rock2.vx = -50
let rock3 = sprites.create(img`
. e e .
e e e e
e e e e
`, SpriteKind.Enemy)
rock3.setPosition(320, 60)
rock3.vx = -50
sprites.onOverlap(SpriteKind.Player, SpriteKind.Enemy, function (sprite, otherSprite) {
info.changeLifeBy(-1)
otherSprite.destroy()
})
Dodge the rocks with the arrow keys and collect the heart. Lose on purpose once, too.

info.setLife(3)
let mySprite = sprites.create(img`
. 4 4 .
4 4 4 4
. 8 8 .
. 8 8 .
`, SpriteKind.Player)
mySprite.setPosition(20, 60)
controller.moveSprite(mySprite)
mySprite.setStayInScreen(true)
let heart = sprites.create(img`
2 2 . 2 2
2 2 2 2 2
. 2 2 2 .
. . 2 . .
`, SpriteKind.Food)
heart.setPosition(80, 100)
let rock = sprites.create(img`
. e e .
e e e e
e e e e
`, SpriteKind.Enemy)
rock.setPosition(160, 30)
rock.vx = -40
let rock2 = sprites.create(img`
. e e .
e e e e
e e e e
`, SpriteKind.Enemy)
rock2.setPosition(240, 60)
rock2.vx = -40
let rock3 = sprites.create(img`
. e e .
e e e e
e e e e
`, SpriteKind.Enemy)
rock3.setPosition(320, 90)
rock3.vx = -40
sprites.onOverlap(SpriteKind.Player, SpriteKind.Enemy, function (sprite, otherSprite) {
info.changeLifeBy(-1)
otherSprite.destroy()
})
sprites.onOverlap(SpriteKind.Player, SpriteKind.Food, function (sprite, otherSprite) {
info.changeLifeBy(1)
otherSprite.destroy()
})
Sam's overlap event:

sprites.onOverlap(SpriteKind.Player, SpriteKind.Enemy, function (sprite, otherSprite) {
info.changeLifeBy(-1)
})
Play this game in your head. Fill in the lives after each thing happens.
| what happens | lives after |
|---|---|
| (start) | 3 |
| a rock hits the player | |
| a rock flies past | |
| the player collects the heart | |
| a rock hits the player |
Start the player with 5 lives.
Change the 3 in set life.
Make the heart give a point as well as a life.
Inside the Player–Food event, add change score by 1 (Info) next to change life by 1.
Start the player with 5 lives.
This ticks by itself when your blocks do what is asked.
Collecting the heart also scores a point.
This ticks by itself when your blocks do what is asked.

let mySprite = sprites.create(img`
. 4 4 .
4 4 4 4
. 8 8 .
. 8 8 .
`, SpriteKind.Player)
mySprite.setPosition(20, 60)
let coin = sprites.create(img`
. 5 5 .
5 5 4 5
5 4 5 5
. 5 5 .
`, SpriteKind.Food)
coin.setPosition(150, 60)
coin.vx = -30
sprites.onOverlap(SpriteKind.Player, SpriteKind.Food, function (sprite, otherSprite) {
info.changeScoreBy(1)
otherSprite.destroy()
})
sprites.onOverlap(SpriteKind.Player, SpriteKind.Enemy, function (sprite, otherSprite) {
info.changeLifeBy(-1)
otherSprite.destroy()
})
The rocks fly already. Make it a game:
In on start: set life to 3 (Info).
Add an on overlap for Player and Enemy. Inside: change life by -1, then destroy otherSprite.
A dodge game: 3 lives, and a rock that hits takes one life and is destroyed.
This ticks by itself when your blocks do what is asked.
Balls bounce around the court; each hit costs a life. Add a fourth ball, give the player 5 lives, and make the balls a little faster.
Students give the player lives, make a hit cost one life, and see that the engine ends the game at 0 lives and that an overlap runs every frame while sprites touch. About 40 minutes.
Open the teacher guide: answers, solutions, slides and a worksheet.
Info blocks keep a score and lives (hearts) at the top of the screen. When the lives reach 0, Arcade ends the game by itself. One important fact: an overlap event runs every frame (about 30 times a second) while the two sprites still touch. If the enemy is not destroyed, one touch takes life after life, and the game ends at once. Timers (a new enemy every second) are next lesson; here the rocks are made at the start and flown in with a velocity.
An overlap runs every frame while sprites touch, so one hit takes every life. Ask what happens to the enemy after it touches the player.
Stretch: Add a coin worth points, so there is something to chase as well as dodge.
Support: Give students the overlap event already placed, and ask them to fill in the two blocks inside.
Next lesson: a timer that sends a new rock every second, for as long as the game lasts.