我正在用c ++ atm编写一个小游戏。
我的游戏While循环始终处于活动状态,在此循环中, 我有一个条件,如果玩家正在射击。
现在我面临以下问题,
每次射击后,都会有一个延迟,该延迟会随着时间的推移以及玩家应该移动的延迟而改变。
atm我正在使用Sleep(700),问题是我不能在700毫秒内移动,我需要一个计时器,因此移动命令仅执行700毫秒而不是等待700毫秒
答案 0 :(得分:1)
这取决于您假设的“睡眠”是如何实现的。您应该知道一些事情,因为可以通过几种方法解决。
您不想让线程进入睡眠状态,因为这会导致一切暂停,这不是您想要的。
此外,您得到的时间可能比睡眠所允许的时间还要多。例如,如果您睡700毫秒,您可能会得到更多,这意味着,如果您依赖准确的时间,您可能会因此而感到疲劳。
1)第一种方法是记录播放器内部的原始时间。这不是最好的方法,但是它适用于简单的玩具程序并在您解雇时在班级内记录std::chrono::high_resolution_clock::now()
(检查#include <chrono>
或查看here)的结果。要检查是否可以再次触发,只需将您存储的值与...::now()
进行比较,看看是否经过了700ms。您必须阅读文档才能在几毫秒内使用它。
2)一种更好的方法是通过一种称为“游戏滴答”的方式给您的游戏一个脉动,这就是您的世界前进的脉动。然后,您可以存储触发的游戏标记,并执行与上一段类似的操作(除了现在,您只是在检查是否currentGametick > lastFiredGametick + gametickUntilFiring
)。
对于花哨的想法,请确保每隔X毫秒执行一次gametick++
,然后运行世界。常见值在10毫秒到50毫秒之间。
然后您的游戏循环会变成
while (!exit) {
readInput();
if (ticker.shouldTick()) {
ticker.tick();
world.tick(ticker.gametick);
}
render();
}
以上内容具有以下优点:
您只需要在每个游戏滴答声中更新世界
您可以保持在游戏标记之间进行渲染,因此可以流畅地制作动画,因为您将以很高的帧率进行渲染
如果要暂停,只需旋转一会儿循环,直到经过一段时间即可
现在,这避免了重要的讨论,如果您正在考虑采用壁垒路线,则一定要阅读this。
无论采取哪种路线,您都可能需要阅读this。