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 в живой функции

Другие вопросы по тегам