C++ C++;/SDL动画速度

C++ C++;/SDL动画速度,c++,animation,sdl,frame-rate,C++,Animation,Sdl,Frame Rate,因此,我正在做一个游戏,遵循在线教程。目前,我在系统中内置了一些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

因此,我正在做一个游戏,遵循在线教程。目前,我在系统中内置了一些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个框架

将刷新速率(60 fps)与动画速率分开。在我看来,最好的解决方案是将动画速率与实时时钟联系起来。在SDL中,您可以使用SDL_Ticks()函数来实现这一点,您可以使用该函数以毫秒分辨率测量时间

作为一个例子,考虑这个例子(不是工作代码,只是草图):

如果不清楚,则通过计算动画开始播放后经过的时间来计算
frameToDraw
变量。将其乘以动画速率,即可得到以动画速率传递的绝对帧数。然后应用“模”操作符将该数字减少到动画长度的范围内,从而获得此时需要绘制的帧

如果刷新速率低于动画速率,则精灵将跳过帧以跟上请求的动画速率。如果刷新速度更快,则将重复绘制同一帧,直到显示下一帧


我希望这能有所帮助。

米格尔写的东西非常好。你可以使用的另一种方法是,使用一个定时器,将它设置为以某个频率启动,并在该频率下,增加你的精灵索引


请注意,您应该始终将渲染和逻辑分开。

我同意,此解决方案也可以工作,但如果您的显示速率低于动画速率,它将使用更多CPU,因为您仍将全速更新动画状态。我同意您的方法更快。然而,这种方法更为通用。例如,如果你想跳过一段时间内的精灵更改或做其他事情,你的公式会变得复杂。我在解决方案中处理精灵更改的方法是让每个角色跟踪其状态。游戏逻辑触发状态更改,状态更改意味着动画可以停止,或更改为不同的帧集,等等。每个精灵都知道其可能的状态。事实上,这很容易。
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 );
}