Проблемы с гладкой анимацией в С++/SDL/OpenGL

2 oscar.rpr [2011-10-19 07:31:00]

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

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

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

В случае, когда вектор delayMovementSprite содержит все значения для анимаций differents и increment countX в каждом кадре, пока он не будет равен или больше значения, которое соответствует в vector 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.

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

c++ animation sdl opengl smooth


1 ответ


0 Решение datenwolf [2011-10-19 10:41:00]

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