В настоящее время я работаю над небольшой игрой js / canvas под названием «Туннель 2» (я уверен, что есть хорошо известная летняя версия этого, но я не знаю ни одной). Вы можете попробовать игру здесь . Кроме того, я бы порекомендовал хром.
Итак, я разработал в Google Chrome, и он отлично работает, даже на моей дрянной старой машине. я получаю около 30 кадров в секунду. на моем ноутбуке коллег он дает> 100 кадров в секунду. Все идет нормально. Сафари, кажется, тоже хорошо работает.
затем я попробовал это на Firefox 4 бета 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 . нигде около> 100 мс это потребовалось бы для скудных 10fps! весь вызов loop()
также занимает не намного больше, в Firefox - менее 10 мс!
разницу можно увидеть, если вы исследуете dt
. оно должно быть около time-loop () - время ожидания + 5 мс (или любое другое минимальное время ожидания браузера).
но на ff4 значение ближе к 180 мс, то есть следующее событие тайм-аута срабатывает через 170 мс вместо 5 мс! если вы играете немного дольше, он достигает ~ 800 мс для одного кадра (gc, конечно), а затем возвращается к 180 мс.
Кто-нибудь знает, каким может быть виновник?
виноват ли ГК? С одной стороны, я не думаю, что я создаю слишком много недолговечных переменных, и эй, 150 мс каждый раз !? но, конечно, это может быть. Есть ли простой способ проверить это? Профилировщик chrome регистрирует время gc (около 0.10%), а профилировщик firebug - нет.
также интересно: игра работает быстрее (~ 5 кадров в секунду) с включенным firebug.
добавить. информация: использование setInterval вместо setTimeout не должно и ничего не меняет.