← Arcade advanced skills

Level up

Keep the level in a variable and change it where the score changes, with a goal that moves up each time.

Almost every game gets harder as you play. Behind it is one number, the level, and one place where it changes.

A game with levels needs a variable, level, that remembers where the player is, and one place where it goes up. This game also keeps a goal: the score the next level needs.

The splash uses join (in Text) to stick the word Level and the number together. Copy it as it is for now.

PredictRead the code and say what it will do before you run anything. A wrong guess is fine: it shows you what to look for.

Predict

The program as blocks
Show as code
lesson.ts
let enemy: Sprite = null
let level = 1
let goal = 5
function addEnemy () {
    enemy = sprites.create(img`
        a . . a
        a a a a
        a 1 1 a
        a a a a
        `, SpriteKind.Enemy)
    enemy.setPosition(80, 10)
    enemy.setVelocity(50, 40)
    enemy.setBounceOnWall(true)
}
let player = sprites.create(img`
    . 4 4 .
    4 4 4 4
    . 8 8 .
    . 8 8 .
    `, SpriteKind.Player)
controller.moveSprite(player)
player.setStayInScreen(true)
let coin = sprites.create(img`
    . 5 5 .
    5 5 4 5
    5 4 5 5
    . 5 5 .
    `, SpriteKind.Food)
coin.setPosition(randint(10, 150), randint(10, 110))
info.setLife(3)
addEnemy()
sprites.onOverlap(SpriteKind.Player, SpriteKind.Food, function (sprite, otherSprite) {
    otherSprite.setPosition(randint(10, 150), randint(10, 110))
    info.changeScoreBy(1)
    if (info.score() >= goal) {
        level += 1
        goal += 5
        game.splash("Level " + level)
        addEnemy()
    }
})
sprites.onOverlap(SpriteKind.Player, SpriteKind.Enemy, function (sprite, otherSprite) {
    info.changeLifeBy(-1)
    otherSprite.setPosition(80, 10)
})

Read the Player–Food overlap. What is goal after the first level-up?

You collect 5 coins, then one more. What happens?

RunRun it and compare the result with your prediction.

Run

Collect coins and dodge the enemies. Press A (space) to close each splash.

The program as blocks
Show as code
lesson.ts
let enemy: Sprite = null
let level = 1
let goal = 5
function addEnemy () {
    enemy = sprites.create(img`
        a . . a
        a a a a
        a 1 1 a
        a a a a
        `, SpriteKind.Enemy)
    enemy.setPosition(80, 10)
    enemy.setVelocity(50, 40)
    enemy.setBounceOnWall(true)
}
let player = sprites.create(img`
    . 4 4 .
    4 4 4 4
    . 8 8 .
    . 8 8 .
    `, SpriteKind.Player)
controller.moveSprite(player)
player.setStayInScreen(true)
let coin = sprites.create(img`
    . 5 5 .
    5 5 4 5
    5 4 5 5
    . 5 5 .
    `, SpriteKind.Food)
coin.setPosition(randint(10, 150), randint(10, 110))
info.setLife(3)
addEnemy()
sprites.onOverlap(SpriteKind.Player, SpriteKind.Food, function (sprite, otherSprite) {
    otherSprite.setPosition(randint(10, 150), randint(10, 110))
    info.changeScoreBy(1)
    if (info.score() >= goal) {
        level += 1
        goal += 5
        game.splash("Level " + level)
        addEnemy()
    }
})
sprites.onOverlap(SpriteKind.Player, SpriteKind.Enemy, function (sprite, otherSprite) {
    info.changeLifeBy(-1)
    otherSprite.setPosition(80, 10)
})
Try it yourselfYour edits are saved in this browser.
It takes a few seconds to load. Your work in this step is kept.

InvestigateTrace how each line of code connects to what you see.

Investigate

The program as blocks
Show as code
lesson.ts
let enemy: Sprite = null
let level = 1
let goal = 5
function addEnemy () {
    enemy = sprites.create(img`
        a . . a
        a a a a
        a 1 1 a
        a a a a
        `, SpriteKind.Enemy)
    enemy.setPosition(80, 10)
    enemy.setVelocity(50, 40)
    enemy.setBounceOnWall(true)
}
let player = sprites.create(img`
    . 4 4 .
    4 4 4 4
    . 8 8 .
    . 8 8 .
    `, SpriteKind.Player)
controller.moveSprite(player)
player.setStayInScreen(true)
let coin = sprites.create(img`
    . 5 5 .
    5 5 4 5
    5 4 5 5
    . 5 5 .
    `, SpriteKind.Food)
coin.setPosition(randint(10, 150), randint(10, 110))
info.setLife(3)
addEnemy()
sprites.onOverlap(SpriteKind.Player, SpriteKind.Food, function (sprite, otherSprite) {
    otherSprite.setPosition(randint(10, 150), randint(10, 110))
    info.changeScoreBy(1)
    if (info.score() >= goal) {
        level += 1
        goal += 5
        game.splash("Level " + level)
        addEnemy()
    }
})
sprites.onOverlap(SpriteKind.Player, SpriteKind.Enemy, function (sprite, otherSprite) {
    info.changeLifeBy(-1)
    otherSprite.setPosition(80, 10)
})

Follow level and goal coin by coin.

Zoe's level-up:

The program as blocks
Show as code
game.onUpdate(function () {
    if (info.score() >= 5) {
        level += 1
        game.splash("Level " + level)
        addEnemy()
    }
})
Try it yourselfYour edits are saved in this browser.
It takes a few seconds to load. Your work in this step is kept.

level starts at 1 and goal at 5. Fill in level and goal after each coin.

scorelevelgoal
015
5
6
10

Ben deleted change goal by 5. What happens after his 5th coin?

Zoe moved the level-up into on game update (below). The moment she reaches 5 points the splashes never stop, though she collects no more coins. Why?

ModifyChange the code on purpose and check the result.

Modify

Make a new level come every 3 coins.

Need a hint?

Two numbers: the goal you start with and how much it changes by.

Another hint

Both 3.

Give the player a bonus life at every new level. One block, in the right place.

Need a hint?

change life by 1 (Info) goes inside the level-up if.

Try it yourselfYour edits are saved in this browser.
It takes a few seconds to load. Your work in this step is kept.

A new level every 3 coins.

This ticks by itself when your blocks do what is asked.

A bonus life at every new level.

This ticks by itself when your blocks do what is asked.

InvestigateTrace how each line of code connects to what you see.

Mix it up

The program as blocks
Show as code
lesson.ts
scene.setBackgroundColor(9)
let player = sprites.create(img`
    . 4 4 .
    4 4 4 4
    . 8 8 .
    . 8 8 .
    `, SpriteKind.Player)
player.ay = 300
game.onUpdate(function () {
    if (player.bottom > 80) {
        player.bottom = 80
        player.vy = 0
    }
})
controller.A.onEvent(ControllerButtonEvent.Pressed, function () {
    if (player.bottom >= 100) {
        player.vy = -150
    }
})

Ana raises the floor: the floor if now puts the player's bottom at 80. Her jump still asks bottom ≥ 100. What number should the jump ask about now?

MakeBuild something new using what you have learned. Expect a few tries; that is normal.

Make

This is your runner from last lesson. Every rock that appears scores a point. Give it levels:

Try it yourselfYour edits are saved in this browser.
It takes a few seconds to load. Your work in this step is kept.
Need a hint?

Two new variables in on start: level 1 and goal 10.

Another hint

The score changes in the timer, so the level-up goes there, just after change score.

Another hint

Inside the if: change level by 1, change goal by 10, change speed by -20, and a splash.

Every 10 points the runner levels up: a splash, and faster rocks.

This ticks by itself when your blocks do what is asked.

ModifyChange the code on purpose and check the result.

Change a fishing game

Catch fish with the net. Every 5 fish the level goes up and the fish swim faster. Make the water darker at every level too: one block, in the level-up.

Try it yourselfYour edits are saved in this browser.
It takes a few seconds to load. Your work in this step is kept.
For teachers

Students keep the level in a variable, change it where the score changes with a goal that moves up, see why a level-up in on game update fires every frame, and add levels to their runner. About 45 minutes.

Open the teacher guide: answers, solutions, slides and a worksheet.

Students will be able to

Before class

A level is a variable that starts at 1 and changes by 1. The level-up is an if in the event where the score changes (here the coin overlap): if score ≥ goal, change level by 1, change goal by 5, splash and add an enemy. goal is a target that moves up, so the question is false again until 5 more coins.

The trap is the lesson's misconception: put if score ≥ 5 in on game update and it fires every frame while the score stays 5 or more, so the level races up. The splash uses join ("Level " + level), labelled copy-for-now.

Next lesson keeps what changes per level in a list.

Running the lesson

  1. Predict: most students expect Level 2 at 5 coins. Ask what happens at 6.
  2. Investigate: Ben's game shows why goal moves; Zoe's shows why on game update is the wrong place.
  3. Modify: both numbers must change for every 3 coins. The bonus life shows the if runs once per level.
  4. Mix it up: the jump from last lesson.
  5. Make: the runner's score changes in the timer, so the level-up goes there.

The hard part (on purpose)

Where the level-up goes. When levels race up, ask how often that block runs.

When students get stuck

Stretch and support

Stretch: Win the game at level 5: an if inside the level-up with game over (win).

Support: Give students the level and goal variables in the Make starter, so they write only the if in the timer.

Where it leads

Next: a list per level, so each level can have its own background and speed. Skillmap: Jungle Jump Platformer (arcade.makecode.com/skillmaps) moves between level maps.

What each step is for

Now you can
Next lesson7. A list per levelKeep what changes from level to level in a list, and look it up with the level as the place, counted from 0.