3

在我的应用程序中,我有一个画布,它的 CSS 大小(CSS,不是 html)会根据窗口大小进行更新。

我有一个主要的游戏循环,看起来像这样:

run = function(){

    console.log(timerDiff(frameTime));

    game.inputManage();
    game.logics();
    game.graphics.animate();
    game.graphics.render();

    frameTime = timerInit();

    requestAnimFrame(run);

}

我的 requestAnimFrame 函数是来自 Paul Irish 的函数:

window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       || 
          window.webkitRequestAnimationFrame || 
          window.mozRequestAnimationFrame    || 
          window.oRequestAnimationFrame      || 
          window.msRequestAnimationFrame     || 
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();

所以基本上问题是我记录的用于测量 requestAnimFrame 调用和有效函数调用之间时间的计时器完全改变了。如果我的浏览器处于全屏状态,我会得到 50/60 毫秒,如果我有一个小窗口,我可以达到 10 毫秒。

由于 requestAnimFrame 调用应该以 60fps 的节奏(我认为大约是 30 毫秒)不断调用函数,所以我不应该有这种结果,因为在计时器的创建和检查之间基本上没有发生任何事情,除了requestAnimFrame

我也有一些反复出现的微冻结(不到一秒),每 2/3 秒发生一次。但是计时器没有检测到时间的任何变化(就像javascript的时间计数器被阻止一样)

我的计时器功能是这样的,但在这里并不重要

timerInit = function()
{
    return new Date();
}

timerDiff = function(datePrev)
{
    return new Date().getTime() - datePrev.getTime();
}
4

2 回答 2

7

好吧,标准基本上说requestAnimationFrame它将“尽最大努力”以“一致”的帧速率运行。这并不能保证 60fps;它只是声明它将尽可能快地制作动画。

不幸的是,到目前为止,我对它的体验和你一样黯淡。我最终回到setTimeout. 它以大致相同的速度进行,并且图形更新是准确的,并且不会像使用requestAnimationFrame. 当然不是 60fps,但至少你可以知道发生了什么。

我确信性能只会随着浏览器开发人员优化新功能而提高,但暂时考虑回到timeouts.

编辑:我想提醒人们,这是一年前回答的,时代变了:)

于 2012-03-25T13:29:16.077 回答
4

“所以基本上问题是我记录的用于测量 requestAnimFrame 调用和有效函数调用之间时间的计时器完全改变了......”

当然可以,这就是为什么你需要测量它并根据这个时间差值计算你的下一帧。

假设您想在 1 秒内以 60 fps 将 div 的“left”css 属性从 0px 设置为 120px。

  • 使用 setTimeout,因为你设置了帧数,你知道你必须增加多少'left'属性:120px/60frames = 2px/frame

  • 使用 requestAnimationFrame,你不知道下一帧何时发生,直到它发生;然后你测量这个和前一帧之间的时间差,然后计算你必须增加css“左值”的值;如果帧发生在 500 毫秒后,增量距离 = (120 像素 * 500 毫秒)/1000 毫秒 = 60 像素;想法是,在动画开始时,您不能在每一帧都有一个固定的预定值来递增,您需要根据时间差动态计算它

所以即使动画不是宣传的60fps,如果跳帧,每一帧没有跳帧都会绘制出准确的更新情况。

您必须稍作调整才能决定动画何时结束。

于 2012-07-31T09:18:37.457 回答