О чем этот пример

В разработке игр на Phaser часто возникает необходимость динамически управлять стеком сцен: менять их видимость, порядок отрисовки или реакцию на ввод. Метод `scene.moveDown()` — это простой, но мощный инструмент для перестановки сцен внутри списка исполнения. В этой статье мы разберем конкретный пример, где клик мыши перемещает активную сцену вниз по списку, и объясним, как это влияет на рендеринг и почему порядок сцен в массиве конфига так важен.

Версия 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.on('pointerup', function ()
        {

            this.scene.moveDown();

        }, 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.WEBGL,
    width: 800,
    height: 600,
    parent: 'phaser-example',
    scene: [ DemoB, DemoC, DemoA ]
};

const game = new Phaser.Game(config);

Структура примера: три сцены в стеке

Исходный код определяет три независимые сцены: DemoA, DemoB и DemoC. Ключевой момент — порядок их передачи в конфигурацию игры.

scene: [ DemoB, DemoC, DemoA ]

Этот массив определяет изначальный порядок сцен в системе Phaser. Сцены рендерятся и обновляются, начиная с последней в этом списке (с индексом 0 считается самой верхней в стеке визуализации). В нашем случае DemoA добавлена последней, поэтому изначально она будет находиться поверх DemoC и DemoB.

Механика метода moveDown

В сцене DemoA в методе create навешивается обработчик события клика (pointerup). При клике вызывается this.scene.moveDown().

this.input.on('pointerup', function () {
    this.scene.moveDown();
}, this);

Метод moveDown() перемещает текущую сцену (в данном случае DemoA) на одну позицию вниз в внутреннем списке сцен игры. Если сцена уже находится в самом низу списка, вызов метода не даст эффекта. Важно: этот метод влияет на порядок обновления и рендеринга, но не на активность сцен. Все сцены, помеченные active: true в конструкторе, продолжают работать.

Визуальный результат и порядок отрисовки

Изначально, так как DemoA последняя в массиве конфига, её изображение (picA) отрисовывается поверх остальных. После первого клика DemoA переместится в списке между DemoB и DemoC. Это значит, что теперь: 1. DemoB (индекс 0) — в самом низу стека отрисовки. 2. DemoA (переместилась вниз) — посередине. 3. DemoC (бывшая в середине) — теперь наверху.

Визуально изображение сцены DemoC (picC) перекроет часть изображения DemoA, так как DemoC теперь рендерится последней. Координаты изображений зафиксированы, поэтому мы увидим, как одно изображение "проваливается" под другое.

Практическое применение и важные детали

Такое управление порядком полезно для: * Реализации сложных UI-экранов, составленных из нескольких слоев-сцен. * Динамического изменения приоритета отрисовки игровых объектов (например, когда игрок заходит за определенный объект). * Организации модальных окон или всплывающих меню.

Обратите внимание на два нюанса в коде: 1. Связывание контекста this: в колбэке обработчика используется , this, чтобы внутри функции this указывал на экземпляр сцены, а не на InputPlugin. 2. Активность сцен: все три сцены созданы с флагом active: true, поэтому они работают одновременно. Метод moveDown() не останавливает и не запускает сцены, а только меняет их порядок в списке.

constructor () {
    super({ key: 'demoA', active: true });
}

Что попробовать дальше

Метод scene.moveDown() — это простой способ динамического управления порядком сцен в Phaser. Он позволяет создавать гибкие композиции без необходимости перезапуска или ручного управления видимостью каждого слоя. Для экспериментов попробуйте: вызвать moveDown() несколько раз подряд, использовать moveUp() для обратного действия, или менять порядок сцен в исходном массиве конфига и наблюдать за разницей в начальном состоянии.