这可能是一个愚蠢的/以前回答过的问题,但这段时间一直困扰着我和我的朋友,我一直无法找到一个好的答案。
现在,我让我所有的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,但老实说它有点令人困惑(并不是所有很多好的教程),虽然它可能会加快你的处理速度,但它并没有完全解决问题。
谢谢你们 - 感谢任何帮助。
答案 0 :(得分:0)
RequestAnimationFrame会产生大差异。它可能是您的问题的解决方案。还有两件事你可以做:设置第二个滴答系统来处理它的模型侧,例如:命中检测。一个很好的例子是PhysiJS如何做到这一点。它更进了一步,并使用了一些称为web worker的新浏览器的功能。它允许您使用第二个CPU核心。 John Resig has a good tutorial。但要注意,它很复杂,支持得不是很好(因此马车很多,它往往会崩溃很多)。
真的,请求动画框架非常简单,它只是几行,一旦你设置你就可以忘记它。它不应该更改任何现有代码。理解代码的作用是一个很大的挑战,但你可以为那里的例子切换和替换你的setTimeout代码。如果你问我,setTimeout就像复杂一样!它们几乎完全相同,除了setTimeout有一个延迟时间,而requestAnimationFrame没有 - 它只是在它准备好时调用你的函数,而不是在设定的一段时间后调用。
答案 1 :(得分:0)
你实际上并没有使用滴答声。令人沮丧的是,您反复拨打tick()
一遍又一遍。您需要删除()
并离开setTimeout(tick,timeout);
我个人喜欢使用arguments.callee
来明确声明函数调用自身(从而消除了知道函数名称的依赖性)。 / p>
话虽如此,我在实现可变帧速率时喜欢做的是尽可能简化底层引擎。例如,为了让一个球在墙上反弹,我会检查从球的前一个位置到下一个位置的线是否会撞到墙上,如果是的话,是什么时候。
话虽如此,你需要小心,因为有些浏览器会在打开一个文件菜单(或任何其他菜单)时暂停所有JavaScript执行,所以你最终可能会在两个“帧”之间留出几秒甚至几分钟的间隔。就个人而言,我认为在大多数情况下,基于帧的计时是最佳选择。
答案 2 :(得分:0)
正如Kolink所说。 setTimeout
看起来像个bug。假设它只是一个拼写错误,实际上并不是一个错误我会说它不太可能是动画本身(也就是说,DOM更新),这真的会减慢你的代码。
多少多少钱?我已经在屏幕上动画了数百个元素,在VMWare上的IE7上使用1.2GHz Atom上网本获得了良好的效果(我在最慢的机器上使用最慢的浏览器,VMWare是因为我使用的是Linux)。
根据我的经验,如果没有正确完成,点击检测会在您动画的元素数量增加时导致最慢的速度。那是因为天真的实现本质上是指数式的(它将尝试进行n^n
比较)。解决这个问题的方法是过滤掉比较以避免不必要的比较。
在游戏引擎(无论语言)中执行此操作的最常见方法之一是将您的世界地图划分为更大的网格集。然后,您只对同一网格中的项目进行点击检测(如果您想要更准确,则选择相邻的网格)。这大大减少了你需要进行的比较次数,特别是如果你有很多字符。