О чем этот пример
Управление несколькими сценами — одна из ключевых концепций Phaser 3, которая позволяет организовать сложную игровую логику, разделить интерфейс и геймплей или реализовать систему уровней. В этой статье на конкретном примере мы разберем, как создавать независимые экземпляры сцен и запускать их параллельно. Этот подход полезен для создания загрузочных экранов, меню, которые остаются поверх игры, или разделения логики на модули.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
const demo = new Phaser.Scene('Demo');
demo.preload = function () {
this.load.image('face', 'assets/pics/bw-face.png');
};
demo.create = function () {
console.log(this.sys.settings.key, 'is alive');
this.add.image(400, 300, 'face');
this.scene.launch('Test');
};
const test = new Phaser.Scene('Test');
test.preload = function () {
this.load.image('barbarian', 'assets/pics/barbarian-loading.png');
};
test.create = function () {
console.log(this.sys.settings.key, 'is alive');
this.add.image(400, 300, 'barbarian').setScale(0.5);
}
const config = {
type: Phaser.CANVAS,
parent: 'phaser-example',
width: 800,
height: 600,
scene: [ demo, test ]
};
const game = new Phaser.Game(config);
Создание сцен через конструктор `new Phaser.Scene`
В отличие от распространённого подхода с передачей классов в конфигурацию игры, данный пример демонстрирует создание сцен как объектов. Каждая сцена создается с помощью конструктора new Phaser.Scene, и ей сразу присваивается уникальный строковый ключ. Этот ключ позже используется для управления сценой.
const demo = new Phaser.Scene('Demo');
const test = new Phaser.Scene('Test');
После создания объектам сцен напрямую присваиваются методы жизненного цикла, такие как preload и create. Это классический подход для быстрого прототипирования или случаев, когда вы хотите явно контролировать экземпляры.
Настройка и жизненный цикл сцены Demo
Первая сцена, Demo, загружает одно изображение и, после создания, запускает вторую сцену.
В методе preload используется this.load.image для загрузки ассета. Важно помнить, что this внутри этих методов ссылается на саму сцену, предоставляя доступ к её системам.
demo.preload = function () {
this.load.image('face', 'assets/pics/bw-face.png');
};
В методе create сцена выводит в консоль свой ключ (доступный через this.sys.settings.key) и добавляет загруженное изображение в центр экрана. Затем с помощью this.scene.launch('Test') она запускает вторую сцену.
demo.create = function () {
console.log(this.sys.settings.key, 'is alive');
this.add.image(400, 300, 'face');
this.scene.launch('Test');
};
Метод launch запускает сцену с ключом 'Test', не останавливая текущую. Обе сцены теперь будут выполняться параллельно.
Параллельная работа сцены Test
Вторая сцена, Test, создается и настраивается аналогичным образом. Она загружает своё собственное изображение и выводит его с измененным масштабом.
const test = new Phaser.Scene('Test');
test.preload = function () {
this.load.image('barbarian', 'assets/pics/barbarian-loading.png');
};
test.create = function () {
console.log(this.sys.settings.key, 'is alive');
this.add.image(400, 300, 'barbarian').setScale(0.5);
}
Обратите внимание, что сцены загружают ресурсы независимо друг от друга. Ресурсы, загруженные в сцене Demo, не доступны в сцене Test и наоборот, если не используется общий кэш. После вызова this.scene.launch('Test') из сцены Demo, Phaser автоматически вызовет методы preload и create для сцены Test. Обе сцены активны и отрисовываются: изображение из Test будет нарисовано поверх изображения из Demo, так как она была запущена позже.
Конфигурация игры и регистрация сцен
Чтобы сцены стали частью игры, их необходимо передать в конфигурацию игры в свойстве scene. В данном случае передается массив созданных экземпляров [demo, test].
const config = {
type: Phaser.CANVAS,
parent: 'phaser-example',
width: 800,
height: 600,
scene: [ demo, test ] // Экземпляры сцен передаются напрямую
};
const game = new Phaser.Game(config);
Phaser запускает первую сцену из массива (demo) автоматически. Порядок в массиве определяет порядок вызова некоторых системных событий, но не порядок отрисовки — он зависит от порядка запуска сцен и их настроек. Важно: сцена, запущенная первой (в данном случае demo), считается активной, и её методы обновления (update) будут вызываться.
Что попробовать дальше
Использование экземпляров сцен, созданных через new Phaser.Scene(), даёт прямой контроль над их жизненным циклом и позволяет гибко управлять их запуском и остановкой. Для экспериментов попробуйте: изменить порядок сцен в массиве конфигурации; запустить сцену Test с задержкой, используя this.time.delayedCall; или управлять сценами через меню, останавливая одну и запуская другую с помощью методов this.scene.stop() и this.scene.start().
