Playing with HTML5

In the last weeks I have been playing with HTML5 in a very literal way, merging two of my interests: web development and video games. The result is a small arcade game which makes use of several features from the new web standard.

You can take a look at the code on GitHub at any time and even play it online here. Let me comment on some of the implementation details below:

The game loop

The game loop is implemented using the function setInterval() from the standard JS libraries. In particular, a callback is invoked 30 times per second: it checks the state of the game entities, updates them and then redraws the scene. This was the best option given that I’m not using any development framework.

Canvas

The game area is contained in a canvas. The canvas has been around long before HTML5 took shape, but it has received quite a lot of love recently in the form of acceleration. The game code is not specially designed for performance (after all, it was mostly developed in a week), and the scene is being completely redrawn 30 times per second. Nonetheless, I could try it in a first-generation Atom laptop with no noticeable lag.

Bitmaps

The canvas element has primitive operations to draw vector graphics (lines, bezier curves, text…) but 99% of the scene has been implemented using bitmaps, piled in several layers. This way of working is really similar to using a low-level graphic abstraction like SDL in the end.

What’s more, the bitmaps are sent to the browser packed in sheets that contain several sprites. It is a common technique in web development to save bandwidth and to overcome the limit in the number of simultaneous requests that browsers can send, but its use in video games dates from longer ago, when programmers had to deal with memory limitations.

Input

The game is controlled with the keyboard, and I use callbacks for standard key events (keyupkeydown) to check its state. These events act asynchronously and independently from the game loop, so the state of the keys is stored in an object which is checked in the update entities phase of the loop.

It also has to be taken into account that the key event callbacks are set on the canvas object, as a consequence events are lost if the focus moves out of the canvas. I have found some weird interactions when the focus changes while keys are pressed, so this part of the code definitely needs some work yet to become more robust.

Sound

I’ve used the web audio API to be able to manipulate sound with a high level of detail. Though I haven’t used most of its capabilities by far, it was worth connecting all the wires to make it work.

This API is designed as an audio flow going through several nodes, similarly to other popular multimedia frameworks. Each node has the ability to process the input in some way before sending it to the next node. I used only one intermediate node, the GainNode, to be able to mute the audio output at will, but it could have been used to implement an internal volume control.

Wishlist

A project is never complete with a list of things one would like to add, complete or polish. I’ve already mentioned some details worth revisiting, but there are also some features that I would have liked to use; examples are local storage to implement high score boards or network code to implement some sort of interaction between players. But in the end of the day, this has been a worthwhile exercise; I’m satisfied with the result and  I might still improve it in the future!