How to write a BrikBloc game with HTML5 SVG and Canvas
by David Catuhe
Starter and full solution can be found here.
The goal of this tutorial is discovering graphics development using SVG and Canvas (which are two majors technologies of HTML5).
To do so, we will write together a brick breaker game (à la Arkanoïd or Blockout). It will be composed of an animated background (using Canvas) and will use SVG for bricks, pad and ball.
You can try the final version here: http://www.catuhe.com/ms/en/index.htm
Visual Studio 2010 SP1
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 Description: Sourire)
Setting up HTML5 page
Starting from the index.htm file, we will add our canvas as child of the div “gameZone”:
The background is handled by background.js file (what a surprise!). So we have to register it inside index.htm. So just before the body closing tag, we will add the following code:
Setting up constants
First of all, we need constants to drive the rendering:
You can of course modify these constants if you want different effects on your wormhole.
We also need to keep reference to main elements of the html page:
How to display a circle?
The wormhole is only a sequence of circles with different positions and sizes. So to draw it, we will use a circle function which is build around a depth, an angle and an intensity (the base color).
The angle and the intensity are private but the depth is public to allow the wormhole to change it.
We also need a public draw function to draw the circle and update depth, angle. So we need to define where to display the circle. To do so, two variables (x and y) are defined:
As x and y are in space coordinates, we need to project them into the screen:
So final position of the circle is computed by the following code:
And using this position, we can simply draw our circle:
You can note that the circle is more opaque when it is closer.
With our circle function, we can have an array of circles that we will initiate more and more close to us with a slight shift of the angle each time:
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:
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:
So the full wormhole drawing code will look like:
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:
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.
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:
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):
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:
The ball will be defined by:
The pad will be defined by:
Bricks will be saved in an array and will be defined by:
We also need an offset and a variable for counting destroyed bricks.
And finally we also need the limits of the playground and a start date to compute session duration.
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:
The brick function will also provide a drawAndCollide function to display a brick and to check if there is a collision with the ball:
Finally the full brick function will look like:
Collisions with the pad and the playground
The ball will also have collision functions that will handle collisions with the pad and the playground. These functions will have to update the ball direction when a collision will be detected.
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:
The code responsible for handling inputs is pretty simple:
Before setting up the game loop we need a function to define the playground size. This function will be called when window is resized.
By the way, the game loop is the orchestrator here:
Initialization and victory
The first step of initialization is creating bricks:
The next step is about setting variables used by the game:
Every time the user will change the window size, we will have to reset the game:
Then we have to attach an event handler to the new game button:
Finally, we will add two functions for handling start and end of the game:
You are now a game developer! Using the power of accelerated graphics, we have developed a small game but with really interesting special effects!
It’s now up to you to update the game to make it the next blockbuster!
To go further
About the Author
David Catuhe is a developer evangelist for Microsoft France in charge of user experience development tools (from XAML to DirectX/XNA and HTML5). He defines himself as a geek and likes coding all that refer to graphics. Before working for Microsoft, he founded a company that developed a realtime 3D engine written with DirectX (www.vertice.fr)."