Я работаю над этим довольно долго, ища решения в разных местах. Я использовал стиль Nick Gravelyn для хранения анимаций в текстовом файле и просто увеличиваю индекс для изменения фреймов. Беда, которую я испытываю, - это цикл анимации один раз и только один раз, но по какой-то причине способ, которым я знаю, должен работать, не работает так, как я думал. Я не могу для жизни понять, почему, если это не очень специфично для того, как работает XNA.XNA Fighting Game Style Animation Looping Issue
Вот мой код:
private void UpdateAttack(KeyboardState current, KeyboardState last, GameTime gameTime)
{
if (current.IsKeyDown(Keys.S) && last.IsKeyUp(Keys.S))
{
neutralStandingKick(gameTime);
}
}
private void neutralStandingKick(GameTime gameTime)
{
//timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds; //Framerate control
//if (timeSinceLastFrame > millisecondsPerFrame) //Framerate control
//{
//timeSinceLastFrame -= millisecondsPerFrame; //Framerate control
if (mCurrentState != State.Kicking)
{
mCurrentState = State.Kicking;
Position.Y = 200;
loopOnce(25, 30); //Starts at frame 25, ends at 30
}
//}
}
private void loopOnce(int min, int max)
{
if (currentImageIndex > max || currentImageIndex < min) //Checks to see if index out of range of current animation
currentImageIndex = min; //Starts at the beginning of the animation
for (int i = min; i < max; i++) //Uses the range to determine when to stop
{ currentImageIndex++; } //Increments index each iteration that passes
}
Edit: Вот метод Рисования этого конкретного класса
public void Draw(SpriteBatch spriteBatch)
{
//Get the name of the current sprite to draw
string spriteName = possibleImages[currentImageIndex];
//Use that to get the source rectangle
Rectangle source = spriteSourceRectangles[spriteName];
//Send rectangle to a function to set the framesize for bounds checking
getFrameSize(source);
spriteBatch.Draw(theSpriteSheet, Position, source, Color.White);
}
private void getFrameSize(Rectangle frame)
{
frameSize = frame; //For bounds checking
}
Почему бы не работать?
Новый код (Предложение Гэвина):
private void UpdateAttack(KeyboardState current, KeyboardState last, GameTime gameTime)
{
const int min = 22;
const int max = 30;
timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds; //Framerate control
if (current.IsKeyDown(Keys.S) && mCurrentState != State.Kicking)
{
mCurrentState = State.Kicking;
currentImageIndex = min;
}
if (mCurrentState == State.Kicking)
{
if (timeSinceLastFrame > millisecondsPerFrame) //Framerate control
{
timeSinceLastFrame -= millisecondsPerFrame; //Framerate control
currentImageIndex++;
}
}
if (currentImageIndex == max)
mCurrentState = State.Idle;
}
Метод, который вызывает UpdateAttack:
public void Update(GameTime theGameTime, Game game)
{
KeyboardState aCurrentKeyboardState = Keyboard.GetState();
UpdateMovement(aCurrentKeyboardState);
UpdateJump(aCurrentKeyboardState);
UpdateAttack(aCurrentKeyboardState, mPreviousKeyboardState, theGameTime);
UpdateStageBounds(game);
mPreviousKeyboardState = aCurrentKeyboardState;
}
Это будет цикл анимации на удерживая клавишу клавиатуры "s" вниз. Но он не будет зацикливать все 7 кадров в 1 нажатие клавиши, как и предполагалось.
Что не работает? Занимает ли он цикл более одного раза или вообще не зацикливается? – Gavin
Приносим извинения за не указание. Проблема в том, что когда клавиша нажата, она не проходит через кадры с помощью циклов for. Вместо этого он отображает только один кадр анимации, застывший на месте. Возможно, последний кадр, как вы указали ниже. –