我有几点意见。首先是你没有足够的评论。有些地方不清楚你想做什么,所以很难说是否有更好的方法来做,但我会在我来的时候指出这些。不过,首先:
#define MSECS_PER_STEP 20
int stepCount, stepSize; // these are not globals in the real source
void loop() {
int i,j;
int iterations =0;
static int accumulator; // the accumulator holds extra msecs
static int lastMsec;
loop
通过引用。
int deltatime = msec() - lastMsec;
lastMsec
未初始化(可能为0),这可能开始时是一个大的增量。
lastMsec = msec();
这条线和最后一条线一样
msec
. 这可能意味着“当前时间”,这些调用非常接近,两个调用的返回值可能相同,这可能也是您所期望的,但仍然需要调用函数两次。你应该把这些线改成
int now = msec();
int deltatime = now - lastMsec;
lastMsec = now;
以避免调用此函数两次。当前获取函数的时间开销通常比您想象的要高得多。
if (deltatime != 0) {
iterations = deltatime/MSECS_PER_STEP;
accumulator += deltatime%MSECS_PER_STEP;
}
这说明了变量的含义。
while (accumulator >= MSECS_PER_STEP) {
iterations++;
accumulator -= MSECS_PER_STEP;
}
iterations += accumulator/MSECS_PER_STEP;
accumulator %= MSECS_PER_STEP;
. 除法和模数应该比任何有硬件除法的机器(许多机器都这样做)上的回路运行的时间更短、更一致。
handleInput(); // gathers user input from an event queue
for (j=0; j<iterations; j++) {
for (i=0; i<stepCount; i++) {
doStep(stepSize/(float) stepCount); // forwards the sim
}
}
做
在一个独立于输入的循环中,如果游戏执行缓慢并且落后,则会产生使游戏无响应的效果。看来,至少,如果游戏落后于所有的输入,就会开始堆积起来,一起执行,所有的游戏时间都会一块一块地过去。这是一种不太优雅的失败方式。
另外,我能猜到
j
loop(外环)的意思是,但我不太清楚内环。另外,传递给
doStep
函数——这是什么意思。
}
这是最后一个大括号。我觉得它看起来很孤独。
我不知道到底发生了什么
环
您应该始终假设每个计时器事件都是在同一时间段处理的,尽管如果处理落后,这里可能会有一些偏移。这里你可能注意到的最奇怪的是,如果游戏在处理计时器事件上落后了,然后又赶上了,游戏中的时间可能看起来慢下来(低于实时),然后加速(到实时),然后慢下来(到实时)。
另一种方法,在功能上与您所拥有的类似,是让处理每个计时器事件的最后一步是排队等待下一个计时器事件(注意,如果您选择以这种方式实现游戏,则除第一个事件外,其他人不应发送计时器事件)。这意味着取消计时器事件之间的固定时间间隔,并限制程序睡眠的能力,因为至少每次检查事件队列时,都会有一个计时器事件要处理。