void logicLoop () { float finalTime = (float) clock() / CLOCKS_PER_SEC; float deltaTime = finalTime - initialTime; initialTime = finalTime; ... // Here I move things using deltaTime value ... }
当我在游戏中添加子弹时,问题出现了.如果子弹在两秒内没有击中任何目标,则必须将其销毁.然后,我所做的是保持对子弹创建的时刻的引用:
class Bullet: public GameObject { float birthday; public: Bullet () { ... // Some initialization staff ... birthday = (float) clock() / CLOCKS_PER_SEC; } float getBirthday () { return birthday; } }
然后我将其添加到finalTime和deltaTime测量之外的逻辑中:
if (bullet != NULL) { if (finalTime - bullet->getBirthday() > 2) { world.remove(bullet); bullet = NULL; } }
它看起来很不错,但是当我运行代码时,子弹会保留太多时间.寻找问题,我打印了(finalTime – bullet-> getBirthday())的值,我看到它增加的确非常慢,就像它不是以秒为单位测量的时间.
问题出在哪儿?我虽然结果将在几秒钟内完成,因此子弹将在两秒内被移除.
解决方法
其他进程也占用cpu时间,因此两个时钟不一样.每当您的操作系统执行某些其他进程的代码时,包括此进程“休眠”时,都不会计入clock().如果你的程序在具有多个cpu的系统上是多线程的,那么clock()可能会“重复计算”时间!
人类对OS时间片没有任何了解或感知:我们只是感知实际时间的实际通过(称为“壁时间”).最后,你会看到clock()的时基与墙上时间不同.
Do not use clock()
to measure wall time!
你需要像gettimeofday()或clock_gettime()这样的东西.为了减轻人们改变系统时间的影响,在Linux上我个人推荐使用系统的“单调时钟”clock_gettime(),这个时钟与墙上时间同步但是有一个任意的时代不受人们玩耍的影响.电脑的时间设置. (如果需要,显然可以转用便携式替代品.)
这实际上是在the cppreference.com page for clock()
讨论的:
std::clock
time may advance faster or slower than the wall clock,depending on the execution resources given to the program by the operating system. For example,if the cpu is shared by other processes,std::clock
time may advance slower than wall clock. On the other hand,if the current process is multithreaded and more than one execution core is available,std::clock
time may advance faster than wall clock.
当您不确定发生了什么时,请养成阅读所使用的所有功能的文档的习惯.
编辑:结果GLUT本身有一个你可以使用的功能,这可能很方便. glutGet(GLUT_ELAPSED_TIME)为您提供自调用glutInit()以来经过的墙毫秒数.所以我想这就是你需要的东西.它可能稍微高一些,特别是如果GLUT(或OpenGL的其他部分)已经定期请求挂起时间,并且此函数仅查询已经获得的时间…从而使您免于不必要的第二次系统调用(成本) .