XNA/ c# 2D玩家动画问题

本文关键字:动画 问题 玩家 2D XNA | 更新日期: 2023-09-27 18:08:46

我和朋友决定为自己制作一款游戏。它采用了Pokemon和《Harvest Moon》的旧图像风格。我对动画做了一些测试,我让它工作了。我的玩家精灵表有8张图片(每个方向2张)。

但是,当我按住向上箭头键和向左或向右或向下箭头键和向左或向右时,它试图同时做两个动画。我知道一定有办法解决这个问题,我只是需要有人告诉我怎么做。

这是我为播放器创建的动画类:

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);
    }
}

XNA/ c# 2D玩家动画问题

这将允许一次只能朝一个方向移动(如果你遵循pokemon的游戏风格,我相信这是你想要的):

    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;

如果你想同时移动两个方向,像这样:

    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;

我知道这有点过时,但在这种情况下,玩家无法控制顺序优先级,如果同时按下两个键,就会影响他移动的方向。一个更好的解决方案是:

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);
}

通过这种方式,我们将输入和逻辑分开,这使事情变得更加清晰,并且我们不会优先考虑某些输入(除了up/down…但w/e)如果玩家试图同时向左和向右移动,移动将被取消。