2010-06-28 59 views
6

我有一个函数可以计算在X轴和Y轴上移动的各种对象(我称之为frameRender())和将结果帧应用到对象[我称之为frameDisplay()]的动画中的下一帧。物体不仅从A点移动到B点,它们不断移动,始终接收新的目标坐标。我使用setInterval(),间隔时间为1000/frameRate,但由于浏览器没有准确的计时,所以这似乎不起作用。如何在所有系统上的所有浏览器上以相同的速度播放JavaScript动画?

问题是:如何确保动画具有恒定的帧速率,并且在所有浏览器上以相同的速度在所有系统上运行?我已经尝试了一切,并且即使在不同的浏览器上也看不到准确的结果(我在Firefox和Chrome上测试,Chrome通常显示速度更快)。

结果应该是:当播放速度慢时,动画间隔应该首先减少,然后尝试跳过一些帧[跳过frameDisplay()],如果DOM显示慢,直到播放正确。播放速度快时,应增加动画间隔,使动画以正确的速度播放。

但是,如何保持所有这一切的一致性,因为您无法始终确定何时浏览器变慢,或者执行速度快。例如,如果运动的峰值很大,并且为了保持帧速率稳定而减少间隔,然后突然大部分运动物体停止或移动不多,它会突然表现得非常快!

任何想法?

回答

3

答案is here,由Glenn Fiedler撰写的一篇很好的文章,需要稍微调整一下在Javascript中进行转换,但原理是一样的。基本上,您需要使用一个累加器来累计delta时序,并根据这个时序执行步骤。无需改变任何物理数学或任何东西,解决方案就是即插即用。还有一个很酷的内插器,可以消除口吃,还可以让您做超慢的平滑运动(用于重播等)。这太棒了,适用于物理学,并应该在任何基于步进的运动中工作。基本上所有你需要精确计时的游戏动作就在那里。

7

问题是:如何确保动画具有恒定的帧速率,并且在所有浏览器上,在所有系统上以相同的速度运行?

你无法对帧率做任何事情。您可以控制的唯一一件事是您的应用程序如何基于时间更新而进行更新。这在浏览器之外也是如此,并且是游戏开发中的一个常见话题。

要做的最好的事情是跟踪更新之间的增量(读取:时间差)。

(function() { 
    function getTime() { 
     return new Date().getTime(); 
    } 
    var last = getTime(); 

    function update(delta) { 
     // Update your application state on delta (ms of time passed) 
    } 

    (function loop() { 
     update(last = getTime()-last); 
     render(); 
     setTimeout(loop, 20); // 20 = attempt 50fps 
    }()); 
}()); 

请注意在这里使用setTimeout。这是为了避免loop()被调用为不同步。即使先前的呼叫没有完成,setInterval也会继续发射。

+0

所以基本上你的意思是我应该改变帧渲染数学包括一个delta变量,所以我可以移动例如基于前一次通过的对象或多或少的X Y像素? – stagas 2010-06-28 22:52:31

+0

@stagas - 正好。这样,如果一次更新在50ms内,另一次在450ms内,如果你明白我的意思,你的应用程序仍然应该处于“500ms大关”。 – Matt 2010-06-28 22:54:51

+0

很酷,会马上试试,谢谢 – stagas 2010-06-28 23:00:19

2

可以synhronize与系统时间动画。

将当前系统时间保存在变量中。 在所有的框架上,然后你想重画图片检查当前时间 - 你的变量等于一些增量时间。然后重新制作您的动画。否则等待这个区别

相关问题