我想重置时钟,以便clock.getElapsedTime()
从我重置时钟时起给我一个新的时间(例如,在第二次重新启动游戏关卡/场景时很有用)。
我在init()
中初始化clock = new THREE.Clock();
,在我的游戏循环update()
中,我使用这个时钟。但是当游戏结束时,我想重置时钟(我不会再次初始化关卡,只是将玩家定位回起点,所以我不会初始化新的时钟)。
我怎样才能做到这一点?
我想重置时钟,以便clock.getElapsedTime()
从我重置时钟时起给我一个新的时间(例如,在第二次重新启动游戏关卡/场景时很有用)。
我在init()
中初始化clock = new THREE.Clock();
,在我的游戏循环update()
中,我使用这个时钟。但是当游戏结束时,我想重置时钟(我不会再次初始化关卡,只是将玩家定位回起点,所以我不会初始化新的时钟)。
我怎样才能做到这一点?
4条答案
按热度按时间wnavrhmk1#
坏消息:从2015年10月发布的r73开始,不可能将
THREE.Clock
重置为零时间。解释如下,唯一可能的解决方案在此答案的末尾。三钟设计中的问题深入探讨
时钟的设计是危险的...
要了解
THREE.Clock
中的缺陷,我们必须检查the source code,看看它是如何工作的。我们可以看到,在时钟的构造函数中,一些变量被示例化,乍一看,我们可以覆盖我们的Clock
示例,将其重置为零:但是,如果再深入一点,我们需要弄清楚当
getElapsedTime()
被调用时会发生什么,在幕后,它调用getDelta()
,getDelta()
会变异为this.elapsedTime
,也就是getDelta
andgetElapsedTime
are dangerous, conflicting functions,但是我们仍然需要更仔细地研究getDelta
:这个函数**引用了某个未知的隐式全局变量
self
,**并调用了某个奇怪的函数self.performance.now()
。危险信号!但是让我们继续挖掘...结果是Three在“main”Three.js文件中定义了一个全局变量
self
,它的属性为performance
,方法为now()
。回到
THREE.Clock
,看看它是如何计算this.elapsedTime
的,它基于self.performance.now()
返回的值,表面上看起来很简单,但真正的问题出现在这里,我们可以看到self.performance.now()
在闭包中创建了一个真正的“私有”变量,这意味着外部世界的任何人都不能看到/访问它:此
start
变量是应用程序的开始时间,从Date.now()
返回,以毫秒为单位。这意味着**当
Three.js
库加载时,start
将被设置为值Date.now()
。**为了澄清,简单地包含Three.js
脚本对计时器具有全局的、不可逆的副作用。回顾一下时钟,我们可以看到self.performance.now()
的返回值用于计算Clock
的当前经过时间。因为这是基于Three.js
的私有的、不可访问的“开始时间”,它将始终相对于您包含Three.js
脚本的时间。变通方案#1
在你的游戏/关卡开始时存储
startTime = clock.getElapsedTime()
,并相对于此进行所有的计算。类似var currentTime = clock.getElapsedTime() - startTime
的东西是从你的场景加载/开始获得真实绝对时间的唯一方法。变通方案2
Three.Clock
实际上只是Date.now()
的一个薄薄的 Package 器,Date.now()
是一个IE9+可用的方法。您最好围绕它创建自己的小抽象来获得一个合理的时钟,并使用一个易于实现的reset()
方法。如果我找到一个具有此功能的npm
包,或者自己创建一个,我会更新此答案。变通方案3
等待Three.js
Three.Clock
源代码更新,可能由我来更新。由于有一个开放的票证,修复它的拉取请求可能会被接受。puruo6ea2#
保存游戏开始时的时间:
var gameStartTime = clock.performance.now()
,并且通过在游戏期间的任何其他点(包括其结束)从clock.performance.now()
减去gameStartTime
来计算此后的运行时间。gameStartTime - gameStartTime
将等于零,clock.performance.now() - gameStartTime
将为您提供自游戏开始以来的秒数或分钟数。下面是对JavaScript中
performance.now()
定时器函数的引用。brvekthn3#
这不会重置时钟,但会生成一个新的时钟对象,并每隔5秒将新值赋给lapsedTime变量:
oogrdqng4#
下面是我使用
start
pause
和reset
作为动画系统运行时的简单解决方案。