Проблема с плавной анимацией в C ++ / SDL / OpenGL - PullRequest
2 голосов
/ 19 октября 2011

Я работал над анимацией 2D-платформерной игры на C ++ / SDL / OpenGL, и я и моя команда достигли точки, когда нам нужно установить, что каждая анимация игрока (ходьба, бег и т. Д.) Нужна другая частота кадров для нашей концепции, но я использую в качестве руководства программирование игр All In One в качестве примера для плавной анимации, и в книге рекомендую иметь переменные, которые ограничивают движение и изменения кадров.

Чтобы уточнить, что я имею в виду, у меня в классе Sprite есть следующие параметры:

std::vector< Vector2f > delayMovementSprite;
std::vector< int > frameDelayPerAnimation;
GLfloat countX, countY;

Где вектор delayMovementSprite содержит все значения для разностных анимаций и приращения countX в каждом кадре до тех пор, пока он не станет равным или больше значения, соответствующего в векторе delayMovementSprite.

Примерно так:

void Sprite::movePosXWithSpeed()
{
  playerMoveInX = false || playerMoveInX;

  countX++;
  if ( countX > delayMovementSprite.at(getCurrentState()).x )
  {
    countX = 0;
    if ( handlerAnimation->getAnimationDirection() == SpriteData::RIGHT )
    {
      if ( position.x + getSpeedX() + width < 6368.f )
      {
        position.x += getSpeedX();
        playerMoveInX = true;
        return;
      }
    }

    else if ( position.x + getSpeedX() + width  > 0 )
    {
      position.x += getSpeedX();
      playerMoveInX = true;
      return;
    }
    playerMoveInX = false;
  }
}

А для кадров у меня есть класс Animation, который обрабатывает следующую информацию:

Uint32 frameRate, oldTime;
int frameDelay;
int frameCount;

И в функции, которая оживляет, я делаю следующее, очень похоже на MoveX в Sprite:

int Animation::animate() 
{
  if( oldTime + frameRate > SDL_GetTicks() ) 
  {
    return -1;
  }

  oldTime += frameRate;
  frameCount++;

  if ( frameCount > frameDelay )
  {
    animationAlreadyEnd = false;
    frameCount = 0;
    currentFrame += incrementFrame;

    if( currentFrame > maxFrames)
    {
      animationAlreadyEnd = true;
      currentFrame = returnFrame;
    }
  }

  return currentFrame;
}

Я получил все это, и все работает, по-видимому, нормально, но в некоторых точках игры анимация выглядит не совсем гладко, когда в других точках это так.

Я оставляю видео "геймплея", чтобы все могли понять, о чем я.

http://www.youtube.com/watch?v=uoxKEYzwkcQ

В настоящее время я использую во время исполнения игры общий таймер со скоростью 60 FPS.

Если кому-то нужна дополнительная информация, не стесняйтесь спрашивать.

1 Ответ

0 голосов
/ 19 октября 2011

На первый взгляд Animation::animate не выглядит правильно. Позвольте мне объяснить: если у вас фиксированная частота кадров дисплея (для игры на основе спрайтов это будет продолжаться), вам нужно линейное отображение счетчика кадров на кадр спрайта. Если вы построите график, это была линия. И в этом случае один над сеткой дискретизации. Всякий раз, когда кто-то думает «дискретная дискретизация строк», он должен думать «Брезенхем», и на самом деле вы можете и должны использовать алгоритм Брезенхэма для продвижения вашей анимации, если вы хотите сохранить инкрементную схему. Другой возможностью было просто оценить аффинное уравнение f_anim = framerate_anim/framerate_game * (framecounter_game - startframe_animation).

...