О чем этот пример
В Phaser сцена (Scene) — это фундаментальный блок организации кода. Она может представлять собой меню, уровень игры или, как в нашем примере, отдельный экран. Умение переключаться между сценами — ключ к созданию структурированных и сложных игровых проектов. Эта статья на практическом примере покажет, как настроить две простые сцены и реализовать мгновенное переключение между ними по клику мыши. Вы освоите базовый паттерн, который ляжет в основу навигации в вашей следующей игре.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
const sceneConfigA = {
key: 'sceneA',
create: createA,
pack: {
files: [
{ type: 'image', key: 'face', url: 'assets/pics/bw-face.png' }
]
}
};
const sceneConfigB = {
key: 'sceneB',
create: createB,
pack: {
files: [
{ type: 'image', key: 'logo', url: 'assets/pics/monika-krawinkel-amberstar-title.png' }
]
}
};
function createA ()
{
this.add.image(400, 300, 'face');
this.input.on('pointerdown', () =>
{
this.input.stopPropagation();
this.scene.switch('sceneB');
});
}
function createB ()
{
this.add.image(400, 300, 'logo');
this.input.on('pointerdown', () =>
{
this.input.stopPropagation();
this.scene.switch('sceneA');
});
}
const gameConfig = {
type: Phaser.CANVAS,
parent: 'phaser-example',
width: 800,
height: 600,
scene: [ sceneConfigA, sceneConfigB ]
};
const game = new Phaser.Game(gameConfig);
Конфигурация сцен: разделяем ресурсы и логику
В Phaser сцена настраивается через объект конфигурации. В примере создано две таких конфигурации: sceneConfigA и sceneConfigB. Ключевое поле key задаёт уникальное имя сцены, по которому мы будем к ней обращаться.
Поле pack позволяет предзагрузить ассеты (изображения, аудио) непосредственно для этой сцены. Это удобно для модульности: ресурсы для меню загружаются с меню, а для уровня — с уровнем.
Функция create, указанная в поле create, будет вызвана автоматически, когда сцена будет создана движком. В ней выполняется начальная настройка.
const sceneConfigA = {
key: 'sceneA',
create: createA,
pack: {
files: [
{ type: 'image', key: 'face', url: 'assets/pics/bw-face.png' }
]
}
};
Создание графики и обработка ввода
Внутри функций createA и createB происходит отрисовка изображения на сцене с помощью метода this.add.image(). Первые два аргумента — координаты X и Y, третий — ключ изображения, объявленный в pack.
Затем настраивается обработчик события клика (pointerdown). Вызов this.input.stopPropagation() предотвращает потенциальное "всплытие" события, если бы элементы ввода были вложены друг в друга (хотя в данном примере это не требуется).
function createA ()
{
this.add.image(400, 300, 'face');
this.input.on('pointerdown', () =>
{
this.input.stopPropagation();
this.scene.switch('sceneB');
});
}
Магия метода `this.scene.switch()`
Сердце примера — вызов this.scene.switch() внутри обработчика клика. Этот метод мгновенно переключает активную сцену.
Важно понимать его поведение:
- Текущая сцена **не уничтожается**. Она переходит в состояние паузы (SCENE.SLEEPING).
- Сцена, на которую происходит переключение, **пробуждается** (SCENE.RUNNING), если она была создана ранее, либо создаётся и запускается.
- Состояние сцены (позиции объектов, переменные) сохраняется. Это идеально для переключения между, например, игровым уровнем и инвентарём.
В нашем примере вызов this.scene.switch('sceneB') из сцены A делает активной сцену B, и наоборот.
this.scene.switch('sceneB');
Инициализация игры с несколькими сценами
Чтобы движок знал о существовании наших сцен, их конфигурации необходимо передать в главную конфигурацию игры (gameConfig) в поле scene. Оно принимает массив. Порядок в массиве имеет значение: первая сцена в списке будет запущена автоматически при старте игры.
const gameConfig = {
type: Phaser.CANVAS,
parent: 'phaser-example',
width: 800,
height: 600,
scene: [ sceneConfigA, sceneConfigB ] // Запустится sceneA
};
const game = new Phaser.Game(gameConfig);
Что попробовать дальше
Метод switch() предоставляет простой и эффективный способ управления несколькими экранами в игре, сохраняя их состояние. Это базовый кирпичик для построения сложной навигации.
**Идеи для экспериментов:**
1. Добавьте третью сцену и создайте "циклический" переключатель между всеми.
2. Загрузите разные звуки в pack каждой сцены и воспроизводите их при переключении.
3. Используйте this.scene.start() вместо switch() и посмотрите, как полностью перезапускается сцена (её состояние сбросится).
