О чем этот пример
В Phaser игра может состоять из нескольких сцен, которые рендерятся друг поверх друга. Иногда возникает необходимость динамически изменить порядок их отображения, например, чтобы показать всплывающее окно поверх игрового мира. В этой статье мы разберем простой, но мощный метод `bringToTop`, который позволяет переместить сцену на самый верх стека рендеринга. Понимание работы со стеком сцен и методов управления их порядком — ключ к созданию сложных интерфейсов и многослойных игровых миров, где элементы должны появляться и скрываться по требованию игрока.
Версия 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.bringToTop();
}, 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: [ DemoA, DemoB, DemoC ]
};
const game = new Phaser.Game(config);
Что такое стек сцен и почему важен порядок?
В примере инициализируются три сцены: DemoA, DemoB и DemoC. Они добавлены в массив scene конфигурации игры в таком же порядке. Phaser рендерит сцены последовательно, начиная с первой в массиве и заканчивая последней. Это значит, что сцена, указанная последней (DemoC), будет отрисована поверх всех предыдущих.
Представьте себе стопку прозрачных слайдов: изображение на нижнем слайде будет перекрыто изображениями на верхних. Порядок сцен в массиве определяет их изначальное положение в этой стопке. Метод bringToTop позволяет взять любой слайд (сцену) и переместить его на самый верх.
Анализ кода: инициализация и структура
Давайте посмотрим на конфигурацию игры и конструкторы сцен. Все три сцены создаются с флагом active: true, что означает их одновременную активность и рендеринг.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
scene: [ DemoA, DemoB, DemoC ] // Исходный порядок рендеринга
};
constructor ()
{
super({ key: 'demoA', active: true });
}
Сцены загружают разные изображения и размещают их в своих методах create. Изначальный порядок отрисовки будет: DemoA (фон), поверх него DemoB, и на самом верху — DemoC.
Ключевой триггер: обработка ввода
Вся магия происходит в сцене DemoA. В её методе create мы навешиваем одноразовый обработчик события клика (pointerdown).
create ()
{
this.add.image(400, 300, 'picA');
this.input.once('pointerdown', function ()
{
this.scene.bringToTop();
}, this);
}
Использование this.input.once гарантирует, что функция выполнится только при первом клике. Важно передать контекст this третьим аргументом, чтобы внутри функции-обработчика this ссылался на экземпляр сцены DemoA, а не на глобальный объект. Это позволяет нам вызвать this.scene.bringToTop().
Как работает метод bringToTop
Метод bringToTop() вызывается для менеджера сцен (this.scene) текущей сцены (DemoA). Этот метод ищет сцену, из которой он был вызван, в общем списке активных сцен игры и перемещает её на последнюю позицию в этом списке.
До клика порядок рендеринга: [DemoA, DemoB, DemoC]. После вызова this.scene.bringToTop() внутри DemoA порядок изменится на: [DemoB, DemoC, DemoA]. Следовательно, изображение из DemoA (lance-overdose-loader-eye.png), которое было внизу, теперь окажется поверх изображений из DemoB и DemoC.
Это чисто визуальное изменение порядка отрисовки. Логика и обновление (update) сцен остаются нетронутыми.
Практическое применение и аналоги
bringToTop идеально подходит для:
* Всплывающих окон (пауза, инвентарь, диалоги).
* Переключения HUD или слоев интерфейса.
* Эффектов, которые должны быть поверх всего (затемнение экрана, вспышка).
Phaser Scene Manager предоставляет и другие методы для управления порядком:
* sendToBack() — перемещает сцену в самый низ стека.
* moveUp() — перемещает сцену на одну позицию выше.
* moveDown() — перемещает сцену на одну позицию ниже.
// Примеры других методов управления порядком
this.scene.sendToBack(); // Отправить сцену на задний план
this.scene.moveUp(); // Поднять на один уровень
this.scene.moveDown(); // Опустить на один уровень
Эти методы дают точный контроль над визуальной иерархией вашей игры.
Что попробовать дальше
Метод bringToTop — это простой и эффективный инструмент для динамического управления визуальным порядком сцен в Phaser. Он позволяет реагировать на действия игрока и создавать многослойные композиции.
Для экспериментов попробуйте:
1. Вызвать bringToTop из разных сцен по разным условиям (не только по клику).
2. Скомбинировать его с методами паузы (this.scene.pause()) и возобновления (this.scene.resume()) для сложного управления состоянием интерфейса.
3. Создать систему модальных окон, где новое окно автоматически вызывается на верхний план, а предыдущее затемняется.
