This worksheet shows you how to handle a sprite sheet containing multiple images. This is useful for simple forms of sprite animation where the program cycles between different images from the sprite sheet.
When you've completed this worksheet, you should be able to:
To get the most out of this worksheet you should do the following:
If you are unable to finish any of these worksheets in one go, then this is what you should do to make sure that you can resume it from the point you finished, without having to start from scratch:
This worksheet assumes that you've already completed worksheets 1, 2 and 3, building on the knowledge that you have previously acquired.
The sprite sheet is loaded into the project just like any other Texture2D image:
Texture2D spriteSheet;LoadContent() method, load the sprite file into the spriteSheet field.The complete sprite sheet looks like this:
There are five images of a balloon, in various stages of inflation, and three images of it exploding. Each image is exactly 120x120 pixels, with the whole sprite sheet being 960 (120x8) pixels wide. We will call the first image Frame 0 and the final image Frame 7.
To draw any particular object from the sprite sheet, we need to put an invisible rectangle around it. For example, to draw Frame 4, we need to define this rectangle:
The starting X position of the rectangle within the sprite sheet is
given by the frame number * the image width. In this case, the frame number is 4 (starting
from 0!) and the image width is 120. The starting Y position of the rectangle is 0. The rectangle
width and height are both 120. We can use this information to create a C# Rectangle object:
Rectangle source = new Rectangle(4*120, 0, 120, 120); // Frame 4
We can also set up a screen location for the sprite image:
Vector2 position = new Vector2(400, 300);
We pass the source Rectangle and screen position to the spriteBatch.Draw() method like
this:
spriteBatch.Draw(spriteSheet, position, source, Color.White);
Let's put it all together to create a simple program:
Draw() method:
spriteBatch.Begin(); Vector2 position = new Vector2(400, 300); Rectangle source = new Rectangle(4*120, 0, 120, 120); spriteBatch.Draw(spriteSheet, position, source, Color.White); spriteBatch.End();
int frame = 0;
Draw() method to replace 4 by frame:
Rectangle source = new Rectangle(frame*120, 0, 120, 120);
frame each time. You
should see a different image drawn each time.The somewhat basic version of spriteBatch.Draw() is acceptable for this simple
case, but as we've seen in earlier worksheets we would really like to have the ability to
support a sprite origin, rotation and scaling. Fortunately there's an alternative version
we can use:
spriteBatch.Draw(spriteSheet, position, source, colour, rotation, spriteOrigin, scale, spriteEffects, zPosition);
For this particular sprite sheet, all the images can use the same origin value of 60, 60 - which approximately the centre of each balloon image.
Draw() method, so that it is before the
spriteBatch.Draw() statement:
Vector2 origin = new Vector2(60, 60);
spriteBatch.Draw() statement that you put in earlier to choose the version
(overload) shown above, with source, origin, rotation, etc.frame each time and confirming
that the correct image frame is displayed with each change.We will now expand the program so that it shows simple animation by moving from frame to frame at some fixed rate.
An obvious way to do this is to add 1 to frame on each update, however this will cause the animation to run too quickly. Try it for
yourself and see.
We need to slow down the animation, so that we only update frame once every 20 (say) updates. To do this, we need to add an extra field to the Game1.cs file:
int updateCount = 0;
Within the Update() method, we can now increment (add 1) to this counter. When
the counter value reaches or exceeds 20 we can then add 1 to frame and reset updateCount to zero. In this way, we will slow
down the animation.
updateCount field to the Game1.cs file. Since it's a field it needs
to go near the declaration of spriteSheet.Update() method:
// TODO: Add your update logic here
updateCount++;
if (updateCount >= 20)
{
frame++;
updateCount = 0;
}
Use what you've learned so far to modify the project so that:
When you've got this working then try this:
When you've finished all the steps above, you need to close down Game Studio Express as follows: