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);
}
}
这将允许一次只能朝一个方向移动(如果你遵循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)如果玩家试图同时向左和向右移动,移动将被取消。