Haxe неактивная вкладка браузера останавливается полностью
Я разрабатываю браузерную игру с haxe. Пока у меня есть вкладка браузера в качестве активной вкладки, все работает так, как задумано и гладко, но как только я переключаю вкладку (независимо от того, использую ли я Chrome или Firefox), она перестает работать полностью и не отправляет никаких сердцебиение вообще на мой сервер.
Мне известно, что неактивные вкладки замедляются в производительности, и я также знаю, что неактивные вкладки не могут загружать ресурсы. (Моя игра не делает этого).
Я хочу, чтобы моя игра продолжалась, пока она неактивна, и, что более важно, я хочу, чтобы она посылала пульс на сервер.
Есть ли способ, которым я могу обеспечить это?
Я использую Kha и Haxe, я пробовал собственный haxe-планировщик для биения и kha-планировщика, оба они не работают, будучи неактивными.
2 ответа
Хорошо, я нашел решение. SystemImpl из kha запрашивает requestAnimationFrame и проверяет, является ли он нулевым для каждой отметки времени.
var window: Dynamic = Browser.window;
if (requestAnimationFrame == null) window.setTimeout(animate, 1000.0 / 60.0);
else requestAnimationFrame(animate);
На неактивной вкладке requestAnimationFrame не имеет значение null, но не вызывает функцию animate. Я добавил статическое значение bool isFocused, которое изменяется каждый раз, когда браузер закрывает или открывает это окно.
Чтобы исправить это, я временно изменил этот небольшой фрагмент на:
var window = Browser.window;
window.onfocus = function(){isFocused = true;}
window.onblur = function()
{
window.setTimeout(animate, 1000.0 / 60.0);
isFocused = false;
}
if (requestAnimationFrame == null || !isFocused) window.setTimeout(animate, 1000.0 / 60.0);
else requestAnimationFrame(animate);
Таким образом, я проверяю, является ли текущее окно активным, и использую гораздо более плавный requestAnimationFrame, а если нет, то использую setTimeout. Методы обратного вызова устанавливают целевое значение. Значение Blur Callback также гарантирует, что функция animate всегда вызывается в размытом виде.
Я собираюсь представить это решение в ближайшие 1 или 2 недели, чтобы ограбить, может быть, он рассматривает реализацию
Вы уже нашли это, но я думаю window.Top
должно быть window.top
,
Такая вещь выдала бы ошибку, если бы вы не использовали :Dynamic
, Окно - это типизированный объект, и вы получаете хорошие ошибки, что является хорошей чертой строго типизированного языка. requestAnimationFrame
это глобальная функция для окна, поэтому этот фрагмент работает без динамической аннотации.
var window = Browser.window;
if (window.requestAnimationFrame == null || window.top != window.self) window.setTimeout(animate, 1000.0 / 60.0);
else window.requestAnimationFrame(animate);
Вы также упоминаете, что проверка window.top != window.self
проверяет, активно ли окно. Это не правда, он проверяет, работает ли окно в (i) кадре. Кроме того, вы используете эту проверку только один раз (и только когда requestAnimationFrame не поддерживается, поэтому, если это не так в первый раз, вы никогда не будете получать обновления.
Вы могли бы использовать !Browser.document.hidden
свойство, которое очень хорошо поддерживается https://caniuse.com/
var window = Browser.window;
if (window.requestAnimationFrame == null) window.setTimeout(animate, 1000.0 / 60.0);
else window.requestAnimationFrame(animate);
Я бы предложил использовать этот фрагмент. И использовать if (Browser.document.hidden) return
в живой функции