如何重置three.js时钟?

时间:2016-01-21 21:21:44

标签: javascript three.js

我想重置时钟,以便clock.getElapsedTime()给我一个重置时钟的新时间(例如,第二次重启游戏关卡/场景时很有用)。

我在clock = new THREE.Clock();发起了init(),在游戏循环update()中,我正在使用这个时钟。但是当游戏结束时,我想重置时钟(我没有再次启动该级别,只是将玩家定位回到开头,所以我没有启动新的时钟)。

我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:6)

坏消息:从2015年10月发布的r73开始,不可能THREE.Clock重置为零时间。解释如下,并且这个答案的最后只有可能的解决方法。

深度调查的三个问题的设计

  

时钟的设计很危险......

     

- Mrdoob,GitHub issue comment

要理解THREE.Clock中的缺陷,我们必须检查the source code以了解其工作原理。我们可以看到在constructor for a Clock中,实例化了一些变量,我们可以在我们的Clock实例上重写以重置为零:

this.startTime = 0;
this.oldTime = 0;
this.elapsedTime = 0;

然而,深入挖掘,我们需要弄清楚调用getElapsedTime()时的情况。在引擎盖下,它会调用getDelta(),这会改变this.elapsedTime,这意味着getDelta and getElapsedTime are dangerous, conflicting functions,但我们仍需要仔细查看getDelta

var newTime = self.performance.now();

diff = 0.001 * ( newTime - this.oldTime );
this.oldTime = newTime;
this.elapsedTime += diff;

此函数引用一些未知的隐式全局变量self并调用一些奇函数self.performance.now()。红色标志!但是,让我们继续挖掘...

事实证明,Three定义了一个全局变量self,其属性performance的方法为now() in the "main" Three.js file

回到THREE.Clock片刻,查看它如何计算this.elapsedTime。它基于self.performance.now()返回的值。从表面上看,这似乎是无辜的,除了这里出现了真正的问题。我们可以在闭包中看到self.performance.now() creates a true "private" variable,这意味着外界中没有人能看到/访问它:

( function () {
    var start = Date.now();
    self.performance.now = function () {
        return Date.now() - start;
    }
} )();

start变量是应用的开始时间,以毫秒为单位从Date.now()返回。

这意味着加载Three.js库时,start将设置为值Date.now()要澄清,只需包含{ {1}}脚本对计时器具有全局的,不可逆转的副作用。回顾时钟,我们可以看到Three.js的返回值用于计算{{1}的当前经过时间。 1}}。因为这是基于私人的,无法访问的"开始时间"在{strong>包含self.performance.now()脚本的时候,Clock总是相对的。

解决方法#1

在您的游戏/关卡开始时存储Three.js,然后根据该计算进行所有计算。像Three.js这样的东西是从场景加载/开始获得真正绝对时间的唯一方法。

解决方法#2

引擎盖下的

startTime = clock.getElapsedTime()实际上只是Date.now()周围的一个薄包装,这是一个IE9 +可用的方法。你可以更好地创建自己的微小抽象来获得一个理智的时钟,并且易于实现var currentTime = clock.getElapsedTime() - startTime方法。如果我找到具有此功能的Three.Clock包,或者自己创建,我将更新此答案。

解决方法#3

等待可能由我更新Three.js reset()源代码。由于有一张开放票,因此可能会接受解决它的拉动请求。

答案 1 :(得分:0)

在游戏开始时节省时间:var gameStartTime = clock.performance.now(),然后在游戏过程中的任何其他时间点从gameStartTime减去clock.performance.now()来计算其后的时间,包括其结束。例如:gameStartTime - gameStartTime将等于零,clock.performance.now() - gameStartTime将为您提供自游戏开始以来的秒数或分钟数。

这里是对JavaScript中performance.now()计时器功能的引用。