Скорость анимации C ++ / SDL - PullRequest
       19

Скорость анимации C ++ / SDL

3 голосов
/ 15 сентября 2011

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

if( frameCount > 12 )
        frameCount = 0;

    //hero frames   
    SDL_Rect clip[ 13 ];

    clip[ 0 ].x = 0;
    clip[ 0 ].y = 0;
    clip[ 0 ].w = 44;
    clip[ 0 ].h = 39;

    clip[ 1 ].x = 51;
    clip[ 1 ].y = 0;
    clip[ 1 ].w = 44;
    clip[ 1 ].h = 39;

    clip[ 2 ].x = 102;
    clip[ 2 ].y = 0;
    clip[ 2 ].w = 44;
    clip[ 2 ].h = 39;
    ...
    ...
    SDL_BlitSurface( hero, &clip[ frameCount ], destination, &offset );
    frameCount++;

Теперь это работает просто отлично, и каждая итерация цикла while заставит его воспроизводить следующий кадр анимации (кстати, эта анимация является частью класса персонажа).

Проблема, с которой я сталкиваюсь - это скорость анимации. Это происходит при текущем FPS игры, а это 60. Я хочу иметь возможность контролировать скорость анимации игрока отдельно, чтобы я мог замедлить ее до разумной скорости.

У кого-нибудь есть предложения, как мне поступить?

примечание: всего 13 кадров.

Ответы [ 2 ]

6 голосов
/ 15 сентября 2011

Вы используете частоту обновления (60 кадров в секунду) отдельно от частоты анимации. На мой взгляд, лучшее решение - привязать частоту анимации к часам реального времени. В SDL вы можете сделать это с помощью функции SDL_Ticks (), которую вы можете использовать для измерения времени в миллисекундах.

В качестве примера рассмотрим этот пример (не рабочий код, просто набросок):

void init() {
    animationRate = 12;
    animationLength = 13;
    startTime = SDL_Ticks();
}

void drawSprite() {
    int frameToDraw = ((SDL_Ticks() - startTime) * animationRate / 1000) % animationLength;
    SDL_BlitSurface( hero, &clip[ frameToDraw ], destination, &offset );
}

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

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

Надеюсь, это поможет.

2 голосов
/ 15 сентября 2011

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

Обратите внимание, что вы должны всегда разделять визуализацию и логику.

...