How to Build a Multi-State Animation in Your HTML5 Game

By Andy Harris

With all this motion going on in your HTML5 game, you’re sure to want multiple sophisticated animations. You can use the changeImage() or setImage() function (they’re two different names for the same thing) to change the image associated with a sprite any time. Sometimes, though, you want much more sophisticated animations. Take a look at walkAnim.html.

image0.jpg

There’s a whole lot of image-swapping going on here. The walking animation is actually a series of eight different images rapidly swapped to give the illusion of walking. There are 4 different animations (one for each of the cardinal directions), so that’s a total of 32 different images. However, if you look over the code, you’ll see that the character sprite contains only one image.

image1.jpg

This image is a composite animation. Each row represents a direction, and each row contains a cycle, or a series of images, meant to be repeated.

The rpg_sprite_walk.png image was created by Franck Dupont. He generously posted this image on the OpenGameArt.org site, where he is known as “Arikel.” He released his work under a special license called “Attribution — Share Alike.” This means people can use or remix his work for free, as long as they attribute the original author.

The background image is by an author named Hyptosis, who released images under the public domain on the same site. Talented and thoughtful contributors like Franck and Hyptosis are the key to the thriving creative community. Feel free to look over the open game art site for more great artwork to use in your games, but be sure to thank and attribute the authors as they deserve.

The simpleGame.js library contains a feature for making multi-image animations quite easily. Look over the code for walkAnim.html to see how it works:

<!DOCTYPE HTML>
<html lang="en-US">
<head>
 <meta charset="UTF-8">
 <title>walkAnim.html</title>
 <script type = "text/javascript"
   src = "simpleGame.js"></script>
 <script type = "text/javascript">
  var game;
  var background;
  var character;
  function init(){
   game = new Scene();
   background = new Sprite(game, "rpgMap.png", 800, 600);
   background.setSpeed(0,0);
   background.setPosition(400, 300);
   character = new Sprite(game, "rpg_sprite_walk.png", 192, 128);
   character.loadAnimation(192, 128, 24, 32);
   character.generateAnimationCycles();
   character.renameCycles(new Array("down", "up", "left", "right"));
   character.setAnimationSpeed(500);
   //start paused
   character.setPosition(440, 380);
   character.setSpeed(0);
   character.pauseAnimation();
   character.setCurrentCycle("down");
   game.start();
  } // end init
  function update(){
   game.clear();
   checkKeys();
   background.update();
   character.update();
  } // end update
  function checkKeys(){
   if (keysDown[K_LEFT]){
    character.setSpeed(1);
    character.playAnimation()
    character.setMoveAngle(270);
    character.setCurrentCycle("left");
   }
   if (keysDown[K_RIGHT]){
    character.setSpeed(1);
    character.playAnimation()
    character.setMoveAngle(90);
    character.setCurrentCycle("right");
   }   
   if (keysDown[K_UP]){
    character.setSpeed(1);
    character.playAnimation()
    character.setMoveAngle(0);
    character.setCurrentCycle("up");
   }   
   if (keysDown[K_DOWN]){
    character.setSpeed(1);
    character.playAnimation()
    character.setMoveAngle(180);
    character.setCurrentCycle("down");
   }   
   if (keysDown[K_SPACE]){
    character.setSpeed(0);
    character.pauseAnimation();
    character.setCurrentCycle("down");
   }
}
 </script>
</head>
<body onload = "init()">
</body>
</html>

You need to take a few new steps to build an animation, but the results are completely worth the effort.

  1. Obtain an animation image.

    You can either create an image yourself, or look at the excellent resources like OpenGameArt.org to find work that others have done. Of course, you have a responsibility to respect other’s work, but there is some great work available in very permissive licenses today. Be sure the image is organized in rows and columns and that each sub-image is exactly the same size.

    You may have to mess with your image editor to ensure that the image is in the right format and that you know the size of each sub-image.

  2. Attach the animation image to your sprite.

    You’ll be attaching the entire image to your sprite, but just displaying a small part of it at any one time. This is easier than working with a bunch of images, and it’s also more efficient.

  3. Create an animation object with the loadAnimation() method.

    When you invoke the loadAnimation() method of an object, you’re creating an animation tool that helps manage the animation. The first two parameters are the size of the entire image (width and height), and the second two parameters are the width and height of each sub-image. If you get these values wrong, the animation will appear to scroll. Keep playing until you get these values right:

    character.loadAnimation(192, 128, 24, 32);
  4. Build the animation cycles.

    Each row will be turned into an animation cycle. The default version (without any parameters) works fine in most situations. Look up the documentation for the more advanced usages of this tool:

    character.generateAnimationCycles();
  5. Rename the cycles.

    The animations created with the buildAnimationCycles() command have default names, but it’s almost always better to attach your own, more meaningful names. Add an array with a name indicating what each row represents:

    character.renameCycles(new Array("down", "up", "left", "right"));
  6. Set the animation speed.

    The animation speed indicates how fast the animation will run. A value of 500 seems right for most applications, but you can adjust this value so the character’s walk cycle looks like it’s actually propelling the character:

    character.setAnimationSpeed(500);
  7. Set which cycle you intend to display.

    The setCurrentCycle() method allows you to choose the cycle with one of the names you indicated in the renameAnimationCycles() step:

    character.setCurrentCycle("down");
  8. Use the pauseAnimation() command to pause the animation.

    The pauseAnimation() command makes the animation temporarily stop.

  9. Use playAnimation() to begin the animation.

    This method will continuously loop the current animation cycle.

As you can see, animation adds a huge amount of fun to gaming and opens up the whole realm of role-playing games to your repertoire.