Copyright Derek O'Reilly, Dundalk Institute of Technology (DkIT), Dundalk, Co. Louth, Ireland.
Sprite images are images that contain multiple smaller images, which can be displayed in sequence to produce an animation. An example of a sprite image is shown below:
Example of an exploding sprite animation (Run Example)
/* Author: Derek O Reilly, Dundalk Institute of Technology, Ireland. */ /* The Explosion GameObject is an animated gameObject of an explosion */ class Explosion extends GameObject { /* Each gameObject MUST have a constructor() and a render() method. */ /* If the object animates, then it must also have an updateState() method. */ constructor(explosionImage, explosionSound, centreX, centreY, size, delay = 0) { super(40, delay); /* as this class extends from GameObject, you must always call super() */ /* These variables depend on the object */ this.explosionImage = explosionImage; this.explosionSound = explosionSound; this.centreX = centreX; this.centreY = centreY; this.size = size; this.delay = delay; this.NUMBER_OF_SPRITES = 74; // the number of gameObjects in the gameObject image this.NUMBER_OF_COLUMNS_IN_SPRITE_IMAGE = 9; // the number of columns in the gameObject image this.NUMBER_OF_ROWS_IN_SPRITE_IMAGE = 9; // the number of rows in the gameObject image this.START_ROW = 0; this.START_COLUMN = 0; this.currentgameObject = 0; // the current gameObject to be displayed from the gameObject image this.row = this.START_ROW; // current row in gameObject image this.column = this.START_COLUMN; // current column in gameObject image this.SPRITE_WIDTH = (this.explosionImage.width / this.NUMBER_OF_COLUMNS_IN_SPRITE_IMAGE); this.SPRITE_HEIGHT = (this.explosionImage.height / this.NUMBER_OF_ROWS_IN_SPRITE_IMAGE); this.isFirstCallOfUpdateState = true; // used to synchronise explosion sound with start of animation } updateState() { if (this.isFirstCallOfUpdateState) { this.explosionSound.currentTime = 0; this.explosionSound.play(); this.isFirstCallOfUpdateState = false; } if (this.currentgameObject === this.NUMBER_OF_SPRITES) { this.stopAndHide(); } this.currentgameObject++; this.column++; if (this.column >= this.NUMBER_OF_COLUMNS_IN_SPRITE_IMAGE) { this.column = 0; this.row++; } } render() { ctx.drawImage(this.explosionImage, this.column * this.SPRITE_WIDTH, this.row * this.SPRITE_WIDTH, this.SPRITE_WIDTH, this.SPRITE_HEIGHT, this.centreX - parseInt(this.size / 2), this.centreY - parseInt(this.size / 2), this.size, this.size); } }
In order to animate a sprite, we need to be able step through each sub-image in turn. We initialise the sprite image based on the number of columns and rows that it contains, as shown in the code below:
this.NUMBER_OF_SPRITES = 74; // the number of gameObjects in the gameObject image this.NUMBER_OF_COLUMNS_IN_SPRITE_IMAGE = 9; // the number of columns in the gameObject image this.NUMBER_OF_ROWS_IN_SPRITE_IMAGE = 9; // the number of rows in the gameObject image this.START_ROW = 0; this.START_COLUMN = 0; this.currentgameObject = 0; // the current gameObject to be displayed from the gameObject image this.row = this.START_ROW; // current row in gameObject image this.column = this.START_COLUMN; // current column in gameObject image this.SPRITE_WIDTH = (this.explosionImage.width / this.NUMBER_OF_COLUMNS_IN_SPRITE_IMAGE); this.SPRITE_HEIGHT = (this.explosionImage.height / this.NUMBER_OF_ROWS_IN_SPRITE_IMAGE);
We step through the various sub-images in turn, as shown in red in the code below. After all of the sub-images have been displayed, we kill the Explosion object, so that it no longer displays on the canvas.
updateState()
{
if (this.isFirstCallOfUpdateState)
{
this.explosionSound.currentTime = 0;
this.explosionSound.play();
this.isFirstCallOfUpdateState = false;
}
if (this.currentgameObject === this.NUMBER_OF_SPRITES)
{
this.stopAndHide();
}
this.currentgameObject++;
this.column++;
if (this.column >= this.NUMBER_OF_COLUMNS_IN_SPRITE_IMAGE)
{
this.column = 0;
this.row++;
}
}
We can synchronise an audio clip to play with the animation, as shown in blue in the code below. The flag this.isFirstCallOfUpdateState is set as soon as the animation starts to play.
updateState()
{
if (this.isFirstCallOfUpdateState)
{
this.explosionSound.currentTime = 0;
this.explosionSound.play();
this.isFirstCallOfUpdateState = false;
}
if (this.currentgameObject === this.NUMBER_OF_SPRITES)
{
this.stopAndHide();
}
this.currentgameObject++;
this.column++;
if (this.column >= this.NUMBER_OF_COLUMNS_IN_SPRITE_IMAGE)
{
this.column = 0;
this.row++;
}
}
Write code to show three animated birds flying across a scrolling background, as shown here. The bird sprite image is:
Copyright Derek O' Reilly, Dundalk Institute of Technology (DkIT), Dundalk, Co. Louth, Ireland.