Уничтожение экземпляра игры

В библиотеке Phaser создание игры происходит через конструктор Phaser.Game. Экземпляр игры хранит все сцены, системы рендеринга, обработку ввода и таймеры. Для корректного управления ресурсами и предотвращения утечек памяти важно понимать процесс уничтожения экземпляра игры.

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    scene: [MainScene],
};

const game = new Phaser.Game(config);

После завершения использования игры её экземпляр необходимо корректно уничтожить с помощью метода game.destroy(). Этот метод освобождает все ресурсы, очищает сцены и DOM-элементы, создаваемые Phaser, и предотвращает дальнейшее выполнение игрового цикла.

game.destroy(true); // true — удаляет Canvas и слушатели событий

Параметр removeCanvas в методе destroy отвечает за удаление HTML-элемента <canvas> из DOM. Без него canvas остаётся в документе, что может привести к визуальному мусору и ненужной нагрузке на рендеринг.

Освобождение ресурсов

При уничтожении экземпляра игры важно учитывать несколько типов ресурсов:

  1. Графические объекты: текстуры, спрайты, тайлмапы.
  2. Аудио: загруженные звуки и музыкальные дорожки.
  3. Сцены: объекты сцен и их жизненный цикл.
  4. Таймеры и события: интервалы, таймеры, слушатели ввода.

Метод destroy автоматически очищает большинство ресурсов, однако для некоторых объектов может понадобиться явная очистка:

this.textures.remove('spriteKey');
this.cache.audio.remove('soundKey');

Это особенно важно при динамической загрузке ассетов во время игры, когда старые ресурсы больше не нужны.

Управление сценами при уничтожении игры

Phaser поддерживает несколько сцен одновременно. При вызове game.destroy() все активные и приостановленные сцены уничтожаются. Однако каждая сцена имеет свой метод shutdown и destroy, который можно переопределить для дополнительной очистки:

class MainScene extends Phaser.Scene {
    constructor() {
        super({ key: 'MainScene' });
    }

    create() {
        this.sprite = this.add.sprite(400, 300, 'player');
    }

    shutdown() {
        this.sprite.destroy(); // явное уничтожение объектов сцены
    }
}

shutdown вызывается перед удалением сцены, а destroy — после завершения всех операций сцены. Это позволяет корректно управлять объектами, которые Phaser не удаляет автоматически.

Прерывание игрового цикла

Экземпляр игры постоянно запускает игровой цикл, обновляя сцены и обрабатывая события. После вызова destroy игровой цикл останавливается, что предотвращает выполнение методов update на уничтоженных сценах. В противном случае попытка доступа к уже уничтоженным объектам может вызвать ошибки.

game.destroy();
console.log(game.isBooted); // false

Свойство isBooted указывает, завершена ли инициализация и работает ли игровой цикл. После вызова destroy оно становится false.

Практические рекомендации

  • Использовать game.destroy(true) при полной очистке игры и необходимости удалить canvas.
  • Явно уничтожать динамически созданные ресурсы внутри сцен.
  • Следить за таймерами, событиями и анимациями, которые могут продолжать работать после удаления сцены.
  • Для веб-приложений, где Phaser используется многократно, каждый новый экземпляр должен создаваться после полного уничтожения предыдущего, чтобы избежать утечек памяти.

Особенности работы с DOM

Phaser создаёт HTML-элемент <canvas> для рендеринга игры. Метод destroy с параметром true удаляет canvas и все связанные слушатели. Если canvas не удалён, он остаётся в DOM, а WebGL/Canvas контекст продолжает занимать видеопамять, что критично при многократной загрузке и уничтожении игры.

// Альтернатива: перенос canvas в другой контейнер
game.canvas.parentNode.removeChild(game.canvas);
game.destroy();

Итоговая схема уничтожения игры

  1. Завершение сцен (shutdown и destroy для каждой сцены).
  2. Очистка ресурсов (текстуры, аудио, кэш).
  3. Остановка игрового цикла (game.destroy(true)).
  4. Удаление DOM-элементов (canvas).
  5. Очистка сторонних слушателей событий, таймеров и анимаций.

Следование этим шагам обеспечивает корректное уничтожение экземпляра Phaser, предотвращает утечки памяти и позволяет безопасно создавать новые игры на той же странице.