Notes on software development

JavaScript Canvas Sprite Animation

Sprite sheets have been used in game development for many years. In web development it allows you to reduce:

  • a number of HTTP requests for downloading many separate images,
  • webserver load as a result of fewer requests,
  • download time as a combined sprite sheet is smaller than the individual files.

I want to share the approach that I used in my games written with canvas and javascript. I think this is a reusable approach for animating different objects on a canvas.

To demonstrate it, I compiled a Sonic sprite sheet from the "Sonic the Hedgehog 3" game.

It consists of three rows of sprites, responsible for a specific set of actions: idle (9 frames), walk (8 frames), and run (4 frames). And in my case, each frame has the same height and width.

Sonic spritesheet

We will use JavaScript classes, introduced in ECMAScript 2015, which is actually just syntactical sugar.

Let's create a base Sprite class from which our objects will be inherited, which we need to animate.

We declared a constructor() and created two methods - update() and render().

To get started, let's deal with the constructor(). At the input, it accepts parameters, among which deserves attention:

  • frames - Number of frames in a row
  • frameIndex - Index of the current frame
  • row - Row number
  • ticksPerFrame - Determine how long to stay on this frame. This way we control the speed of the animation.
  • tickCount - How long we've already shown this frame.

When we call the update() method, we increment the tickCount counter and compare it with the ticksPerFrame that we specified in the constructor. If enough time has passed and there are still frames, then go to the next frame. Otherwise, switch to the first frame.

The render() method is responsible for drawing an object on canvas using the drawImage() method.

Now let's create a Sonic class that inherits our base Sprite class. At the input, it takes the coordinates where to draw our hero, the context, and a set of constant parameters for this class, which override the parameters of the parent class.

This class has three additional methods walk(), run(), and idle(). Inside them, we redefine the type and frame rate, thereby changing the appearance and speed of the animation.

Let's create another Coin class to show how easily we can now animate our objects, inheriting from the base class.

Finally, create the index.html file in which we initialize our classes and create the base object of the game. 

We've also added an image loader. This allows all image objects to be initialized in one place and only once, which saves processor resources.

Here the init() method responsible for initially creating the canvas, Sonic and coin objects, and running drawingLoop(), in which we repeat the following steps:

  1. Clear a canvas.

  2. Draw (render) all objects.

  3. Update state.

You can see the result below. Also, all the code is available on the GitHub.

Hope this was helpful. If you have any questions, please leave a comment.