HTML5 Gaming: How to animate sprites in Canvas with EaselJS
By David Rousset
I’ve decided to use EaselJS which was used to write PiratesLoveDaisies, a great HTML5 Tower Defense game. We’re going to see in this tutorial how to use your existing sprite elements and animate them.
If you follow my blog, you know I love playing with this sample. I’ve used it in two previous articles:
The platformer sample has been updated by the XNA team and is available for Xbox 360, PC & Windows Phone 7: App Hub – platformer. Download it to play around with it, then extract the sprites to use with EaselJS.
I’m going to use 2 PNG files as source of sprite sequences.
A running monster, which contains 10 different sprites.
Our monster in idle mode, containing 11 different sprites:
Note: These samples don’t work properly in Firefox 5.0, apparently due to a bug in their canvas implementation. It has been tested ok in IE9, IE10, Chrome 12, Opera 11 and Firefox Aurora 7.0.
Tutorial 1: Building the SpriteSheet and the BitmapSequence
We’ll start by running the monster from one end of the canvas to the other.
The first step is to load the complete sequence contained in the PNG file with this code:
This code will be called first to initialize our game’s content. Once loaded, you can start the game.
EaselJS exposes a SpriteSheet object to handle the sprite. Thus, by using this code:
...I’m indicating that I’d like to create a new sequence named “walk_left” that will be made of the imgMonsterARun image. This image will be split into 10 frames with a size of 64x64 pixels. This is the core object to load our sprite and create our sequences. There could be several sequences created from the same PNG file if you want, like in the rats sprite sample on the EaselJS site.
After that, you’ll need to use the BitmapSequence object. It helps animate the sequence and position the sprites on screen.
Let’s review the initializing code of this BitmapSequence:
The constructor of the BitmapSequence object simply needs the SpriteSheet element as a parameter. We’re then giving a name to the sequence, setting some parameters like the speed and the initial position of our first frame. Finally, we add this sequence to the display list by using the Stage object and its addChild() method.
Next, you need to decide what you’d like to do in the animation loop. This animation loop is called every xxx milliseconds and lets you update the position of your sprites. For that, EaselJS exposes a Ticker object that provides a centralized tick or heartbeat broadcast at a set interval.
All you have to do is subscribe to the tick event and implement a .tick() method that will be called back.
This code is for instance registering the event:
And here is the code that will be called every 17ms (when possible) to update the position of our monster:
You can test the final result here: easelJSSpritesTutorial01 to view the complete source code.
But wait! There are 2 problems in this animation!
Let’s fix it.
Tutorial 2: Controlling the animation speed and flipping the sprites
The simplest way I’ve found to fix the animation’s speed is by using a modulus operator to avoid drawing/updating my sequence during each tick.
There’s currently an open issue about this on EaselJS 0.3.2.
To make the character walk normally from left to right, we just need to flip each frame.
EaselJS exposes a SpriteSheetUtils object for that and a flip() method.
You’re essentially making a derivative sequence named “walk_right” based on the “walk_left” sequence that’s flipped horizontally.
Finally, here is the code that slows down the speed animation and handles which sequence to play based on the character position:
You can test the final result here: easelJSSpritesTutorial02
Tutorial 3: Loading multiple sprites and playing with multiple animations
It’s time to load the idle state of the monster.
The idea here is to make the monster travel a single round-trip, then play the idle state.
We’ll have to load multiple PNG files from the web server. It’s very important to wait until all resources are loaded, otherwise you might try to draw non-yet downloaded resources.
Here’s a simple way to do it:
This code is very simple. For instance, it doesn’t handle the errors properly by trying to re-download the image in case of a first failure.
When you’re building a game, you will need to write your own content download manager if the JS library you’re using doesn’t implement it.
To add the idle sequence and set the position parameters, you just need the same kind of code previously seen:
Now, in the tick() method, we need to stop the walking animation once we’ve reached the left side of the screen, and play the idle animation instead.
Here is the code to stop your monster:
You can test the final result here: easelJSSpritesTutorial03.
That’s all folks! If you’re ready for more, check out HTML5 Gaming: building the core objects & handling collisions with EaselJS.
About the Author