О чем этот пример
В Phaser управление порядком и видимостью сцен — мощный инструмент для создания сложных интерфейсов, меню или многослойных игровых миров. Эта статья разберет пример, где одна сцена отправляется на задний план по клику мыши. Вы научитесь контролировать стек сцен и динамически менять их визуальный приоритет, что полезно для пауз, диалоговых окон или смены режимов игры.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class DemoA extends Phaser.Scene
{
constructor ()
{
super({ key: 'demoA', active: true });
}
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('picA', 'assets/pics/lance-overdose-loader-eye.png');
}
create ()
{
this.add.image(400, 300, 'picA');
this.input.once('pointerdown', function ()
{
this.scene.sendToBack();
}, this);
}
}
class DemoB extends Phaser.Scene
{
constructor ()
{
super({ key: 'demoB', active: true });
}
preload ()
{
// this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('picB', 'assets/pics/sukasuka-chtholly.png');
}
create ()
{
this.add.image(400, 500, 'picB');
}
}
class DemoC extends Phaser.Scene
{
constructor ()
{
super({ key: 'demoC', active: true });
}
preload ()
{
// this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('picC', 'assets/pics/titan-mech.png');
}
create ()
{
this.add.image(300, 300, 'picC');
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
scene: [ DemoB, DemoC, DemoA ]
};
const game = new Phaser.Game(config);
Что делает пример?
В примере создаются три независимые сцены (DemoA, DemoB, DemoC), каждая из которых загружает и отображает свою картинку. Изначально сцены активны одновременно и отрисовываются в порядке, указанном в массиве конфигурации игры: [ DemoB, DemoC, DemoA ]. Это значит, что DemoA будет поверх всех.
По клику мыши на сцене DemoA вызывается метод this.scene.sendToBack(), который перемещает эту сцену в самый низ стека отрисовки. Визуально это приводит к тому, что картинка из DemoA "проваливается" под изображения из двух других сцен.
Стек сцен и порядок отрисовки
Phaser управляет сценами как стеком. Сцена, добавленная последней или находящаяся выше в списке конфигурации, отрисовывается поверх остальных. Ключевой параметр active: true в конструкторе каждой сцены позволяет им запускаться и работать одновременно.
Посмотрим на порядок в конфиге:
scene: [ DemoB, DemoC, DemoA ]
Это означает, что DemoB будет отрисована первой (самый нижний слой), затем DemoC поверх неё, и, наконец, DemoA — поверх всех. Именно поэтому в начале работы примера картинка из DemoA перекрывает остальные.
Ключевой метод: `scene.sendToBack()`
Метод sendToBack() — часть API менеджера сцен (this.scene). Он перемещает вызывающую сцену в самый низ стека отрисовки. В нашем примере он привязан к событию клика.
Код в сцене DemoA:
this.input.once('pointerdown', function () {
this.scene.sendToBack();
}, this);
Здесь this.input.once регистрирует обработчик на одно срабатывание события клика (pointerdown). При срабатывании вызывается this.scene.sendToBack(), и сцена DemoA мгновенно отправляется за DemoB и DemoC. Важно передать контекст this как третий аргумент, чтобы внутри функции-колбэка this ссылалось на экземпляр сцены, а не на глобальный объект.
Структура кода: независимые сцены
Каждая сцена — это отдельный класс, расширяющий Phaser.Scene. Они не знают друг о друге, что делает архитектуру чистой и модульной.
Пример объявления сцены DemoA:
class DemoA extends Phaser.Scene
{
constructor ()
{
super({ key: 'demoA', active: true });
}
// ... preload и create ...
}
Ключ (key) — уникальный идентификатор сцены. Параметр active: true в конструкторе позволяет сцене запуститься сразу вместе с игрой. Методы preload и create стандартны: в preload загружается изображение по заданному URL, а в create оно добавляется на сцену с помощью this.add.image(x, y, key).
Что попробовать дальше
Метод sendToBack() — простой, но эффективный способ динамического управления визуальными слоями в игре. Вы можете использовать этот подход для скрытия игрового мира под меню паузы, переключения между режимами (например, карта и бой) или создания сложных UI-композиций. Для экспериментов попробуйте связать вызов метода с другими событиями (таймер, коллизия), использовать парный метод bringToTop() или управлять сценами по их ключам через this.scene.moveDown('key').
