JavaScript является однопоточным и работает (в действительности) в потоке GUI во всех распространенных средах браузера.Когда вы используете JavaScript, пользовательский интерфейс браузера не обновляется до тех пор, пока не завершится работа JavaScript.
Вы используете цикл while
, который никогда не завершится, и поэтому пользовательский интерфейс никогда не будет обновляться.Чтобы это исправить, вам нужно немного реструктурировать: визуализировать кадр, а затем сообщить браузеру, что вы хотите визуализировать другой кадр в ближайшее время;он может обновлять пользовательский интерфейс и выполнять другие действия, связанные с просмотром, а затем может возвращать вас для визуализации другого кадра.
Реализация
Существует новая экспериментальная функция с именем requestAnimationFrame
это может сделать это.Поскольку он все еще экспериментален, для его использования необходимо проверить его версии для браузера или, если он вообще не доступен, предоставить запасной вариант.Вот некоторые из названий версий для браузера:
mozRequestAnimationFrame
для Gecko (Firefox) webkitRequestAnimationFrame
для WebKit (Chrome и Safari) msRequestAnimationFrame
для Trident (Internet Explorer)
Так что, если доступен префикс requestAnimationFrame
, используйте его.Если это не доступно, но с префиксом, используйте это.Если ничего из этого не работает, вы можете использовать запасной вариант:
function fallbackRequestAnimationFrame(func) {
setTimeout(func, 10); // Schedule func to be run in 10 milliseconds.
}
Вот слегка измененная версия кода , найденная в MDN :
var myRequestAnimationFrame =
window.requestAnimationFrame
|| window.mozRequestAnimationFrame
|| window.webkitRequestAnimationFrame
|| window.msRequestAnimationFrame
|| fallbackRequestAnimationFrame;
Один разВы выяснили, какую функцию requestAnimationFrame
вы можете использовать, вы можете изменить свой игровой цикл (который, кажется, не функция gameLoop
, в которой нет циклов, а скорее цикл while
), чтобы он выглядел следующим образом:
function runFrame() {
switch(state) {
// state handling code
}
if(state != State.EXIT) {
myRequestAnimationFrame(runFrame);
}
}
Затем запустите:
runFrame();