6

我有一个函数可以计算在 X 轴和 Y 轴上移动的各种对象的动画中的下一帧[我称之为frameRender()],还有一个函数将生成的帧应用于对象[我称之为frameDisplay()]。对象不只是从 A 点移动到 B,它们不断移动,总是接收新的目标坐标。我使用setInterval()带有1000/frameRate间隔的 a ,但这似乎根本不起作用,因为浏览器没有准确的时间。

问题是:如何确保动画具有恒定的帧速率,并在所有浏览器、所有系统上以相同的速度运行?我已经尝试了所有方法,即使在不同的浏览器上似乎也无法获得准确的结果(我在 Firefox 和 Chrome 上进行测试,Chrome 通常显示速度要快得多)。

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

但是您如何在所有这些中保持一致性,因为您无法始终确定浏览器何时会变慢,或者它们何时会执行得更快。例如,如果有巨大的运动尖峰,我们减小间隔以保持帧率稳定,然后突然大部分运动物体停止或不动,它会突然执行得非常快!

有任何想法吗?

4

3 回答 3

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 也会继续触发它。

于 2010-06-28T22:41:52.900 回答
3

答案就在这里,Glenn Fiedler 的一篇很棒的文章,需要稍作调整才能将其转换为 Javascript,但原理是相同的。基本上,您需要使用累加器来累加增量时间,并基于此执行步骤。无需更改任何物理数学或任何东西,解决方案是即插即用。还有一个很酷的插值器,可以消除口吃,还可以让你做超级慢的平滑动作(用于回放等)。这太棒了,适用于物理学,应该适用于任何基于步骤的运动。基本上所有你需要的精确计时游戏动作都在那里。

于 2010-06-29T12:25:35.940 回答
2

您可以将动画与系统时间同步。

将当前系统时间保存在变量中。在所有帧上,您要重绘图片检查当前时间 - 您的变量是否等于某个增量时间。然后重新绘制你的动画。否则等待这个差异

于 2010-06-28T22:46:33.503 回答