О чем этот пример
Управление жизненным циклом игры — ключевой навык для создания сложных проектов. В этой статье мы разберем, как корректно уничтожить текущий экземпляр Phaser.Game и создать новый, не перезагружая страницу. Этот подход полезен для реализации перезапуска уровня, смены режима игры или полного сброса состояния приложения. Мы будем использовать пример с кастомным плагином, который демонстрирует чистый способ уничтожения игры и ее последующего восстановления по событию пользователя.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.plugin('RandomNamePlugin', 'assets/loader-tests/RandomNamePlugin.js', true);
}
create ()
{
let plugin = this.plugins.get('RandomNamePlugin');
let names = plugin.getNames(10);
names.push('', 'Click to destroy game instance');
this.add.text(10, 10, names, { font: '16px Courier', fill: '#00ff00' });
this.input.on('pointerdown', function ()
{
this.sys.game.destroy(true);
document.addEventListener('mousedown', function newGame ()
{
game = new Phaser.Game(config);
document.removeEventListener('mousedown', newGame);
});
}, this);
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
let game = new Phaser.Game(config);
Загрузка кастомного плагина
Плагины в Phaser позволяют расширять базовый функционал игры. В данном примере используется плагин RandomNamePlugin, который загружается в методе preload. Ключевой параметр true в методе load.plugin указывает, что плагин должен быть запущен автоматически после загрузки.
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.plugin('RandomNamePlugin', 'assets/loader-tests/RandomNamePlugin.js', true);
Использование плагина и отрисовка интерфейса
В методе create мы получаем экземпляр загруженного плагина с помощью this.plugins.get. Плагин предоставляет метод getNames, который генерирует массив случайных имен. После добавления служебных строк этот массив выводится на экран с помощью this.add.text.
let plugin = this.plugins.get('RandomNamePlugin');
let names = plugin.getNames(10);
names.push('', 'Click to destroy game instance');
this.add.text(10, 10, names, { font: '16px Courier', fill: '#00ff00' });
Уничтожение игры и подготовка перезапуска
Основная логика находится в обработчике клика. При срабатывании события pointerdown вызывается метод this.sys.game.destroy(true). Параметр true указывает, что нужно остановить игровой цикл, отключить все системы Phaser и очистить связанные ресурсы.
this.input.on('pointerdown', function () {
this.sys.game.destroy(true);
}, this);
Создание нового экземпляра игры
После уничтожения игры мы вешаем глобальный обработчик события mousedown на документ. При следующем клике создается новый экземпляр Phaser.Game с исходной конфигурацией, что приводит к полной перезагрузке сцены. Важно удалить обработчик после его срабатывания, чтобы избежать утечек памяти.
document.addEventListener('mousedown', function newGame () {
game = new Phaser.Game(config);
document.removeEventListener('mousedown', newGame);
});
Структура конфигурации игры
Конфиг определяет базовые параметры игры: тип рендерера, контейнер в DOM, размеры холста и главную сцену. Переменная game хранится глобально, чтобы к ней можно было обратиться при пересоздании.
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
let game = new Phaser.Game(config);
Что попробовать дальше
Корректное уничтожение и пересоздание игры позволяет эффективно управлять памятью и состоянием приложения. Для экспериментов попробуйте
- уничтожать игру не по клику, а по таймеру или игровому событию
- передавать в новую игру модифицированный конфиг (например, другие размеры экрана)
- сохранять некоторые данные между перезапусками, используя локальное хранилище браузера
