2014-10-26 127 views
0

我正在尝试创建一个独立帧速率的游戏,其中myObject正以每毫秒一个单位向右移动。不过,我不知道如何在这段代码计算deltaTime如何正确计算时间增量?

var currentTime = 0; 
var lastTime = 0; 
var deltaTime = 0; 

while(play) { 

    // Retrieve the current time 
    currentTime = Time.now();    
    deltaTime = currentTime - lastTime; 
    lastTime = currentTime; 

    // Move myObject at the rate of one unit per millisecond 
    myObject.x += 1 * deltaTime;  
} 

比方说,第一架用了30毫秒,所以deltaTime应该是30,但它是0 因为我们只知道在开始的时间不在帧的末尾。然后,在第二帧花了40毫秒,所以deltaTime是30,因此myObject.x是30.但是,经过的时间是70毫秒(第一帧30毫秒+第二帧40毫秒),所以myObject.x应该是70,而不是30

我不是在模拟物理,我只是试图将myObject相对于经过的时间(不是帧)移动。

如何正确计算deltaTime

我知道一些游戏引擎的人使用大块时间或打勾,所以他们提前做动画。另外,我已经阅读了Glenn Fiedler的article on fixing your timestep和其他很多,但我仍然感到困惑。

+0

你在用什么语言进行编程? – APerson 2014-10-26 18:52:30

+0

这看起来像JavaScript,但这是一个语言无关的问题 – 2014-10-26 18:54:04

+0

@APerson我尝试学习概念先生..我不打扰任何语言,只要它不会汇编 – user3578021 2014-10-26 18:55:30

回答

1

试试这个:

float LOW_LIMIT = 0.0167f;   // Keep At/Below 60fps 
float HIGH_LIMIT = 0.1f;   // Keep At/Above 10fps 

float lastTime = Time.now(); 

while(play) { 

    float currentTime = Time.now(); 
    float deltaTime = (currentTime - lastTime)/1000.0f; 
    if (deltaTime < LOW_LIMIT) 
     deltaTime = LOW_LIMIT; 
    else if (deltaTime > HIGH_LIMIT) 
     deltaTime = HIGH_LIMIT; 

    lastTime = currentTime; 

    myObject.x += 1000 * deltaTime;  // equivalent to one unit per ms (ie. 1000 per s) 
} 

有很多错,但它可以更容易说明基本概念。

首先,请注意,在循环开始之前,您需要使用某个值初始化lastTime。您可以使用较低的值(即Time.now() - 33),以便第一帧产生所需的增量,或者像我一样使用它(您会看到我们将其限制在循环中)。

接下来,您将获得每个froame开始时的当前时间,并使用它计算自上次循环(在此例的第一次运行时将为零)以来的时间。然后我喜欢将其转换为,因为“每秒”工作比“每毫秒”更有意义 - 但随时可以删除/ 1000.0f部分以保持ms。

然后,您需要将deltaTime限制为某个可用范围(例如,我使用10-60fps,但您可以根据需要更改此范围)。这只是防止循环运行太快或太慢。 HIGH_LIMIT尤其重要,因为它可以防止可能导致游戏循环中的混乱的非常大的delta值(最好比代码失效时有些不准确) - LOW_LIMIT可以防止零(或非常小)的时间步长,有问题的(特别是对于物理)。

最后,一旦您计算了此帧的新的deltaTime,您将保存下一帧期间使用的当前时间。

+0

谢谢先生..为迟到道歉..我认为没有1会在这里..使用变量low_limit&high_limit给我的想法.. 在行 if(deltaTime user3578021 2014-10-29 14:31:31

+0

很高兴帮助:) – free3dom 2014-10-29 18:16:20