Prerequisites

Setting up the background

The background is only an alibi to use a canvas. It will allow us to draw pixels in a given area. So we will use it to draw a space wormhole (yes, I love Stargate!). Users will have choice to display it or not using the mode button:

You can note that we will add a performance counter in the right top corner (just to see the power of accelerated graphics)

Setting up HTML5 page

Starting from the index.htm file, we will add our canvas as child of the div “gameZone”:

Computing FPS

We can compute FPS by measuring the amount of time between two calls to a given function. In our case, the function will be computeFPS. It will save the last 60 measures and will compute an average to produce the desired result:

// FPS

var previous = [];

function computeFPS() {

if (previous.length > 60) {

previous.splice(0, 1);

}

var start = (new Date).getTime();

previous.push(start);

var sum = 0;

for (var id = 0; id < previous.length - 1; id++) {

sum += previous[id + 1] - previous[id];

}

var diff = 1000.0 / (sum / previous.length);

stats.innerHTML = diff.toFixed() + " fps";

}

Drawing and animations

The canvas is a direct mode tool. This means that we have to reproduce all the content of the canvas every time we need to change something.

And first of all, we need to clear the content before each frame. The better solution to do that is to use clearRect:

// Drawing & Animation

function clearCanvas() {

context.clearRect(0, 0, canvas.width, canvas.height);

}

So the full wormhole drawing code will look like:

function wormHole() {

computeFPS();

canvas.width = window.innerWidth;

canvas.height = window.innerHeight - 130 - 40;

clearCanvas();

for (var index = 0; index < circlesCount; index++) {

circles[index].draw();

}

circles.sort(function (a, b) {

if (a.depth > b.depth)

return -1;

if (a.depth < b.depth)

return 1;

return 0;

});

}

The sort code is used to prevent circles from overlapping.

Setting up mode button

To finalize our background, we just need to hook up the mode button to display or hide the background:

var wormHoleIntervalID = -1;

function startWormHole() {

if (wormHoleIntervalID > -1)

clearInterval(wormHoleIntervalID);

wormHoleIntervalID = setInterval(wormHole, 16);

document.getElementById("wormHole").onclick = stopWormHole;

document.getElementById("wormHole").innerHTML = "Standard Mode";

}

function stopWormHole() {

if (wormHoleIntervalID > -1)

clearInterval(wormHoleIntervalID);

clearCanvas();

document.getElementById("wormHole").onclick = startWormHole;

document.getElementById("wormHole").innerHTML = "Wormhole Mode";

}

stopWormHole();

Setting up the game

In order to simplify a bit the tutorial, the mouse handling code is already done. You can find all you need in the mouse.js file.

Adding the game JavaScript file

The background is handled by game.js file. So we have to register it inside index.htm. So right before the body closing tag, we will add the following code:

<scripttype="text/javascript"src="game.js"></script>

Updating HTML5 page

The game will use SVG (Scalable Vector Graphics) to display the bricks, pad and ball. The SVG is a retained mode tool. So you don’t need to redraw all every time you want to move or change an item.

To add a SVG tag in our page, we just have to insert the following code (just after the canvas):

<svgid="svgRoot">

<circlecx="100"cy="100"r="10"id="ball"/>

<rectid="pad"height="15px"width="150px"x="200"y="200"rx="10"ry="20"/>

</svg>

As you can note, the SVG starts with two already defined objects : a circle for the ball and a rectangle for the pad.

Defining constants and variables

In game.js file, we will start by adding some variables:

// Getting elements

var pad = document.getElementById("pad");

var ball = document.getElementById("ball");

var svg = document.getElementById("svgRoot");

var message = document.getElementById("message");

The ball will be defined by:

A position

A radius

A speed

A direction

Its previous position

// Ball

var ballRadius = ball.r.baseVal.value;

var ballX;

var ballY;

var previousBallPosition = { x: 0, y: 0 };

var ballDirectionX;

var ballDirectionY;

var ballSpeed = 10;

The pad will be defined by:

Width

Height

Position

Speed

Inertia value (just to make things smoother )

// Pad

var padWidth = pad.width.baseVal.value;

var padHeight = pad.height.baseVal.value;

var padX;

var padY;

var padSpeed = 0;

var inertia = 0.80;

Bricks will be saved in an array and will be defined by:

Width

Height

Margin between them

Lines count

Columns count

We also need an offset and a variable for counting destroyed bricks.

// Bricks

var bricks = [];

var destroyedBricksCount;

var brickWidth = 50;

var brickHeight = 20;

var bricksRows = 5;

var bricksCols = 20;

var bricksMargin = 15;

var bricksTop = 20;

And finally we also need the limits of the playground and a start date to compute session duration.

// Misc.

var minX = ballRadius;

var minY = ballRadius;

var maxX;

var maxY;

var startDate;

Handling a brick

To create a brick, we will need a function that will add a new element to the svg root. It will also configure each brick with required information:

collideWithWindow checks the limits of the playground and collideWithPad checks the limits of the pad (We add a subtle change here: the horizontal speed of the ball will be computed using the distance with the center of the pad).

Moving the pad

You can control the pad with the mouse or with the left and right arrows. The movePad function is responsible for handling pad movement. It will also handle the inertia: