Professional Documents
Culture Documents
When you want to write casual games using the HTML5 Canvas element, you’ll need to find a way to handle your
sprites. There are several libraries available to help you writing games such as ImpactJS, CraftyJS and so on. On my
side, I’ve decided to use EaselJS which has been used to write PiratesLoveDaisies: an HTML5 Tower Defense game
as well as for the very cool Atari Arcade suite. This awesome library works in all modern HTML5 browsers and could
even help you building a Windows 8 HTML5 games. For instance, if you’re running the Windows 8, you can install
the Pirates Love Daisies game from the Windows Store here: Pirates Love Daisies for Windows 8
In this first article, we’re going to see how to use your existing sprite elements and animate them.
This article is the first of a series of 3 that will guide you to build a complete platformer game from scratch:
I’ve also written 3 others articles going further with the same game & assets:
- Tutorial: how to create HTML5 applications on Windows Phone thanks to PhoneGap where I’ll show you how to
migrate the game to PhoneGap
- Modernizing your HTML5 Canvas games Part 1: hardware scaling & CSS3 where we’ll use CSS3 3D Transform,
Transitions & Grid Layout
- Modernizing your HTML5 Canvas games Part 2: Offline API, Drag’n’drop & File API where we will enable playing to
the game in offline mode
By reading all of them, you will know how to build a HTML5 game that will work under all modern browsers (IE9/10,
Firefox, Chrome, Safari, Opera) and all modern mobile platforms (iPad/iPhone, Android/Firefox OS & Windows
8/Windows Phone 8)!
You can play to the final result (article 6/6) in your favorite browser here: Modern HTML5 Platformer
Ready to learn how to build the same kind of game from scratch? Let’s go then!
Introduction
On the official EaselJS site, you’ll find some interesting samples and some basic documentation. We will use the
sprites sample as a base. We will use also the resources available in the XNA 4.0 Platformer sample. For those of
you who are following my blog, you may remember that I love playing with this sample. The platformer sample have
been updated in the meantime by our XNA team and is available here for Xbox 360, PC & Windows Phone 7: App
Hub – platformer . You can download it to play with it and extract the sprites to use them with EaselJS.
In this article, we’re going to use these 2 PNG files as source of our sprite sequences:
Note: The following samples have been tested successfully in IE9/IE10/Chrome, Firefox, Opera 12 & Safari.
First step is to load the complete sequence contained in the PNG file via this code:
function init() {
//find canvas and load images, wait for last image to load
blogs.msdn.com/b/davrous/archive/2011/07/21/html5-gaming-animating-sprites-in-canvas-with-easeljs.aspx 1/7
03/04/13 HTML5 Gaming: animating sprites in Canvas with EaselJS - David Rousset - Site Home - MSDN Blogs
canvas = document.getElementById("testCanvas");
imgMonsterARun.onload = handleImageLoad;
imgMonsterARun.onerror = handleImageError;
imgMonsterARun.src = "img/MonsterARun.png";
}
This code will be called first to initialize our game’s content. Once loaded, we can start the game. EaselJS expose a
SpriteSheet object to handle the sprite. Thus, by using this code:
We’re indicating that we’d like to create a new sequence named “walk” 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 sprites
and create our sequences. There could be several sequences created from the same PNG file if you want to, like in
the rats sprite sample of the EaselJS site.
After that, we need to use the BitmapAnimation object. It helps us animating our sequence and positioning our
sprites on the screen. Let’s review the initializing code of this BitmapAnimation:
// create a BitmapAnimation instance to display and play back the sprite sheet:
bmpAnimation = new createjs.BitmapAnimation(spriteSheet);
// set up a shadow. Note that shadows are ridiculously expensive. You could display hundreds
// of animated rats if you disabled the shadow.
bmpAnimation.shadow = new createjs.Shadow("#454", 0, 5, 4);
bmpAnimation.name = "monster1";
bmpAnimation.direction = 90;
bmpAnimation.vX = 4;
bmpAnimation.x = 16;
bmpAnimation.y = 32;
The constructor of the BitmapAnimation 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 step is now to decide what we’d like to do in our animation loop. This animation loop is called every xxx
milliseconds and let you update the position of your sprites. For that, EaselJS exposes a Ticker object which
provides a centralized tick or heartbeat broadcast at a set interval. If you’re looking to the Ticker.js source code,
you’ll see that since 0.4, the Ticker object of EaselJS supports requestAnimationFrame() :
Thanks to this code, IE10, Firefox, Chrome and future versions of Opera are supported already. But it’s not used by
default by EaselJS. Probably for compatibility reasons I guess.
You can request to use it (for possible more efficient animations) via the boolean property useRAF set to true.
Don’t worry, if your browser doesn’t support it, the code will automatically falls back to the setTimeout() method.
Ok, all you’ve got to do now is to subscribe to the tick event and implement a .tick() method that will be called back.
This code is for instance registering the event on the global window object:
createjs.Ticker.addListener(window);
createjs.Ticker.useRAF = true;
// Best Framerate targeted (60 FPS)
createjs.Ticker.setFPS(60);
And here is the code that will be called every 17ms (in an ideal world) to update the position of our monster:
function tick() {
// Hit testing the screen width, otherwise our sprite would disappear
if (bmpAnimation.x >= screen_width - 16) {
// We've reached the right side of our screen
// We need to walk left now to go back to our initial position
bmpAnimation.direction = -90;
}
blogs.msdn.com/b/davrous/archive/2011/07/21/html5-gaming-animating-sprites-in-canvas-with-easeljs.aspx 2/7
03/04/13 HTML5 Gaming: animating sprites in Canvas with EaselJS - David Rousset - Site Home - MSDN Blogs
Start Reset
You can also browse this sample here: easelJSSpritesTutorial01 if you’d like to view the complete source code.
1 – the animation steps are weird as the character seems to loop through its different sprites sequence too fast
2 – the character can only walk normally from right to left otherwise it looks like it tries to achieve a kind of
Moonwalk dance.
You’ll need also to slow down the velocity by changing the vX from 4 to 1 (logically divided by 4).
To add new animation frames to let the character walking normally from left to right, we need to flip each frame.
EaselJS exposes a SpriteSheetUtils object for that and a addFlippedFrames() method you’ll find in the source. Here is
my code that uses that:
We’re creating a derivative sequence that will be named “walk_h” based on the “walk” sequence that we’re flipping
horizontally. At last, here is the code that handles which sequence we should play based on the character position:
function tick() {
// Hit testing the screen width, otherwise our sprite would disappear
if (bmpAnimation.x >= screen_width - 16) {
// We've reached the right side of our screen
// We need to walk left now to go back to our initial position
bmpAnimation.direction = -90;
bmpAnimation.gotoAndPlay("walk")
}
blogs.msdn.com/b/davrous/archive/2011/07/21/html5-gaming-animating-sprites-in-canvas-with-easeljs.aspx 3/7
03/04/13 HTML5 Gaming: animating sprites in Canvas with EaselJS - David Rousset - Site Home - MSDN Blogs
else {
bmpAnimation.x -= bmpAnimation.vX;
}
Start Reset
You can also browse this sample here: easelJSSpritesTutorial02 if you’d like to view the complete source code.
We will then now load multiple PNG files from the web server. It’s then very important to wait until all resources are
loaded otherwise you may try to draw non-yet downloaded resources. Here is a very simple way to do it:
var numberOfImagesLoaded = 0;
function init() {
//find canvas and load images, wait for last image to load
canvas = document.getElementById("testCanvas");
imgMonsterARun.onload = handleImageLoad;
imgMonsterARun.onerror = handleImageError;
imgMonsterARun.src = "img/MonsterARun.png";
imgMonsterAIdle.onload = handleImageLoad;
imgMonsterAIdle.onerror = handleImageError;
imgMonsterAIdle.src = "img/MonsterAIdle.png";
}
function handleImageLoad(e) {
numberOfImagesLoaded++;
// We're not starting the game until all images are loaded
// Otherwise, you may start to draw without the resource and raise
// this DOM Exception: INVALID_STATE_ERR (11) on the drawImage method
if (numberOfImagesLoaded == 2) {
numberOfImagesLoaded = 0;
startGame();
}
}
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. If 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 setting the position parameters, we just need to use the same kind of code
previously seen:
bmpAnimationIdle.name = "monsteridle1";
bmpAnimationIdle.x = 16;
bmpAnimationIdle.y = 32;
Now, in the tick() method, we need to stop the walking animation once we’ve reached back the left side of the
screen and to play the idle animation instead. Here is the code which does that:
blogs.msdn.com/b/davrous/archive/2011/07/21/html5-gaming-animating-sprites-in-canvas-with-easeljs.aspx 4/7
03/04/13 HTML5 Gaming: animating sprites in Canvas with EaselJS - David Rousset - Site Home - MSDN Blogs
if (bmpAnimation.x < 16) {
// We've reached the left side of our screen
// We need to walk right now
bmpAnimation.direction = 90;
bmpAnimation.gotoAndStop("walk");
stage.removeChild(bmpAnimation);
bmpAnimationIdle.gotoAndPlay("idle");
stage.addChild(bmpAnimationIdle);
}
Start Reset
You can also browse this sample here: easelJSSpritesTutorial03 if you’d like to view the complete source code.
That’s all folks! But if you want to go further, you can read the next part here: HTML5 Gaming: building the core
objects & handling collisions with EaselJS which is the second step you need to understand before writing a
complete platform game detailed in the third article.
David
Note : this tutorial has originally been written for EaselJS 0.3.2 in July 2010 and has been updated for EaselJS 0.6
on 04/03/2013. For those of you who read the version 0.3.2, here are the main changes for this tutorial to be aware
of:
1. BitmapSequence is not available anymore since 0.4 and has been replaced by BitmapAnimation
2. You can now slow down the animation loop of the sprites natively while building the SpriteSheet object
3. EaselJS 0.4 is now using requestAnimationFrame for more efficient animations on supported browsers (like
IE10+, Firefox 4.0+ & Chrome via the appropriate vendors’ prefixes).
4. Since EaselJS 0.4.2 and in 0.5, you need to add the createjs namespace before every EaselJS objects by
default. Otherwise, simply affect the createjs namespace to the window object.
Comments
You just need indeed the easel.js file, the 2 PNG file and re-use the code in this page for instance:
david.blob.core.windows.net/.../easelJSSpritesTutorial03.html (View Source).
Bye,
David
David
Bye
blogs.msdn.com/b/davrous/archive/2011/07/21/html5-gaming-animating-sprites-in-canvas-with-easeljs.aspx 5/7
03/04/13 HTML5 Gaming: animating sprites in Canvas with EaselJS - David Rousset - Site Home - MSDN Blogs
I've searched the web for an answer but can't find it. I know the "|" is a bitwise OR, but I don't
understand how it's used here.
Thanks
www.tapper-ware.net/blog
imgJugador.onload = handleImageLoad;
imgJugador.onerror = handleImageError;
If I try to execute this 2 lines doesn't work and if I try to use the SpriteSheetUtils.flip method I can not
execute it.
The code I'm trying to execute is www.luiniel.com/.../PruebaAnimacion.htm also It work in Chrome but
not in IE9 ¿?
Thanks
Bye,
David
Seems the new easeljs 4 has another function Bitmap Animation instead of Bitmap sequence, I tried
changing the line new BitmapSequence(spriteSheet) to new BitmapAnimation(spriteSheet) in your code,
the code runs just before the line bmpSeq.gotoAndPlay("walk_left");, and this line is not executed and
hence no animating monster. I went into Bitmap Sequence and this function is present there .... Please
through some light on this.
Thanks in Advance
blogs.msdn.com/b/davrous/archive/2011/07/21/html5-gaming-animating-sprites-in-canvas-with-easeljs.aspx 6/7
03/04/13 HTML5 Gaming: animating sprites in Canvas with EaselJS - David Rousset - Site Home - MSDN Blogs
I'm going to refactor the 3 tutorials using EaselJS 0.4. You're right, BitmapSequence has gone for
BitmapAnimation. The animation loop has changed also to use, when available, requestanimationframe.
Stay tuned for the updates.
Regards,
David
I've updated this first tutorial to match EaselJS 0.4 changes (BitmapAnimation instead of BitmapSequence
and so on).
Enjoy!
David
1 2 3
blogs.msdn.com/b/davrous/archive/2011/07/21/html5-gaming-animating-sprites-in-canvas-with-easeljs.aspx 7/7