javascript游戏中的异步/可变帧率
asynchronous / variable framerate in javascript game
这可能是一个愚蠢的/以前回答过的问题,但它一直困扰着我和我的朋友一段时间,我一直无法找到一个好的答案。
现在,我让我所有的JS画布游戏运行滴答。例如:
function tick(){
//calculate character position
//clear canvas
//draw sprites to canvas
if(gameOn == true)
t = setTimeout(tick(), timeout)
}
这对于高端系统上cpu便宜的游戏来说很好,但是当我试图每隔一秒画更多的时候,它开始以慢动作运行。所以我的问题是,我如何保持x,y位置和命中检测计算全速进行,同时允许可变帧率?
旁注:我曾尝试使用requestAnimationFrame API,但说实话,它有点令人困惑(不是所有的好教程),虽然它可能会加快你的处理,它并不能完全解决问题。
RequestAnimationFrame使产生很大的差异。这可能是解决你问题的办法。你还可以做两件事:设置第二个滴答系统来处理它的模型方面,例如命中检测。一个很好的例子就是PhysiJS是如何做到这一点的。它更进了一步,使用了一些新浏览器的一个功能,叫做web worker。它允许您使用第二个CPU核心。John Resig有一个很好的教程。但是要注意,它很复杂,没有得到很好的支持(因此有很多bug,经常崩溃)。
真的,请求动画帧是非常简单的,它只是几行,一旦你设置好,你可以忘记它。它不应该改变任何现有的代码。理解代码的作用有点困难,但是您可以对示例中的setTimeout代码进行剪切和替换。如果你问我,setTimeout也一样复杂!它们实际上做同样的事情,除了setTimeout有一个延迟时间,而requestAnimationFrame没有——它只是在准备好时调用你的函数,而不是在一段设定的时间之后。您实际上并没有使用刻度。发生的是你不断地调用tick()
,一遍又一遍。你需要删除()
,只留下setTimeout(tick,timeout);
。我个人喜欢使用arguments.callee
来明确地声明一个函数调用自己(从而消除了知道函数名称的依赖关系)。
话虽如此,我在执行可变帧率时喜欢做的是尽可能地简化底层引擎。例如,要让一个球在墙上弹跳,我要检查从球的前一个位置到下一个位置的线是否碰到了墙,如果是,什么时候。
也就是说,你需要小心,因为一些浏览器停止所有的JavaScript执行时,一个链接菜单(或任何其他菜单)被打开,所以你可能以几秒甚至几分钟的间隔结束两个"帧"之间。我个人认为基于帧的计时在大多数情况下是可行的。
正如Kolink提到的。setTimeout
看起来像个bug。假设这只是一个拼写错误,而不是一个bug,我想说,它不太可能是动画本身(也就是说,DOM更新),这是真正减慢你的代码。
多一点多少钱?我在一台1.2GHz Atom上网本(我在我最慢的机器上使用的最慢的浏览器,VMWare是因为我使用Linux)上的IE7上,在屏幕上同时动画了数百个元素,效果很好。
根据我的经验,当动画元素的数量增加时,如果没有正确地进行命中检测会导致最大的减速。这是因为一个朴素的实现本质上是指数的(它会尝试做n^n
比较)。解决这个问题的方法是过滤掉比较,以避免不必要的比较。
- esri javascript异步打印
- JavaScript异步问题
- $translateProvider.useStaticFilesLoader的Angular Translate异步定
- 异步facebook功能
- D3/Raphael js 以慢帧率绘制 1000+ 动画圆圈
- BlackBerry PlayBook网络作品:低帧率
- 尝试使用getUserMedia帧率约束
- 画布游戏帧率下降
- 用requestAnimationFrame实现一些稳定的帧率
- HTML5 Canvas和JS帧率慢慢下降到0
- 低帧率的JS和CSS动画
- 如何使用javascript获得良好的帧率
- EaselJS性能问题/帧率下降
- Javascript水涟漪效应减慢帧率
- 如何改变精灵帧率
- 动态调整paperjs动画的帧率
- 低帧率嵌套转换元素
- 使用JS和DOM设置多个DIV元素的动画会导致低帧率
- javascript游戏中的异步/可变帧率
- 函数计算函数帧率