Skip to main content

游戏开发:游戏逻辑处理时钟

Feishiko
Author
Feishiko
Programming Avali

这周参加了GMTK GAMEJAM 2024,是个平台跳跃,游戏内出现了如果卡顿就会卡墙里或者浮空的BUG,经过我仔细研究发现这和我在和时间有关的变量后面都乘上了一个deltatime。

但是不这么做是不行的,因为每个人的机子响应时间不同而且屏幕刷新率也不同,为了保证相同时间内执行的效果一样(比如玩家的移动速度),所以需要乘上一个deltatime补上这一部分时差。然后deltatime由于是上一帧逻辑与当前逻辑的实际现实时间差,所以如果中间有卡顿这个deltatime就会变大。一旦窗口freeze了一段时间,玩家就顺其自然的掉出去了。

又多亏了我另外两个好哥们(TML和域外),我现在掌握了使用tick时钟进行游戏逻辑帧的处理。

具体原理是让一秒内处理相同的时间逻辑。因为deltatime经过一秒后整数部位会来到1,所以通过限制一帧内deltatime > 1/一秒内执行的逻辑次数,使deltatime等于1/一秒内执行的逻辑次数,就能让tick进行相对恒定的逻辑帧处理。

以下代码设定一秒内执行60次tick,即60次逻辑执行,并且恒定。

local totalTime, elapsedTime = 0, 0 -- <
function love.update(dt)
    totalTime = totalTime + dt -- <
    DrawEvent:Update();
    while totalTime - elapsedTime > 1 / 60 do -- <
        dt = 1 / 60 -- <
        if self.scenes[self.currentScene].Update ~= nil then self.scenes[self.currentScene]:Update(dt) end;
        gameObject:ObjectInitUpdate(dt);
        love.keyboard.updateKeys();
        elapsedTime = elapsedTime + 1 / 60 -- <
    end -- <
end