Gamedev Canvas Content Kit

Article 08: Track the score and win

Destroying the bricks is really cool, but to be even more awesome we could award points for every brick we hi, and keep count of the total score.

Counting the score

If we can see our score throughout the game, eventually we can impress our friends. We will need a variable to record the score — add the following into your JavaScript, below the rest of your variables:

var score = 0;

We also need a drawScore() function, to create and update the score display — add the following below the collisionDetection() function:

function drawScore() {
    ctx.font = "16px Arial";
    ctx.fillStyle = "#0095DD";
    ctx.fillText("Score: "+score, 8, 20);
}

Drawing text on a canvas is similar to drawing a shape. The font definition looks exactly like the one in CSS — we can set the size and font type in the font() method. Then we use fillStyle() to set the color of the font and fillText() to set the actual text that will be placed on the canvas, and where it will be placed. The first parameter is the text itself — here we are showing the current number of points — and the last two parameters are the coordinates where the text will be placed on the canvas.

To actually award a score each time a brick is hit, we need to add a line to the collisionDetection() function to increment the value of the score variable each time a collision is detected. Add the following highlighted line to your code:

function collisionDetection() {
    for(c=0; c<brickColumnCount; c++) {
        for(r=0; r<brickRowCount; r++) {
            var b = bricks[c][r];
            if(b.status == 1) {
                if(x > b.x && x < b.x+brickWidth && y > b.y && y < b.y+brickHeight) {
                    dy = -dy;
                    b.status = 0;
                    score++;
                }
            }
        }
    }
}

Calling drawScore() from our draw() function keeps the score up to date with every new frame — add the following line inside draw(), just below the drawPaddle() call:

drawScore();

Displaying a winning message when all bricks have been destroyed

Collecting the points works well, but we won't be adding them forever — what about when all the bricks have been destroyed?. It's the main purpose of the game after all, so we should display a winning message if all available points have been collected. Add the following highlighted section into your collisionDetection() function:

function collisionDetection() {
    for(c=0; c<brickColumnCount; c++) {
        for(r=0; r<brickRowCount; r++) {
            var b = bricks[c][r];
            if(b.status == 1) {
                if(x > b.x && x < b.x+brickWidth && y > b.y && y < b.y+brickHeight) {
                    dy = -dy;
                    b.status = 0;
                    score++;
                    if(score == brickRowCount*brickColumnCount) {
                        alert("YOU WIN, CONGRATULATIONS!");
                        document.location.reload();
                    }
                }
            }
        }
    }
}

Thanks to this we'll be able to actually win the game when we destroy all the bricks, which is quite important when it comes to games. The document.location.reload() function will then reload the page and start the game again once the alert button is clicked.

Compare your code

The latest code looks (and works) like this, for those who want to compare and contrast:

Exercise: add more points per brick hit, print out the number of collected points in the end game alert box.

Next steps

The game is looking pretty good at this point — in the next lesson we will widen the game's appeal by adding Mouse controls.