One thing not mentioned in the article: you don't have to render everything on a single canvas, you can use multiple canvases as layers. This is specially useful to separate what is updated often with what changes rarely, for instance the characters layer, the background layer and the HUD layer can potentially have very different update rates, so it makes sense to redraw them at a different pace each. In fact, you can also get creative and combine DOM elements with canvases.
These tricks matter because redrawing the entire screen every frame is usually an expensive operation; this is not noticable on small examples but it can become an issue on larger, more complex games.
Thanks! I don't think you really need to do that on desktop devices, but that definitely helps on mobile. There's a lot of things I could have mentioned but I was focusing on beginners.
It may be worth following up this article with another one that includes techniques like this.
Do you know of any good resources that talk about using multiple canvases as layers? I have tried searching for some good examples, but I have been coming up empty.
I don't think there'd really be any trick to it -- you just have multiple canvases, and render different stuff on each one. The most trivial example would be to have a single background canvas that has stuff that'll never be redrawn.
Remember that each canvas element is still part of the DOM, so you can put one on top of another just like you could with ordinary HTML.
Just dealt with some of these issues last week in 7drl.
>image-rendering: optimizeSpeed;
In some cases, you will want to scale the images drawn to the canvas, but not the canvas itself. This causes a lot of headache because of image smoothing and is not resolved by the above CSS. The answer is to set the image smoothing property of the canvas context to false. For example:
ctx.mozImageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false;
Worked great on Chrome and Firefox. For some reason, though, this does not appear to work in Safari. I'm still amazed that something so simple is so hard to accomplish across browsers (after all you're asking to turn off extra, slower functionality). A good article on the intricacies: http://phoboslab.org/log/2012/09/drawing-pixels-is-hard
There is a pitfall with the approach of update loop using variable time steps. Depending on the game type this can matter quite a great deal. Essentially it is analogous to an iterated solution of the three body problem. 50 tiny steps produces a different result to 10 big steps.
There was a Google contraption editing game(a Google IO demo?) that suffered from this approach quite badly. It was a set-up-and-go game which should perform deterministically, but was influenced by variations in frame-rate.
The easiest approach to fixing this is simply quantised time.
var now = Date.now();
while(gameAge < now) {
update();
gameAge+=stepDuration;
}
render();
//with usual caveats of resyncing if now-gameAge is too large
The much harder (but possibly ideal) approach is to not even have such a time step at all and move in variable increments calculated at the point of interaction between entities. An example of this would be a snooker simulation which moves in steps when the balls make contact. Balls slowing, rolling and curving become calculus problems. Produces a very nice result but your brain explodes.
This is a great article, but if you're really going to make a canvas game then you're much better off using a game engine. I recommend MelonJS[1] or Impact[2] if you don't mind the cost. I also have a side project that compares JavaScript game engines in much the same way TodoMVC compares MV* frameworks: http://city41.github.com/breakouts
Hmm, you seem to have missed that Crafty can do scaling/rotating/moving/fading animations through the "Tween" component. (I'm not actually sure what "Sequencing" is in that context.)
wow, I did miss that. So has many other people who have looked at it, including the original creator of Crafty :) Not sure how that happened, but thanks for the heads up.
Much more useful than the Udacity HTML5 games class, which bizarrely dives into the bookkeeping minutia of looking up sprites in a collection of spritesheets for an entire unit (edit: unit of the class, I mean)
That should eliminate branching and make the interpreter much happier.
Additionally, by making the speed/velocity a member of the bullet instance, you can do things like have bullets that slow down or speed up if they have a think method or something, or that do homing (for this, look up dot-products and cross-products for steering).
Thanks this is a good article. I've been looking at HTML5 for game development recently for 1GAM [1]. One of the things that has really annoyed me is there does not seem to be any kind of standard way of structuring games. Is there anything like MVC for games?
I haven't followed html5 development too closely, but audio support in current browsers hasn't been uniform. I'm guessing the lack of one size fits all for audio in browsers is why.
"Fieldrunners is an award-winning tower-defense style game that was originally released for iPhone in 2008. Since then it has been ported to many other platforms. One of the most recent platforms was the Chrome browser in October 2011. One of the challenges of porting Fieldrunners to an HTML5 platform was how to play sound."
I discussed it briefly near the end of the article under "Adding Sounds". The main reason this article doesn't do it is because it's focusing on rendering with canvas, and there's already a lot of information for beginners to go through there.
I plan on writing a followup to include sound, though, or possible extending this article.
What the other comments say is true, also. It's not extremely straightforward. The state of APIs on the web is very mixed, but I think in a year or so the Web Audio API will in most places.
Canvas doesn't have any kind of support for playing music, but there is a (flash) based sound manager that works everywhere and Chrome has some facility for playing sound too.
However making music is an art not all programmers have mastered, so most would likely skip that step.
I disagree, it's not the best, but it's decent enough for most games. Most HTML5 game engines use the audio tag. My game uses a good amount of sound effects and background music just fine with the audio tag: http://cityfortyone-mattgreer.dotcloud.com/dragonPlunder/
These tricks matter because redrawing the entire screen every frame is usually an expensive operation; this is not noticable on small examples but it can become an issue on larger, more complex games.
Great article otherwise.