# Animated Sprites

To animate a sprite, we simply swap the image it is using. Animated sprites typically lay out all their frames in a single texture, just like a texture atlas. Consider this animated bat sprite by bagzie from OpenGameArt:

The images of the bat are laid out into a 4x4 grid of 32x32 pixel tiles. We can create the illusion of motion by swapping which of these images we display. However, we don’t want to swap it every frame - doing so will be too quick for the viewer to follow, and destroy the illusion. So we also need a timer and an idea of the direction the sprite is facing.

To represent the direction, we might define an enum. And since the enum can represent a numerical value, let’s assign the corresponding row index to each direction:

/// <summary>
/// The directions a sprite can face
/// </summary>
public enum Direction {
Down = 0,
Right = 1,
Up = 2,
Left = 3
}


With this extra state to track, it makes sense to create a class to represent our sprite:

/// <summary>
/// A class representing a bat
// </summary>
public class BatSprite
{
// The animated bat texture
private Texture2D texture;

// A timer variable for sprite animation
private double directionTimer;

// A timer variable for sprite animation
private double animationTimer;

// The current animation frame
private short animationFrame;

///<summary>
/// The bat's position in the world
///</summary>
public Vector2 Position { get; set; }

///<summary>
/// The bat's direction
/// </summary>
public Direction Direction { get; set; }
}


We’ll need a LoadContent() method to load our texture:

/// <summary>
/// Loads the bat sprite texture
/// </summary>
/// <param name="content">The ContentManager</param>
{
}


Let’s make our bat fly in a regular pattern, switching directions every two seconds. To do this, we would want to give our bat an Update() method that updates a timer to determine when it is time to switch:

public void Update(GameTime gameTime)
{
directionTimer += gameTime.ElapsedGameTime.TotalSeconds;

// every two seconds, change direction
if(directionTimer > 2.0)
{
switch(Direction)
{
case Direction.Up:
Direction = Direction.Down;
break;
case Direction.Down:
Direction = Direction.Left;
break;
case Direction.Left:
Direction = Direction.Right;
break;
case Direction.Right:
Direction = Direction.Up;
break;
}
// roll back timer
directionTimer -= 2.0;
}

// move bat in desired direction
switch (Direction)
{
case Direction.Up:
Position += new Vector2(0, -1) * 100 * (float)gameTime.ElapsedGameTime.TotalSeconds;
break;
case Direction.Down:
Position += new Vector2(0, 1) * 100 * (float)gameTime.ElapsedGameTime.TotalSeconds;
break;
case Direction.Left:
Position += new Vector2(-1, 0) * 100 * (float)gameTime.ElapsedGameTime.TotalSeconds;
break;
case Direction.Right:
Position += new Vector2(1, 0) * 100 * (float)gameTime.ElapsedGameTime.TotalSeconds;
break;
}
}


We’ll use a similar technique to advance the animation frame - once every 16th of a second, in the Draw() method:

public void Draw(GameTime gameTime, SpriteBatch spriteBatch) {
animationTimer += gameTime.ElapsedGameTime.TotalSeconds;

// Every 1/16th of a second, advance the animation frame
if(animationTimer > 1/16)
{
animationFrame++;
if(animationFrame > 3) animationFrame = 0;
animationTimer -= 1/16;
}

// Determine the source rectangle
var sourceRect = new Rectangle(animationFrame * 32, (int)Direction * 32, 32, 32);

// Draw the bat using the current animation frame
spriteBatch.Draw(texture, Position, sourceRect, Color.White);
}


Notice because our Direction enum uses integer values, we can cast it to be an int and use it to calculate the sourceRect’s x-coordinate.

We can then construct a bat (or multiple bats) in our game, and invoke their LoadContent(), Update(), and Draw() methods in the appropriate places.