Creating Sprite Animations In MonoGame

Set Up Your Project

To animate a sprite sheet in MonoGame, you'll need to follow these steps to load the sprite sheet and then control the animation frames.

Ensure you have a MonoGame project set up and a sprite sheet added to the Content folder.
A sprite sheet is a single image that contains multiple frames of an animation laid out in a grid.

Create a SpriteAnimation Class

You can create a helper class to manage the animation of the sprite sheet:

public class SpriteAnimation
{
    public Texture2D SpriteSheet { get; private set; }
    public int FrameWidth { get; private set; }
    public int FrameHeight { get; private set; }
    public int TotalFrames { get; private set; }
    public int CurrentFrame { get; private set; }
    public int FramesPerSecond { get; private set; }

    private double timePerFrame;
    private double elapsedTime;

    public SpriteAnimation(Texture2D spriteSheet, int frameWidth, int frameHeight, int framesPerSecond)
    {
        SpriteSheet = spriteSheet;
        FrameWidth = frameWidth;
        FrameHeight = frameHeight;
        FramesPerSecond = framesPerSecond;
        TotalFrames = (spriteSheet.Width / frameWidth) * (spriteSheet.Height / frameHeight);
        CurrentFrame = 0;
        timePerFrame = 1.0 / FramesPerSecond;
        elapsedTime = 0;
    }

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

        if (elapsedTime >= timePerFrame)
        {
            CurrentFrame++;
            if (CurrentFrame >= TotalFrames)
                CurrentFrame = 0;

            elapsedTime = 0;
        }
    }

    public void Draw(SpriteBatch spriteBatch, Vector2 position)
    {
        int row = CurrentFrame / (SpriteSheet.Width / FrameWidth);
        int column = CurrentFrame % (SpriteSheet.Width / FrameWidth);

        Rectangle sourceRect = new Rectangle(column * FrameWidth, row * FrameHeight, FrameWidth, FrameHeight);
        spriteBatch.Draw(SpriteSheet, position, sourceRect, Color.White);
    }
}

Load your sprite sheet and create a SpriteAnimation instance

In your Game1 class (or wherever you handle game logic):

public class Game1 : Game
{
    private GraphicsDeviceManager _graphics;
    private SpriteBatch _spriteBatch;
    private Texture2D _spriteSheet;
    private SpriteAnimation _spriteAnimation;

    public Game1()
    {
        _graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
    }

    protected override void Initialize()
    {
        base.Initialize();
    }

    protected override void LoadContent()
    {
        _spriteBatch = new SpriteBatch(GraphicsDevice);
        _spriteSheet = Content.Load<Texture2D>("mySpriteSheet");

        // Assuming each frame is 64x64 and we want to play it at 10 frames per second
        _spriteAnimation = new SpriteAnimation(_spriteSheet, 64, 64, 10);
    }

    protected override void Update(GameTime gameTime)
    {
        _spriteAnimation.Update(gameTime);

        base.Update(gameTime);
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);

        _spriteBatch.Begin();
        _spriteAnimation.Draw(_spriteBatch, new Vector2(100, 100));
        _spriteBatch.End();

        base.Draw(gameTime);
    }
}

Explanation

SpriteAnimation class: This class handles the logic of extracting frames from the sprite sheet and advancing through them at a specified frames-per-second (FPS).

  • The CurrentFrame is incremented each frame and loops back to 0 when it reaches the end.
  • The Update method takes care of advancing frames based on the elapsed time.
  • The Draw method calculates which part of the sprite sheet to draw based on the CurrentFrame.

Running The Game

When you run the game, you should see the sprite sheet being animated at 10 frames per second. You can adjust the frame size, FPS, and sprite sheet dimensions as needed.

Let me know if you'd like more detail on any of the steps!