Subscribe to Sergio Tapia - Lost in the GC.        RSS Feed
***** 1 Votes

Animating a sprite in XNA 4 - or how I made Indy have a seizure.

Icon 3 Comments
Today I'll teach you guys how to add a spritesheet image to an XNA project, and use it to display an animating object. We'll also be tossing this sprite bouncing around the screen.

In short, we're going to throw Indiana Jones into a tornado.

We'll be using this spritesheet.

Posted Image

First create your XNA application (Windows Game type) and you'll see two projects. A Foo project and a FooContent project. We're going to be adding our picture to the content type project.

Right click on it and create a new folder called Images. Then right click on that to add an Existing Item and add our Indy picture.

Next, let's create a couple of class level variables. We need a Texture object to hold our indy spritesheet. We also need a Vector2 object to keep track of where our sprite is currently at.

    
Texture2D texture;
Vector2 position;


Next let's create two variables to set our speeds. How fast is indiana jones going to be tossed around our screen?

float horizontalSpeed = 4;
float verticalSpeed = 4;



Now the goodies.

The way a spritesheet works is we have a collection of images that if displayed fast enough gives the illusion of an animation. Imagine a cartoon flipbook. Same principle.

How this translates into the game means that you have a huge image with many smaller images and we only render a small area of interest. We're looking at a specific image inside of the spritesheet every time we render, resulting in a smooth animation.

Let's create some more class level variables to illustrate.

Point frameSize = new Point(32, 48); //How big is each indiana jones in the sprite sheet?
Point currentFrame = new Point(0, 0); //What tiny indy are we rendering at this time?
Point sheetSize = new Point(4, 4); //How many rows and columns of indies are there?


Posted Image

Ok!

Now we can move on to actually drawing our indy.

We need to load our image to our texture variable. In the LoadContent method:

protected override void LoadContent()
{
    // Create a new SpriteBatch, which can be used to draw textures.
    spriteBatch = new SpriteBatch(GraphicsDevice);
    texture = Content.Load<Texture2D>(@"Images\indy");
    // TODO: use this.Content to load your game content here
}



Next we need to actually modify the position of our indy. We do this by modifying our class level variables inside of the Update method. This method is called up to 60fps making it pretty sweet. :)

protected override void Update(GameTime gameTime)
{
    // Allows the game to exit
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
        this.Exit();

    ++currentFrame.X;
    if (currentFrame.X >= sheetSize.X)
    {
        currentFrame.X = 0;
        ++currentFrame.Y;

        if (currentFrame.Y >= sheetSize.Y)
        {
            currentFrame.Y = 0;
        }
    }

    position.X += horizontalSpeed;
    position.Y += verticalSpeed;
    if (position.X > window.ClientBounds.Width - frameSize.X || position.X < 0)
    {
        horizontalSpeed *= -1;
    }
    if (position.Y > window.ClientBounds.Height - frameSize.Y || position.Y < 0)
    {
        verticalSpeed *= -1;
    }


    base.Update(gameTime);
}



Our method above does two jobs. First it iterates through our spritesheet and modifies the index variable accordingly. You'll see that by using this variable we need what part of the image to draw to the screen.

Second, it checks to see if the image touches a border. If it does, it reverses the speed, thus giving it the illusions of bouncing. :lol: I know, it's pretty advanced stuff! :ninja:

So you've made it this far, huh? Good! It's time to draw this bad boy on the screen and put that GTX560 to use.

We'll do all the magic inside of the Draw() method:

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.Black); //Black and depressing, like the last indy film.

    spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend);

    spriteBatch.Draw(texture,
                        position,
                        new Rectangle(currentFrame.X * frameSize.X, currentFrame.Y * frameSize.Y, frameSize.X, frameSize.Y),
                        Color.White,
                        0,
                        Vector2.Zero,
                        1,
                        SpriteEffects.None,
                        0);

    spriteBatch.End();

    base.Draw(gameTime);
}


Let's look in depth at the spriteBatch.Draw() method.

First we tell it which texture to draw, in this case, our entire spritesheet.
Next we tell it WHERE to draw it.
Then we tell is what PART of the entire spritesheet to draw.
Next the color tint. If you use Color.White, the image isn't changed. Any other color and it gets tinted.
Next rotation,
then origin,
then scale of the image,
then effects (if any),
and finally, the layer depth.

WELL THAT WAS TIRING!

Posted Image

If you made it this far congratulations, you should now see Indy flailing about in purgatory. Expect some more XNA write ups as I'm finding this type of programming like a breath of fresh air after year of enterprisey ORM GUNK! :lol:

Posted Image

If you're confused you can find the entire source code for my Game1.cs class here:
http://pastebin.com/2cNLPeRV

3 Comments On This Entry

Page 1 of 1

fromTheSprawl Icon

20 July 2011 - 08:02 PM
Great and interesting tutorial! Easy to follow and makes me pine for game programming. Keep them coming! Hope that in the future Indy is not lost in purgatory. ^^
0

fromTheSprawl Icon

20 July 2011 - 08:03 PM
By the way how did you create the sprite? Those comprise about 70% of the hurdles I'm facing when it comes to game programming.
0

raziel_ Icon

21 July 2011 - 05:48 AM
so you get GTX560 nice :) great tutorial.
@fromTheSprawl just last night i was reading this out:
http://bittyjava.wor...-made-with-svg/
1
Page 1 of 1

Trackbacks for this entry [ Trackback URL ]

There are no Trackbacks for this entry

0 user(s) viewing

0 Guests
0 member(s)
0 anonymous member(s)

About Me

Posted Image


Bienvenidos! I'm a USA ex-pat living in Bolivia for the past 10 years. Web development is my forte with a heavy lean for usability and optimization. I'm fluent in both English and Spanish. I guest write for the popular Python website Python Central. Visit my website.

Categories