简体   繁体   English

XNA / C#2D播放器动画问题

[英]XNA/C# 2D Player Animation Problems

My friend and I have decided to make a game for ourselves. 我和我的朋友决定自己做一个游戏。 It is going with a Pokemon and the old Harvest Moon graphics style. 它采用了Pokemon和旧的Harvest Moon图形样式。 I have was doing some testing with animation and I got it to work. 我已经用动画进行了一些测试,然后我开始工作了。 My player Sprite Sheet has eight images (2 for each direction). 我的播放器Sprite Sheet有8张图片(每个方向2张)。

But, When I hold down the Up arrow key and Left or Right or Down arrow keys and Left or Right it is trying to do both animations at once. 但是,当我按住向上箭头键,向左或向右或向下箭头键以及向左或向右键时,它试图同时执行两个动画。 I know that there must be a way to solve this I just need someone to tell me how. 我知道一定有办法解决这个问题,我只需要有人告诉我怎么做。

This is my Animation Class that I have for my Player: 这是我为播放器准备的动画课:

public class Animation
{
    Texture2D texture;
    Rectangle rectangle;
    public Vector2 position;
    Vector2 origin;
    Vector2 velocity;

    int currentFrame;
    int frameHeight;
    int frameWidth;

    float timer;
    float interval = 75;

    public Animation(Texture2D newTexture, Vector2 newPosition, int newFrameHeight, int newFrameWidth)
    {
        texture = newTexture;
        position = newPosition;
        frameWidth = newFrameWidth;
        frameHeight = newFrameHeight;
    }

    public void Update(GameTime gameTime)
    {
        rectangle = new Rectangle(currentFrame * frameWidth, 0, frameWidth, frameHeight);
        origin = new Vector2(rectangle.Width / 2, rectangle.Height / 2);
        position = position + velocity;

        // Comment Out For Camera!!!!
        if (position.X <= 0 + 10) position.X = 0 + 10;
        if (position.X >= 1920 - rectangle.Width + 5) position.X = 1920 - rectangle.Width + 5;
        if (position.Y <= 0 + 10) position.Y = 0 + 10;
        if (position.Y >= 1080 - rectangle.Height + 7) position.Y = 1080 - rectangle.Height + 7;

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

        if (Keyboard.GetState().IsKeyDown(Keys.Up))
        {
            AnimateUp(gameTime);
            velocity.Y = -2;
        }
        if (Keyboard.GetState().IsKeyDown(Keys.Down))
        {
            AnimateDown(gameTime);
            velocity.Y = 2;
        }
    }

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

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

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

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

    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(texture, position, rectangle, Color.White, 0f, origin, 1.0f, SpriteEffects.None, 0);
    }
}

This would allow movement in only one direction at a time (which I believe is what you want if you are following pokemon's game style): 这一次只能允许一个方向的移动(如果您遵循口袋妖怪的游戏风格,我相信这是您想要的):

    if (Keyboard.GetState().IsKeyDown(Keys.Right))
    {
        AnimateRight(gameTime);
        velocity.X = 2;
    }
    else if (Keyboard.GetState().IsKeyDown(Keys.Left))
    {
        AnimateLeft(gameTime);
        velocity.X = -2;
    }       
    else if (Keyboard.GetState().IsKeyDown(Keys.Up))
    {
        AnimateUp(gameTime);
        velocity.Y = -2;
    }
    else if (Keyboard.GetState().IsKeyDown(Keys.Down))
    {
        AnimateDown(gameTime);
        velocity.Y = 2;
    }
    else velocity = Vector2.Zero;

If you want to move two directions at once, something like: 如果要一次移动两个方向,则类似:

    bool animated = false;
    if (Keyboard.GetState().IsKeyDown(Keys.Right))
    {
        AnimateRight(gameTime);
        velocity.X = 2;
        animated = true;
    }
    else if (Keyboard.GetState().IsKeyDown(Keys.Left))
    {
        AnimateLeft(gameTime);
        velocity.X = -2;
        animated = true;
    }    
    else
    {
         velocity.X = 0;
    }  

    if (Keyboard.GetState().IsKeyDown(Keys.Up))
    {
        if(animated == false)
        {   AnimateUp(gameTime); }

        velocity.Y = -2;
    }
    else if (Keyboard.GetState().IsKeyDown(Keys.Down))
    {
        if(animated == false)
        { AnimateDown(gameTime); }
        velocity.Y = 2;
    }
    else velocity.Y = 0;

I know this is kinda old but with this scenario, there is order priority that the player can't control which affect the direction he will be moving if two keys are pressed at the same time. 我知道这有点旧,但是在这种情况下,如果同时按下两个键,玩家将无法控制顺序优先级,这会影响他的移动方向。 A better solution would be : 更好的解决方案是:

velocity = Vector2.Zero;

if (Keyboard.GetState().IsKeyDown(Keys.Right))
    velocity.X += 2;
if (Keyboard.GetState().IsKeyDown(Keys.Left))
    velocity.X -= 2;

if (Keyboard.GetState().IsKeyDown(Keys.Up))
    velocity.Y -= 2;
if (Keyboard.GetState().IsKeyDown(Keys.Down))
    velocity.Y += 2;

if (velocity.X > 0)
    AnimateRight(gameTime);
else if (velocity.X < 0)
    AnimateLeft(gameTime);

// Animate Up/Down only if Left/Right does not... 
// not sure if needed but will follow the style.
if (velocity.X == 0) 
{
    if (velocity.Y > 0)
        AnimateDown(gameTime);
    else if (velocity.Y < 0)
        AnimateUp(gameTime);
}

This way, we separate the input and the logic, which makes things much clearer and we doesn't put priority over certain input (xept for the up/down... but w/e) If a player tries to go Left and Right at the same time, the movement will just be canceled. 这样,我们将输入和逻辑分离开来,这使事情变得更加清晰,并且我们不会将某些输入的优先级设置为优先级(对上/下进行了限制...但是w / e)如果玩家尝试左右移动同时,机芯将被取消。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM