目前我正在开发一个名为“隧道2”的小型js/canvas游戏(我相信已经有一个广为人知的版本,但我不知道)。你可以在这里尝试游戏。另外,我建议使用chrome浏览器。
所以,我在google chrome中开发,它运行良好,即使在我的旧机器上也是如此。我获得了约30帧每秒的效果。在我的同事笔记本电脑上,可以达到100多帧每秒。到目前为止,一切都很好。safari看起来也很不错。
接下来,我尝试了firefox 4 beta 10...然后我只能获得大约10帧每秒的效果。但是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上也是如此……在Firefox上也是如此。远远没有10fps所需的100毫秒!整个loop()
调用所需的时间也不多,Firefox上不到10毫秒!
如果您调查dt
,就可以看到差异。它应该约为time-loop()-takes+5ms timeout(或浏览器最小timeout值)。
但是在ff4上,该值更接近180毫秒,即下一个timeout事件在170毫秒而不是5毫秒后触发!如果您玩得更久一些,单帧的时间会增加到约800毫秒(肯定是gc),然后又回到了180毫秒。
有人有什么想法可以解决问题吗?
垃圾回收器是否有责任?一方面,我认为我没有创建太多短期变量,而且每次都要花费150毫秒吗?但当然可能是。有没有一种简单的方法来检查这个?Chrome分析器记录gc时间(约为0.10%),但Firebug分析器没有。
另外有趣的是,启用Firebug后游戏运行得更快(约5fps)。
附加信息:使用setInterval而不是setTimeout不应该也不会改变任何内容。
ctx.arc(75,75,50,0,Math.PI*2,true);
,请查看第270行。.arc方法需要6个参数而不是5个。 - Raynos@raynos:是的,我试过了,但是我没能找到任何东西。感谢ctx.arc的bug(尽管没有那个也可以很好地工作)。
@fazo:那么在Chrome中播放它,你将获得超过100fps :) - stefs