Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I am making a game, and the animation class I made with 8 frames worked fine, but when I added 2 more frames, it messed up. Here is the code:

  using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace Cubiez
{
    class Player
    {
        public Texture2D playerTexture;
        private Rectangle playerRect;
        public Vector2 playerPosition;
        public Vector2 origin;
        public Vector2 velocity;

        public int currentFrame;
        public int frameHeight;
        public int frameWidth;

        float timer;
        float interval = 150;

        bool hasJumped;

        public Player(Texture2D newPlayerTexture, Vector2 NewPosition, int newFrameHeight, int newFrameWidth)
        {
            playerPosition = NewPosition;
            playerTexture = newPlayerTexture;
            frameHeight = newFrameHeight;
            frameWidth = newFrameWidth;
            hasJumped = true;
        }

        public void Update(GameTime gameTime)
        {
            playerPosition += velocity;

            playerRect = new Rectangle(currentFrame * frameWidth, 0, frameWidth, frameHeight);
            origin = new Vector2(playerRect.Width / 2, playerRect.Height / 2);
            playerPosition = playerPosition + velocity;

            if (Keyboard.GetState().IsKeyDown(Keys.Right))
            {
                velocity.X = 2f;
                AnimateRight(gameTime);
            }
            else if (Keyboard.GetState().IsKeyDown(Keys.Left))
            {
                velocity.X = -2f;
                AnimateLeft(gameTime);
            }
            else
            {

            velocity.X = 0f;
        }

        if (Keyboard.GetState().IsKeyDown(Keys.Space) && hasJumped == false)
        {
            playerPosition.Y -= 3f;
            velocity.Y = -4.5f;
            hasJumped = true;
        }

        if (hasJumped == true)
        {
            float i = 1;
            velocity.Y += 0.15f * i;
        }

        if (playerPosition.Y + playerRect.Height >= 450)
        {
            hasJumped = false;
        }

        if (hasJumped == false)
        {
            velocity.Y = 0f;
        }

    }

    public void AnimateRight(GameTime gameTime)
    {
        timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds / 2;
        if (timer > interval)
        {
            currentFrame++;
            timer = 0;
            if (currentFrame > 3)
            {
                currentFrame = 0;
            }
        }
    }

    public void AnimateLeft(GameTime gameTime)
    {
        timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds / 2;
        if (timer > interval)
        {
            currentFrame++;
            timer = 0;
            if (currentFrame > 6 || currentFrame < 3)
            {
                currentFrame = 6;
            }
        }
    }

    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Begin();
        spriteBatch.Draw(playerTexture, playerPosition, playerRect, Color.White, 0f, origin, 1.0f, SpriteEffects.None, 0);
        spriteBatch.End();
    }


}

}

When I move right, the player animates perfectly, but when I move left, depending on what I change the numbers in the

if (currentFrame > 6 || currentFrame < 3)
            {
                currentFrame = 6;
            }

to, it either is no animation on one frame, or it turns right when he moves, or the player only animates part of it. If somebody could tell me what I am doing wrong, I would greatly apprieciate it. Thanks in advance :) Here is the image: enter image description here

share|improve this question
    
How many frames are there in the WalkRight and the WalkLeft animation? –  Luis Estrada Mar 14 '12 at 21:50
    
5 in WalkRight and 5 in WalkLeft –  CJ Cohorst Mar 14 '12 at 21:50
    
So, correct me if i am wrong, but frames 0-4 are the WalkRight and 5-9 are the WalkLeft? –  Luis Estrada Mar 14 '12 at 21:51
    
From left to right, 0-4 is facing left and 5-9 is right –  CJ Cohorst Mar 14 '12 at 21:52
    
How is it when you move right the animation works, when your code is using frames 0-2. (and you said the 5-9 is facing right). Just a little confused. –  Luis Estrada Mar 14 '12 at 21:57

3 Answers 3

up vote 1 down vote accepted

Change your AnimateRight to:

if (currentFrame > 5)
{
  currentFrame = 0;
}

And your AnimateLeft to:

if (currentFrame > 9 || currentFrame < 5)
{
  currentFrame = 5;
}
share|improve this answer
1  
Thanks for marking as the answer, but please look at what Byte56 said about using the generalized method he made. The only thing you would have to change is the RightAnimation_StartFrame = 0; RightAnimation_EndFrame = 4; LeftAnimation_StartFrame = 5; LeftAnimation_EndFrame = 9; –  Luis Estrada Mar 14 '12 at 22:08

Let me update this based on your comments:

I'm guessing your right frame animations live between 0 and 3 and your left frame animations are between 4 and 6?

Clearly, as you know already, your AnimateLeft() function is bugged. Here, you're setting currentFrame to 6, then on the next loop you increment to 7. Then on the next update currentFrame is greater than 6 (it's 7), so it's set back to 6.

It seems more like you'd want something like this:

public void AnimateLeft(GameTime gameTime)
{
    timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds / 2;
    if (timer > interval)
    {
        currentFrame++;
        timer = 0;
        if (currentFrame < 5 || currentFrame > 9)
        {
            currentFrame = 5;
        }
    }
}

You are incrementing currentFrame, and you want to go from frame 5 to frame 9 right? That's how you do it.

I should also note that you should really try to avoid the use of constants like that in your code. For starters you should pull them out and put them at the top of your code with nice names.

int RightAnimation_StartFrame = 0;
int RightAnimation_EndFrame = 4;
int LeftAnimation_StartFrame = 5;
int LeftAnimation_EndFrame = 9;

And it's always nice to try to generalize stuff like this:

public void Animate(GameTime gameTime, int startFrame, int endFrame)
{
    timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds / 2;
    if (timer > interval)
    {
        currentFrame++;
        timer = 0;
        if (currentFrame < startFrame || currentFrame > endFrame)
        {
            currentFrame = startFrame;
        }
    }
}

Then you can use this to animate right:

Animate(gameTime, RightAnimation_StartFrame, RightAnimation_EndFrame);
share|improve this answer
    
I put that code in, and he goes 2 frames left, then 2 frames right. Sorry about not being specific enough. I put the image in the post. Thanks! –  CJ Cohorst Mar 14 '12 at 22:03
    
OK, thanks for waiting for me to update my answer :/ –  Byte56 Mar 14 '12 at 22:09

If you change directions befor timer exceeds interval, the timer does not get reset to 0 so the amount of animation on a changed direction could be unpredictable.

I might try setting the timer to 0 each time the the input poll shows a key down:

EDIT: Actually, it be best if the timer were reset to 0 only when a different key key direction were selected.. But regardless it needs some mechanism to reset to zero when interupted in the middle of an animation.

share|improve this answer
    
I think this would cause timer to never exceed interval, but the OP could do something similar. Reset timer when a new key is pressed that wasn't pressed before. This would require keeping track of the last frame's key state. –  Byte56 Mar 14 '12 at 22:19

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.