Extra lives

This is the 8th step out of 11 of the creating a Breakout game using pure JavaScript tutorial. In this article, we'll implement a lives system, so that the player can continue playing until they have lost three lives, not just one, which makes the game enjoyable for longer.

New variables

Add two new variables below let score = 0; to store the number of lives and whether to display the life lost message:

js
let lives = 3;
let showLifeLostText = false;

Drawing the text labels

Drawing the texts looks like something we already did in the Track the score and win lesson. Replace drawScore() with a drawStatus() function that draws the score, the remaining lives, and a message when the player loses a life:

js
function drawStatus() {
  ctx.font = "18px Arial";
  ctx.fillStyle = "#0095dd";
  ctx.textBaseline = "top";
  ctx.textAlign = "left";
  ctx.fillText(`Points: ${score}`, 5, 5);

  ctx.textAlign = "right";
  ctx.fillText(`Lives: ${lives}`, canvas.width - 5, 5);

  if (showLifeLostText) {
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.fillText(
      "Life lost, click to continue",
      canvas.width / 2,
      canvas.height / 2,
    );
  }
}

The three labels share the same font and color. We use textAlign and textBaseline to position the score at the top left, the lives at the top right, and the life lost message in the center (if showLifeLostText is true).

In update(), replace the drawScore() call with drawStatus().

The lives handling code

To implement lives in our game, let's first change the behavior when the ball gets out of bounds. Instead of restarting right away:

js
if (ballIsOutOfBounds) {
  // Game over logic
  location.reload();
  return;
}

We will call a new function called ballLeaveScreen(); delete the previous lines (shown above) and replace it with the following line:

js
if (ballIsOutOfBounds) {
  ballLeaveScreen();
  return;
}

The return stops processing the remaining movement and collisions for this frame after the ball leaves the screen.

We want to decrease the number of lives every time the ball leaves the canvas. Add the ballLeaveScreen() function to your code:

js
function ballLeaveScreen() {
  lives--;
  if (lives === 0) {
    // Game over logic
    location.reload();
    return;
  }

  paddle.pos.x = canvas.width / 2;
  ball.pos.x = paddle.pos.x;
  ball.pos.y = paddle.hitbox.top - ball.size.h / 2;
  ball.vel = { x: 0, y: 0 };
  showLifeLostText = true;
  canvas.addEventListener(
    "pointerdown",
    () => {
      showLifeLostText = false;
      ball.vel = { x: 150, y: -150 };
      lastTimestamp = null;
    },
    { once: true },
  );
}

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

When the number of available lives reaches zero, the game is over, and the game over alert message will be shown.

Compare your code

Here's what you should have so far, running live. To view its source code, click the "Play" button.

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.