我是 C++ 初学者,目前正在按照教程使用 SDL2 制作游戏。在配置增量时间以允许用户控制对象的过程中,我似乎对对象运动的平滑度有问题:只有添加 cout 时才平滑,没有它,对象看起来几乎没有响应。 这是我的代码:
int Input()
{
const Uint8* state = SDL_GetKeyboardState(NULL);
objectDir = 0;
if(state[SDL_SCANCODE_W]) {
objectDir -=1;
}
if (state[SDL_SCANCODE_S]) {
objectDir += 1;
}
return 0;
}
int Update() {
if (objectDir != 0) {
objectPos.y += objectDir*50*deltaTime;
}
return 0;
};
//Loop
while (gameRunning)
{
if (!SDL_TICKS_PASSED(SDL_GetTicks(), tick + 0.033f)) {continue;}
cout << deltaTime; //rough movement without this line
deltaTime = SDL_GetTicks() - tick;
if (deltaTime > 0.05f) {
deltaTime = 0.05f;
}
Input();
Update();
Output();
tick = SDL_GetTicks();
}
我尝试删除条件行(SDL_TICKS_PASSED()),但没有任何改变。
SDL_GetTicks()
的返回值:它返回一个 integer 值,表示自程序启动以来经过的 millisecond 数。它不返回浮点数。
基本上,您的
if (!SDL_TICKS_PASSED(SDL_GetTicks(), tick + 0.033f)) {continue;}
语句将导致它最多等待一毫秒。那么之后,deltatime = SDL_GetTicks() - tick
肯定会等于1或者更大的整数。所以你总是将deltatime
限制为0.05。
打印到
std::cout
可能需要 1 毫秒多一点的时间,这允许在 while
循环的迭代之间传递更多的刻度,从而导致游戏表现不同。要解决此问题,请确保您正确解释 SDL_GetTicks()
。
还有一个问题:
Input()
、Update()
和Output()
需要一些可变的时间才能完成。如果您在 tick = SDL_GetTicks()
循环结束时调用 while
,则意味着您将在 Output()
返回后等待固定的时间。因此,您的帧周期将是固定量加上由上述函数引起的可变量。要获得稳定的帧速率,有以下选项:
依靠垂直同步。const Uint32 frame_time = 50; // 50 ms per frame
Uint32 next_frame = SDL_GetTicks();
while (gameRunning) {
if (!SDL_TICKS_PASSED(SDL_GetTicks(), next_frame)) {continue;}
…
next_frame += frame_time;
}