目前我正在开发一款名为“隧道 2”的 js/canvas 小游戏(我很确定它有一个众所周知的旧版本,但我不知道没有)。你可以try the game here .另外,我推荐 chrome。
所以,我用谷歌浏览器开发,它运行良好,即使在我那破旧的机器上也是如此。我得到大约 30 fps。在我同事的笔记本上它产生 >100fps。到目前为止,一切都很好。 safari 似乎也运行良好。
接下来我在 firefox 4 beta 10 上试了一下...我只得到大约 10 fps。但肯定 ff4 不会那么慢,对吧?
我开始调查。这是我的主循环:
// starts the game loop
this.run = function () {
this.draw();
var
t = this,
timeLastTurn,
timeThisTurn = (new Date()).getTime()-1;
var loop = function () {
timeLastTurn = timeThisTurn;
timeThisTurn = (new Date()).getTime();
// dt is the time difference between this turn and the last turn
var dt = timeThisTurn - timeLastTurn;
// player movement etc
t.turn(dt);
// draw game state
var res = t.draw();
// if there's no collision, game over
if (!res.collision)
t.setState(2);
// actually, there's a browser dependent minimum timeout that
// may vary. but even if it's more than 10ms - we don't care.
// game should run at the same speed (though not as smooth)
if (gameState == 1)
timer = window.setTimeout(loop, 5);
// just debug output
debug = dt;
}
// start the main loop
loop();
}
我观察到的:
不出所料,this.draw();
是迄今为止最昂贵的函数,但它只需要几毫秒(实际上大约 5 毫秒),在 chrome 上...... 火狐。远不及 10fps 所需的 >100 毫秒!整个 loop()
调用也不会花费太多,在 firefox 上它只需要不到 10 毫秒!
如果您调查dt
,就可以看出差异。它应该在 time-loop()-takes+5ms 超时左右(或者浏览器的最小超时值是什么)。
但在 ff4 上该值更接近 180 毫秒,也就是下一个超时事件将在 170 毫秒而不是 5 毫秒后触发!如果你玩的时间长一点,单帧会上升到 800 毫秒(当然是 gc),然后又回到 180 毫秒。
有人知道罪魁祸首是什么吗?
是 GC 的错吗?一方面,我不认为我创建了太多短暂的变量,嘿,每次 150 毫秒!?但当然可以。有没有简单的方法来检查这个? chrome 分析器记录 gc 时间(大约 0.10%),但 firebug 分析器没有。
同样有趣的是:启用 Firebug 后游戏运行速度更快(~5fps)。
补充。信息:使用 setInterval 而不是 setTimeout 不应该也不会改变任何东西。
最佳答案
我可以确认它不适用于 FF 3.6.13 OS X。
我在开发 Snake JS我发现 setInterval
行为有所不同。你真的应该看看这个:
var timer = setInterval(fn, 500)
// ...
timer = setInterval(fn, 500)
// Since I didn't use clearInterval() I now have two timers running in FF.
我看到你没有使用 setInterval
,但也许它与 setTimeout
类似?
关于javascript - html5 游戏与 Canvas ,在 firefox 上的性能问题 (4),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4821312/