【问题标题】:asynchronous / variable framerate in javascript gamejavascript游戏中的异步/可变帧率
【发布时间】:2013-03-07 00:31:48
【问题描述】:

这可能是一个愚蠢的/以前回答过的问题,但它一直困扰着我和我的朋友一段时间,我一直无法找到一个好的答案。

现在,我让我所有的 JS Canvas 游戏都在滴答声中运行。例如:

function tick(){
//calculate character position
//clear canvas
//draw sprites to canvas
if(gameOn == true)
    t = setTimeout(tick(), timeout)
}

这对于高端系统上的 CPU-cheep 游戏效果很好,但是当我尝试在每个刻度上多画一点时,它开始以慢动作运行。所以我的问题是,如何在允许可变帧速率的同时保持 x、y 位置和命中检测计算全速进行?

旁注:我曾尝试使用 requestAnimationFrame API,但老实说,它有点令人困惑(并不是所有关于它的好教程),虽然它可能会加快您的处理速度,但它并不能完全解决问题。

谢谢大家——感谢任何帮助。

【问题讨论】:

    标签: javascript html5-canvas frame-rate 2d-games


    【解决方案1】:

    RequestAnimationFrame 带来了的不同。这可能是您问题的解决方案。您还可以做两件事:设置第二个刻度系统来处理它的模型端,例如命中检测。一个很好的例子是 PhysiJS 是如何做到的。它更进一步,并使用了一些新浏览器的一项功能,称为网络工作者。它允许您使用第二个 CPU 内核。 John Resig has a good tutorial。但请注意,它很复杂,没有得到很好的支持(因此有问题,它往往会崩溃很多)。

    真的,请求动画帧很简单,只要几行,一旦你设置了你就可以忘记它。它不应该更改您现有的任何代码。理解代码的作用有点挑战,但您几乎可以为那里的示例剪切和替换您的 setTimeout 代码。如果你问我,setTimeout 也一样复杂!它们几乎做同样的事情,除了 setTimeout 有延迟时间,而 requestAnimationFrame 没有 - 它只是在准备好时调用您的函数,而不是在设定的时间段之后。

    【讨论】:

      【解决方案2】:

      您实际上并没有使用刻度线。发生的事情是您一遍又一遍地反复拨打tick()。您需要删除() 并留下setTimeout(tick,timeout); 我个人喜欢使用arguments.callee 来明确声明函数调用自身(从而消除知道函数名称的依赖关系)。

      话虽如此,我在实现可变帧速率时喜欢做的是尽可能简化底层引擎。例如,为了让一个球在墙上反弹,我检查从球的前一个位置到下一个位置的线是否撞到墙上,如果是,何时撞到。

      话虽如此,您需要小心,因为某些浏览器会在打开 contaxt 菜单(或任何其他菜单)时停止所有 JavaScript 执行,因此您最终可能会在两个“帧”之间出现几秒甚至几分钟的间隙.我个人认为,在大多数情况下,基于帧的计时是要走的路。

      【讨论】:

        【解决方案3】:

        正如科林克所说。 setTimeout 看起来像一个错误。假设这只是一个错字而不是真正的错误,我会说它不太可能是动画本身(即 DOM 更新)真正减慢了您的代码。

        多一点是多少?我在 1.2GHz Atom 上网本上的 VMWare 中的 IE7 上一次在屏幕上动画了数百个元素(我在最慢的机器上拥有最慢的浏览器,VMWare 是因为我使用 Linux)。

        根据我的经验,如果未正确执行命中检测,当您制作动画的元素数量增加时,速度最慢。这是因为一个简单的实现本质上是指数的(它会尝试做n^n 比较)。解决这个问题的方法是过滤掉比较以避免不必要的比较。

        在游戏引擎中执行此操作的最常见方法之一(无论使用何种语言)是将您的世界地图分割成一组更大的网格。然后,您只需对同一网格中的项目进行命中检测(如果您想要更准确,还可以检测相邻的网格)。这大大减少了您需要进行的比较次数,尤其是在您有很多字符的情况下。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-06-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多