2010-07-11 3 views
1

Я работаю над этим довольно долго, ища решения в разных местах. Я использовал стиль 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 нажатие клавиши, как и предполагалось.

+0

Что не работает? Занимает ли он цикл более одного раза или вообще не зацикливается? – Gavin

+0

Приносим извинения за не указание. Проблема в том, что когда клавиша нажата, она не проходит через кадры с помощью циклов for. Вместо этого он отображает только один кадр анимации, застывший на месте. Возможно, последний кадр, как вы указали ниже. –

ответ

0

Из того, что я вижу, код, который вы отправили, будет просто нарисовать последний кадр анимации вашего удара, поскольку цикл for в методе LoopOnce обходит все кадры и только рисует последний. Это связано с тем, что метод draw вызывается один раз для каждого обновления.

XNA сначала вызывает метод обновления, после чего вызывает призыв. Поэтому в вашем методе обновления вы устанавливаете текущий кадр анимации на максимальный кадр, затем он переходит к методу рисования, где вы затем рисуете текущий кадр, который на этом этапе является последним кадром.

Для этого вам нужно будет увеличивать только кадр, который вы хотите нарисовать, по одному для каждого вызова для обновления.

Я не XNA на этом компьютере, так что я не могу проверить это, и это, вероятно, не компилируется без установления каких-либо ошибок синтаксиса, но, чтобы дать вам идею что-то подобное должно сделать это

private void UpdateAttack(KeyboardState current, KeyboardState last, GameTime gameTime) 
     { 
      if (current.IsKeyDown(Keys.S) && last.IsKeyUp(Keys.S)) 
      { 
      mCurrentState =State.Kicking; 
      currentImageIndex=25; 
      } 
      if(mCurrentState ==State.Kicking) 
       neutralStandingKick(gameTime);    
     } 

    private void neutralStandingKick(GameTime gameTime) 
    { 
      currentImageIndex++; 
      if(currentImageIndex==30) mCurrentStart = State.SomeOtherState; 
    } 

Удалить дро один раз способ. Вам нужно будет заменить State.SomeOtherState своим состоянием, когда объект не ударит. Вероятно, вы также захотите поменять номера жестко закодированных кадров на константы. Не нужно менять метод рисования, чтобы эта анимация работала. Надеюсь это поможет.

+0

Позвольте мне опубликовать метод draw, который является частью этого класса, очень быстро. Я немного новичок в вопросах, связанных с XNA. X_x; –

+0

Хорошо, я понимаю, что вы имеете в виду. Не могу поверить, что я пропустил это. Я думал, что смогу использовать цикл for, используя количество кадров X для ножной анимации. Я забыл, что метод обновления вызывается только один раз за цикл, поэтому только один кадр из цикла for получает переданный метод draw. Спасибо за вашу помощь, я найду другой подход к работе с этим! –

+0

Большое спасибо Гэвин. Я попробую это прямо сейчас. –