Gamedev Phaser Content Kit

Article 13: Extra lives

We can make the game enjoyable for longer by adding lives. If the player lose one life he can continue playing until he runs out of them. Add the variables we will need for lives and the text message that will be shown on screen when the player lose one of his lives:

var lives = 3;
var livesText;
var lifeLostText;

Defining the texts look like something we already did in the score lesson:

scoreText = game.add.text(5, 5, 'Points: 0', { font: '18px Arial', fill: '#0095DD' });
livesText = game.add.text(game.world.width-5, 5, 'Lives: '+lives, { font: '18px Arial', fill: '#0095DD' });
livesText.anchor.set(1,0);
lifeLostText = game.add.text(game.world.width*0.5, game.world.height*0.5, 'Life lost, click to continue', { font: '18px Arial', fill: '#0095DD' });
lifeLostText.anchor.set(0.5);
lifeLostText.visible = false;

The lifeText object looks very similar to the scoreText one - have a position on the screen, the actual text and the font styling. It is also anchored on its top right edge to align properly with the screen.

The lifeLostText will be shown only when the life will be lost, so its visibility is set to false at the beginning. Its anchor is set in the middle of the text to show it in the center of the screen.

As you probably noticed we're using the same styling for all three texts: scoreText, livesText and lifeLostText. If we ever want to change the font size or color we will have to do it in multiple places. To make it easier for us to maintain in the future we can create a separate variable that will hold our styling, let's call it textStyle:

textStyle = { font: '18px Arial', fill: '#0095DD' };

We can use this variable when creating the texts:

scoreText = game.add.text(5, 5, 'Points: 0', textStyle);
livesText = game.add.text(game.world.width-5, 5, 'Lives: '+lives, textStyle);
livesText.anchor.set(1,0);
lifeLostText = game.add.text(game.world.width*0.5, game.world.height*0.5, 'Life lost, click to continue', textStyle);
lifeLostText.anchor.set(0.5);
lifeLostText.visible = false;

This way changing the font in one variable will apply the changes in every place it is used.

To implement lives in our game, let's first change the ball's function bound to the onOutOfBounds event. Instead of executing the function right away and showing the alert:

ball.events.onOutOfBounds.add(function(){
    alert('Game over!');
    location.reload();
}, this);

We will assign new function called ballLeaveScreen:

ball.events.onOutOfBounds.add(ballLeaveScreen, this);

We want to decrease the number of lives every time the ball leaves the Canvas. Add that function at the end of our code:

function ballLeaveScreen() {
    lives--;
    if(lives) {
        livesText.setText('Lives: '+lives);
        lifeLostText.visible = true;
        ball.reset(game.world.width*0.5, game.world.height-25);
        paddle.reset(game.world.width*0.5, game.world.height-5);
        game.input.onDown.addOnce(function(){
            lifeLostText.visible = false;
            ball.body.velocity.set(150, -150);
        }, this);
    }
    else {
        alert('You lost, game over!');
        location.reload();
    }
}

Instead of instantly printing out the alert when you lose the life, we will subtract one life from the current number and check if it's a non-zero value. If yes, then the player still have some lives left and can continue to play - he will see the life lost message, the ball's and paddle's positions will be reset on screen and on the next input (click or touch) the message will be hidden and the ball will start to move.

If the number of available lives will reach zero, then the game is over and the proper alert message will be shown.

Compare your code

You can check the finished code for this lesson for yourself in the live demo below, and play with it to understand better how it works:

Next steps

Lives made the game more forgiving - if you lose one life, you still have two more left and can continue to play. Now let's expand the look and feel of the game by adding animations and tweens.