Sprite Sheets

Note: Do not save the following sprite sheets for use in a program. Instead, download and unzip the sprite sheets from the Content folder. The files in the zip file have not been resized (and the ones below have).

This is a sprite sheet:

And so is this:

And this:

Sprite sheets don't have to be horizontal. They can be vertical. This is a sprite sheet:

And they can be 2-dimensional:

Here is another 2D sprite sheet:

Sprite sheets are used to simulate motion the same way that a movie simulates motion: by displaying one frame, then displaying the next frame, then the next, etc.

Example

To create an explosion, we can use the following sprite sheet. It is in the bundle of sprite sheets that we unzipped and is ExplosionSpriteSheet.png:

A sprite sheet is a single image file, but each file is composed of multiple images which must be extracted one at a time and then drawn on the screen.

To use a sprite sheet, we must determine the size of each image. Download the zipped sprite sheet file and extract the sprite sheets. Open the explosion sprite sheet and then paste it into Paint.NET.

Determine the frame size

The first thing to do is determine the frame size. A frame is a single sprite. The sprite sheet is 1200x120, and there are 10 images, so the size of each image is 120x120.

To create an animation, we need to display each of the 10 rectangles in succession.

  1. Rectangle 1 is (0, 0, 120, 120).
  2. Rectangle 2 is (120, 0, 120, 120).
  3. Rectangle 3 is (240, 0, 120, 120).
  4. Rectangle 4 is (360, 0, 120, 120)

...

  1. Rectangle 10 is (1080, 0, 120, 120).

Note that the only thing that is changing is the X coordinate. If we number our frames from 0 to 9, we can determine the coordinate by multiplying the frame number by 120:

  1. Rectangle 0 is (0*120=0, 0, 120, 120).
  2. Rectangle 1 is (1*120=120, 0, 120, 120).
  3. Rectangle 2 is (2*120=240, 0, 120, 120).
  4. Rectangle 3 is (3*120=360, 0, 120, 120)

...

  1. Rectangle 9 is (9*120=1080, 0, 120, 120).

This is what the sourcerectangle property is for in our long Draw method.

Let's write a program to animate the man. Create a C#/XNA/Windows game called Explosion.

Add constants and variables at the top of the program that will define our sprite sheet:

constint FRAME_COLS = 10; // sprite sheet size

constint FRAME_ROWS = 1;

const int FRAMES_PER_SECOND = 30;

String TextureFileName = "ExplosionSpriteSheet";

Vector2 position; // where to draw on screen

Rectangle source; // where current frame is

int currentFrame;

int delay; // ticks between frames

int frameTimer;

Point FRAME_SIZE;

Texture2D spriteTexture;

We are using the Point data type for the first time here. It is the same as Vector2 except that its values are integers instead of floats. Although the name implies that we are storing a point, we can also interpret the two values as a width (x) and a height (y). Note that Point cannot be a constant.

Add to Initialize:

position = newVector2(0, 0);

currentFrame = 0;

delay = 60 / FRAMES_PER_SECOND;

frameTimer = delay;

Add to LoadContent:

spriteTexture = Content.Load<Texture2D>(TextureFileName);

int width = spriteTexture.Width / FRAME_COLS;

int height = spriteTexture.Height / FRAME_ROWS;

FRAME_SIZE = newPoint(width, height);

Add to Draw:

spriteBatch.Begin();

source = newRectangle(currentFrame * FRAME_SIZE.X, 0,

FRAME_SIZE.X, FRAME_SIZE.Y);

spriteBatch.Draw(spriteTexture, position, source, Color.White,

0, Vector2.Zero, 1, SpriteEffects.None, 0);

spriteBatch.End();

Run the program. We are not changing the source, so only the first frame will appear.

Move from frame to frame

We need to add instructions to Update to create an animation.

Every tick, we need to decrement our frameTimer. When it gets down to 0, we need to do two things: (1) reset the frameTimer (to the delay value), and (2) move to the next frame:

frameTimer--;

if (frameTimer == 0)

{

frameTimer = delay;

currentFrame++;

if (currentFrame == FRAME_COLS)

currentFrame = 0;

}

Making a man run

Use the same program, but change the texture to the running man (Run.png). The man is 48x48 with 10 frames.

Move across the screen

To make the man run, we need to change his location. Add to your declarations:

constRectangle screen = newRectangle(0, 0, 800, 480);

Determine how fast we want him to move. Add to your declarations:

const float SECONDS_TO_CROSS_SCREEN = 3;

int speed;

Add to Initialize:

speed = (int) (screen.Width / SECONDS_TO_CROSS_SCREEN / 60);

Add to Update:

position.X += speed;

Two-dimensional sprite sheets

We can easily adapt this code to work with a 2-dimensional sprite sheet.

Page 1 of 6