0
\$\begingroup\$

I'm building my very first game with XNA and i'm trying to get my sprite to run. Everything is working fine for the first sprite. E.g : if I go right(D) my sprite is looking right , if I go left(A) my sprite is looking left and if I don't touch anything my sprite is the default one. Now what I want to do is if the sprite goes Right, i want to alternatively change sprites (left leg, right leg, left leg etc..) xCurrent is the current sprite drawn xRunRight is the first running Sprite and xRunRight1 is the one that have to exchange with xRunRight while running right. This is what I have now :

    protected override void Update(GameTime gameTime)
    {
        float timer = 0f;
        float interval = 50f;
        bool frame1 = false ;
        bool frame2 = false;
        bool running = false;

        KeyboardState FaKeyboard = Keyboard.GetState();
        // Allows the game to exit
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();


            if ((FaKeyboard.IsKeyUp(Keys.A)) || (FaKeyboard.IsKeyUp(Keys.D)))
            {
                xCurrent = xDefault;
            }

            if (FaKeyboard.IsKeyDown(Keys.D))
            {

                timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
                if (timer > interval)
                {
                    if (frame1)
                    {
                        xCurrent = xRunRight;
                        frame1 = false;
                    }
                    else
                    {
                        xCurrent = xRunRight1;
                        frame1 = true;

                    }
                }

                xPosition += xDeplacement;


            }

Any ideas...? I've been stuck on this for a while.. Thanks in advance and let me know if you need any other part from the code.

\$\endgroup\$
1
  • \$\begingroup\$ I know the frame 1, frame 2 and (timer > interval) logic is not working but it's where I was going before realizing that it wasn't going to work. \$\endgroup\$
    – PhaDaPhunk
    Commented Nov 30, 2011 at 23:32

1 Answer 1

2
\$\begingroup\$

You want to use a spritesheet. The SpriteSheetPacker tool can assist you in making one.

First of all, we need to define some objects:

Texture2D SpriteSheet;
Point FrameSize = new Point(64, 64);//this is the size of your frame.  This is an example.
//It should be the Width, Height of each of your frames.  
//It's important that each frame is the same size.

Point SheetSize = new Point(12, 1);//this is how many frames of animation
//you have.  The first number is the number of frames in a row.  The second is the
//number of rows you have.  E.g, for 8 frames that are in one row, it would be (8,1).

Point CurrentFrame = new Point(0, 0); //You'll use this later to keep track
//of what frame you're on.

int AnimationDelay = 0;//You'll use this later to slow down the animation
//if it plays too quickly.

Next, you need to assign a texture to your Texture2D:

SpriteSheet= Content.Load<Texture2D>("Sprites\\SpriteSheet");//Loads Texture

Then, you need to update your animation:

if (AnimationDelay == 5)// delay frame update if it's too fast
   {
     if (CurrentFrame.X < SheetSize.X)
        {
           ++CurrentFrame.X;// Move to a new frame
        }
        else
        {
           CurrentFrame.Y++;//Move down a row, since we've
           //hit the end of the current one
           CurrentFrame.X = 1;//set the X to 1, so we start fresh
        }
        if (CurrentFrame.Y >= SheetSize.Y)
           {
             CurrentFrame.X = 0;
             CurrentFrame.Y = 0;//Start the animation over again
           }

           AnimationDelay = 0;//Set this to 0, so we delay it again
    }
    else
    {
      AnimationDelay += 1;// add one, so we can continue when we are ready
    }

Now, we have to draw your sprite, using your new spritesheet:

spriteBatch.Draw(SpriteSheet, Position,
                                new Rectangle(CurrentFrame.X * FrameSize.X,
                                CurrentFrame.Y * FrameSize.Y, FrameSize.X, FrameSize.Y),
                                Color.White, Rotation, Center, Size, SpriteEffects.None, 0);

Alright, time to explain. Everything is pretty straightforward, except for the update, so I'll explain that.

Essentially, what you're doing is moving a Rectangle across your giant spritesheet. In doing so, you will only draw what is inside the rectangle, giving the illusion of changing frames. In reality, you're just drawing a portion of the larger sprite.

You continue this way until you hit the last frame of your row. Then, if applicable, you move down to the next row. You continue this way until you reach the last frame of the last row, at which point you start over. You delay the update with AnimationDelay, as it will normally "play" the animation too quickly.


As for your questions, yes, it is possible to only do a portion of that sheet. However, since the sheet is laid out in a rather arbitrary manner, it's not as easy as specifying a row to start on.

Personally, I would cut out the row that you need (in an image editing program like GIMP or Photoshop. GIMP is free, Photoshop is not). Otherwise, you'll have a hard time lining up your frames.


It is possible to skip frames and rows, if you know which ones you don't want to use. For example, this will skip frame 5 of row 2:

if(CurrentFrame.X == 4 && CurrentFrame.Y == 2)
  {
     CurrentFrame.X += 2;//This will skip frame 5.  Just be sure to not use the
     //normal CurrentFrame.X++, or you're skip 2 frames!
  }

Similarly, you can apply this to skip whole rows as well:

if(CurrentFrame.X >= SheetSize.X && CurrentFrame.Y == 2)
  {
     CurrentFrame.Y += 2;//This will skip row 3.  Just be sure to not use the
     //normal CurrentFrame.Y++, or you're skip 2 rows!
     CurrentFrame.X = 1;
  }    
\$\endgroup\$
7
  • \$\begingroup\$ By the way I already have a sprite sheet if you could put it in the example it would be of great help! sprites-inc.co.uk/files/X/X1/X \$\endgroup\$
    – PhaDaPhunk
    Commented Nov 30, 2011 at 23:44
  • \$\begingroup\$ Ok thanks a lot!! But let's say i don't want to use all the sprites on my sheet? do I have to find a new one or is there a way to tell the program the ones I want on the sheet? \$\endgroup\$
    – PhaDaPhunk
    Commented Nov 30, 2011 at 23:56
  • \$\begingroup\$ Because as you can see on the sheet in linked, there is a set of sprite for the running, shooting, jumping and dashing animations \$\endgroup\$
    – PhaDaPhunk
    Commented Nov 30, 2011 at 23:58
  • \$\begingroup\$ Can I skip Sprites ? Or even row ? \$\endgroup\$
    – PhaDaPhunk
    Commented Dec 1, 2011 at 0:02
  • \$\begingroup\$ Ok thanks!! :) One last question , the frame size (51, 74) is that just a example size? Or does it have to be this size? \$\endgroup\$
    – PhaDaPhunk
    Commented Dec 1, 2011 at 0:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .