Build a cross-platform HTML5 game
Ibon Tolosana and Iker Jamardo Zugaza show you how to get to grips with cross-platform HTML5 game development using Canvas
This article first appeared in issue 230 of .net magazine – the world’s best-selling magazine for web designers and developers.
You can generalise this code for N images, and your asset pre-loader will work like a charm. You can also find a complete asset pre-loader here.
This way of defining animation loops has two major drawbacks. First, if the drawing function takes too long the animation will clash and start to be queued. Second, this function consumes system resources even when the tab our game is running on is hidden, or even worse, when the browser window is minimised. A better solution would be to call requestAnimationFramework functions, like described in this article.
Now that we have images and a decent animation loop, we need some in-game interaction. Depending on the platform you focus on, you could make use of different input subsystems. While keys and mouse are the primary input system on desktop systems, touch events and accelerometers are usually constrained to mobile.
Despite the fact that modern browsers are pushing the envelope on gaming, browsers weren’t built with gaming in mind until the latest major browsers, which now support APIs such as mouse-lock, full-screen and so on.
On mobile, there won’t be a problem, since we keep our game optimised to be full screen. But on a regular browser, where a canvas can be any place in the DOM hierarchy, things can get more complicated since there’s no crossbrowser direct mechanism to get a mouse/touch event coordinate related to our canvas object. So the best practice is to keep the markup around our canvas game as simple as possible. This is our procedure in CAAT, our animation library.
Another drawback for the mouse input system is that it lacks a “mouseDrag” event, which you have to simulate yourself.
The final input code abstraction would mean identifying every input source and binding them to some reusable code, for example:
Moving actors on screen basically means to bind input events to changing on-screen position variables.
More complex operations could require complex path traversal, apply easing functions to traversal, chained animations, either by time or external events and so on. In this example, we’re binding cursor keys to move a rotating rectangle on screen.
Sound is the most important feedback feature for any game. Background music and special effects make the difference between an average game and a great game.
For us HTML5 games developers, audio API is not good news. The audio API is a little bit broken. First of all, different browsers play different audio formats so it’s good to have your audio files in as many audio formats as possible. Second, the audio tag is a bit buggy. Loops won’t work on some browsers and on almost all of them, you won’t be able to play the same sound concurrently.
Our own Audio API workaround can be found here: netm.ag/audioapi-230. We also recommend using SoundManager2. Basically, to programmatically play a sound these are the steps that could be performed:
1 Create an audio object:
2 Set the audio data:
3 Play the sound:
4 Optionally you could attach callback functions to events such as audio end and so on:
Scaling the game
When focusing on multiplatform or cross-browser HTML5 games development, one thing to pay special attention to, especially in mobile, is screen resolution fragmentation. There are so many different screen resolutions to cope with that it could be a real pain to conform all of our in-game assets to such different resolutions.
Fortunately the canvas API, or even the DOM/CSS, is flexible enough to allow us to apply affine transformations so that we can have our games up- or downscale gracefully at almost no development cost. This means that the relationship between one screen pixel and one world coordinate must not be tied to a 1:1 ratio. The only constraint for this procedure will be to have the canvas occupy the whole window area. Therefore, it’s good to set it to body style=”margin:0; padding:0;”with no markup on it. The way to go with the HTML5 canvas object is pretty straightforward:
1 Create a canvas object, or select it from the markup and set the desired size; this size will be our game space size.
2 Add a window event listener for ‘resize’ where you’ll calculate a ratio value between the current window size and our original canvas object’s size:
3 Modify the drawing routine to have a scale applied with the previous scaleFactor:
Despite what it may seem, we truly believe that HTML5 is the way to go when targeting web games development. Right now, the technology is still in its early stages, but it improves daily and powerful APIs are being added.
We would recommend anyone wanting to start with HTML5 games development to rely on any of the available gaming frameworks that are already out there. They’ll help you avoid some common HTML5 pitfalls, and supply you with different rendering technologies to target different deployment devices. We’ve developed our own gaming framework: CAAT, freely available under the MIT licence.
We’ve also made a game as a demonstration of its power that’s under 200 lines of code that you can download here. You can play a complete puzzle game with input abstraction, animations, sound and screen resolution independence.
Taking a look at other coding projects has helped us learn a lot and be able to give simple solutions to complex problems. Choose the framework that best fits your needs here.