Вы используете частоту обновления (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
вычисляется путем подсчета времени, прошедшего с начала воспроизведения анимации. Вы умножаете это на скорость анимации, и вы получаете, сколько абсолютных кадров при скорости анимации прошло. Затем вы применяете оператор по модулю, чтобы уменьшить это число до диапазона длины вашей анимации, и это дает вам кадр, который вам нужно нарисовать в это время.
Если ваша частота обновления ниже, чем ваша скорость анимации, ваш спрайт будет пропускать кадры, чтобы соответствовать запрошенной скорости анимации. Если частота обновления выше, то один и тот же кадр будет отображаться несколько раз, пока не наступит время отображения следующего кадра.
Надеюсь, это поможет.