О чем этот пример
Управление сценами — ключевой навык для создания сложных игр в Phaser. Этот пример показывает, как запускать и контролировать несколько сцен одновременно, что особенно полезно для разделения игровой логики, интерфейсов и фоновых процессов. Понимание работы сценариев позволит вам создавать более структурированные и поддерживаемые проекты, где каждая сцена отвечает за свою часть функционала.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
var SceneA = {
key: 'SceneA',
preload: function preload() {
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('aqua_ball', 'assets/sprites/aqua_ball.png');
},
init: function init() {
// NOTE: Should yield `SceneB { ... }`, etc.
console.info('SceneA init');
console.log(this.scene.get('SceneB'));
console.log(this.scene.get('SceneC'));
},
create: function create() {
console.info('SceneA started.');
// this.scene.launch('SceneB').launch('SceneC');
this.scene.launch('SceneB');
}
};
var SceneB = {
key: 'SceneB',
init: function init() {
console.info('SceneB init.');
setTimeout(
() => {
console.log(this.scene.get('SceneA'));
console.log(this.scene.get('SceneB'));
console.log(this.scene.get('SceneC'));
},
1000
);
},
create: function create() {
console.info('SceneB started.');
}
};
class SceneC extends Phaser.Scene {
constructor() {
super('SceneC');
}
create() {
console.info('SceneC started.');
this.add.image(160, 120, 'aqua_ball')
}
}
var game = new Phaser.Game({
type: Phaser.AUTO,
parent: 'phaser-example',
scene: [SceneA, SceneB, SceneC]
});
Что такое сцена в Phaser?
Сцена (Scene) — это основной контейнер для игровой логики, ресурсов и объектов. В Phaser можно запускать несколько сцен одновременно, что открывает возможности для параллельного выполнения разных задач.
В примере мы видим три сцены: SceneA, SceneB и SceneC. Они по-разному объявлены, что демонстрирует гибкость подхода.
Объявление сцен: объекты и классы
Phaser позволяет создавать сцены как простые объекты или как ES6-классы, расширяющие Phaser.Scene.
Объектный стиль используется для SceneA и SceneB:
var SceneA = {
key: 'SceneA',
preload: function preload() { ... },
init: function init() { ... },
create: function create() { ... }
};
Классовый стиль для SceneC:
class SceneC extends Phaser.Scene {
constructor() {
super('SceneC');
}
create() {
...
}
}
Ключевое поле key (или передача строки в super()) — это уникальный идентификатор сцены, по которому можно получить доступ к её экземпляру через this.scene.get().
Запуск сцен: `launch` и порядок инициализации
Сцены регистрируются при создании игры, но не запускаются автоматически. Запуск происходит через метод launch().
В create() функции SceneA мы видим:
this.scene.launch('SceneB');
Это запускает SceneB параллельно с SceneA. Обе сцены теперь активны. Метод launch() можно чейнить для запуска нескольких сцен сразу.
Каждая сцена проходит свои жизненные циклы: init(), preload() (если есть), create(). Порядок вызова init() соответствует порядку сцен в массиве конфигурации игры, а create() вызывается только после запуска сцены через launch() или start().
Доступ к экземплярам сцен: метод `get()`
Из любой активной сцены можно получить доступ к экземпляру другой сцены (даже если она не запущена) с помощью метода this.scene.get().
Например, в init() функции SceneA:
console.log(this.scene.get('SceneB'));
Это выведет объект сцены SceneB в консоль. В SceneB, через setTimeout, мы видим проверку доступности всех трёх сцен, что подтверждает их регистрацию в системе Phaser.
Важно: get() возвращает экземпляр сцены, но не гарантирует, что она уже была инициализирована (init) или создана (create).
Практическое применение параллельных сцен
Зачем запускать несколько сцен? Вот типичные сценарии: - **UI/HUD сцена**: отвечает за интерфейс (здоровье, очки), работает поверх игровой. - **Фоновая сцена**: управляет музыкой или фоновыми анимациями. - **Меню и пауза**: отдельная сцена для меню, которую можно запускать и останавливать, не трогая игровой мир.
В примере SceneC загружает спрайт 'aqua_ball', демонстрируя, что сцены могут использовать ресурсы, загруженные в других сценах (если они загружены глобально или через общий загрузчик), но в данном случае SceneC ничего не отобразит, так как спрайт загружается только в SceneA, а SceneC никогда не запускается.
Что попробовать дальше
Управление сценами в Phaser — мощный инструмент для организации кода. Вы можете запускать, останавливать, приостанавливать и переключать сцены, создавая сложные игровые состояния.
**Идеи для экспериментов:**
1. Запустите SceneC из SceneA и разместите шары в разных координатах.
2. Добавьте в SceneB метод update() и попробуйте из него влиять на объекты в SceneA через this.scene.get().
3. Создайте сцену-паузу, которая будет приостанавливать (this.scene.pause()) игровую сцену по нажатию клавиши.
