Phaser предоставляет мощную систему для работы с
множественными сценами, позволяя создавать сложные
игровые архитектуры с разделением логики, интерфейса и фоновых
процессов. Каждая сцена в Phaser — это самостоятельный объект с
собственным жизненным циклом, набором игровых объектов и обработчиков
событий. Управление сценами осуществляется через Scene
Manager, доступный через this.scene внутри любой
сцены.
Основные методы управления сценами:
this.scene.start(key, data) —
останавливает текущую сцену и запускает указанную сцену
key. Параметр data позволяет передать объект с
данными.this.scene.launch(key, data) —
запускает сцену поверх текущей, не останавливая её. Часто используется
для интерфейсных слоёв, таких как HUD или меню.this.scene.stop(key) — останавливает
указанную сцену.this.scene.pause(key) /
this.scene.resume(key) — приостанавливает и
возобновляет выполнение сцены, сохраняя её состояние.this.scene.switch(key) — сочетает
остановку текущей сцены и запуск другой, аналогично start,
но оставляет объекты памяти сцены для возможного повторного
использования.Передача информации между сценами возможна через параметры запуска или глобальные объекты состояния.
При использовании scene.start или
scene.launch можно передать объект data:
this.scene.start('GameScene', { score: 100, playerName: 'Alice' });
В целевой сцене доступ к данным осуществляется через метод
init:
class GameScene extends Phaser.Scene {
init(data) {
this.score = data.score;
this.playerName = data.playerName;
}
}
Метод init вызывается до создания объектов
сцены, что позволяет использовать данные для начальной
настройки.
Для сложных проектов удобно использовать объект-синглтон, доступный из всех сцен:
window.gameState = {
score: 0,
level: 1,
inventory: []
};
Из любой сцены можно изменять и читать данные:
window.gameState.score += 10;
Этот подход позволяет хранить прогресс, настройки пользователя и общие ресурсы без передачи их через параметры каждой сцены.
Phaser предоставляет систему событий, которая
облегчает коммуникацию между сценами. Основной инструмент —
Event Emitter, встроенный в Scene и
Game объекты.
Пример отправки события из одной сцены:
this.scene.get('UIScene').events.emit('updateScore', this.score);
В сцене-получателе:
class UIScene extends Phaser.Scene {
create() {
this.events.on('updateScore', (score) => {
this.scoreText.setText(`Score: ${score}`);
});
}
}
События позволяют создавать асинхронное взаимодействие, не привязывая сцены друг к другу напрямую, что снижает связанность кода.
Сцены можно комбинировать по принципу слоёв. Например:
GameScene с логикой игры.UIScene с элементами HUD.BackgroundScene с анимацией или
партиклами.Для запуска нескольких сцен одновременно используют
launch:
this.scene.launch('UIScene');
this.scene.launch('BackgroundScene');
Каждая сцена обновляется независимо, но можно синхронизировать состояния через события или глобальные данные.
Phaser поддерживает один общий пул ресурсов
(this.load), доступный из всех сцен. Это позволяет
загружать текстуры, аудио и шрифты в Preloader Scene и
использовать их в других сценах без повторной загрузки:
class PreloaderScene extends Phaser.Scene {
preload() {
this.load.image('player', 'assets/player.png');
this.load.audio('bgMusic', 'assets/music.mp3');
}
create() {
this.scene.start('GameScene');
}
}
В GameScene достаточно обратиться к ресурсам по
ключу:
this.add.sprite(100, 100, 'player');
this.sound.play('bgMusic');
В крупных проектах сцены могут взаимодействовать по цепочке:
init
для настройки уровня.pause, resume и switch.Такой подход позволяет отделить логику игры от интерфейса, а фоновые процессы — от активного геймплея, обеспечивая чистую и масштабируемую архитектуру.
// Основная игровая сцена
class GameScene extends Phaser.Scene {
create() {
this.score = 0;
this.scene.launch('UIScene');
this.events.on('collectItem', () => {
this.score += 10;
this.scene.get('UIScene').events.emit('updateScore', this.score);
});
}
}
// Сцена интерфейса
class UIScene extends Phaser.Scene {
create() {
this.scoreText = this.add.text(10, 10, 'Score: 0', { fontSize: '20px', fill: '#fff' });
this.events.on('updateScore', (score) => {
this.scoreText.setText(`Score: ${score}`);
});
}
}
// Инициализация игры
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
scene: [PreloaderScene, GameScene, UIScene]
};
const game = new Phaser.Game(config);
Такое разделение позволяет поддерживать чистую структуру, масштабировать проект и гибко управлять различными аспектами игры без взаимных блокировок между сценами.