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

Разработчики часто сталкиваются с необходимостью разделить игровые объекты на логические группы. В Phaser для этого есть слои (Layers). Однако иногда требуется, чтобы определённая группа объектов не отображалась на конкретной камере — например, элементы интерфейса, которые должны быть статичными, или служебные объекты для отладки. В этой статье мы разберём, как использовать метод `camera.ignore()` для слоя, чтобы исключить его из рендеринга выбранной камерой, сохраняя при этом интерактивность объектов. Это мощный инструмент для управления визуальным представлением вашей сцены.

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


class Demo extends Phaser.Scene {
    constructor() {
        super({
            key: 'examples'
        })
    }

    preload() {
    }

    create() {
        var print = this.add.text(0, 0, '');

        var layer = this.add.layer();
        this.cameras.main.ignore(layer);

        var circle0 = this.add.circle(400, 300, 50).setStrokeStyle(3, 0x0000ff)
            .setInteractive()
            .on('pointerdown', function() {
                print.text += 'Click circle0\n';
            })

        layer.add(circle0)

        var point = this.add.circle(400, 300, 10, 0xff0000);
    }
}

var config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    scene: Demo,
    backgroundColor: 0x444444
};

var game = new Phaser.Game(config);

Проблема: объекты на слое видны везде

По умолчанию, когда вы добавляете объект на слой, все камеры сцены будут его отображать. Это не всегда удобно. Представьте, что у вас есть слой с отладочной графикой (хитбоксы, векторы движения), который должен быть виден только в режиме разработки, или слой с элементами UI, которые не должны масштабироваться и перемещаться вместе с игровым миром при движении камеры.

Прямое добавление объектов на слой без дополнительных настроек делает их видимыми для основной камеры, что может мешать финальному виду игры.

Решение: метод `camera.ignore()`

Phaser предоставляет простой способ сказать камере: "не обращай внимания на этот слой". Для этого используется метод ignore() экземпляра камеры, в который передаётся целевой слой.

После вызова этого метода камера перестаёт рендерить любые объекты, добавленные на этот слой или которые будут добавлены на него в будущем. Важно понимать, что объекты физически никуда не исчезают — они просто не отображаются этой конкретной камерой.

Давайте посмотрим на ключевой код из примера:

var layer = this.add.layer();
this.cameras.main.ignore(layer);

Здесь мы создаём новый пустой слой с помощью this.add.layer(). Затем получаем ссылку на основную камеру сцены (this.cameras.main) и вызываем для неё метод ignore(), передавая в качестве аргумента созданный слой.

Детали примера: интерактивность сохраняется

Даже если камера игнорирует слой, это не влияет на функциональность самих игровых объектов. Они остаются частью сцены, их обновление (update) продолжает работать, а события ввода (например, клики) по-прежнему обрабатываются.

В нашем примере на проигнорированный слой добавляется синий круг (circle0), на который назначено событие pointerdown.

var circle0 = this.add.circle(400, 300, 50).setStrokeStyle(3, 0x0000ff)
    .setInteractive()
    .on('pointerdown', function() {
        print.text += 'Click circle0\n';
    })
layer.add(circle0)

Несмотря на то что основная камера не рисует этот круг, вы можете кликнуть по месту, где он должен находиться (координаты 400, 300), и событие сработает — в текстовом поле print появится запись "Click circle0". Это доказывает, что объект существует и является интерактивным.

Для наглядности в тех же координатах создан маленький красный круг (point), который добавляется прямо на сцену (не на слой). Его камера отрисовывает, и он служит визуальным маркером, показывающим, где находится невидимый circle0.

Практическое применение: UI и отладка

1. **Статичный UI:** Создайте слой для элементов интерфейса (здоровье, очки, кнопки паузы) и добавьте его в игнор для всех камер, которые следуют за игровым миром. Затем создайте отдельную камеру (например, this.cameras.add) специально для UI, которая не будет игнорировать этот слой. Так UI останется на месте, независимо от скролла игровой камеры.

2. **Отладочная информация:** Во время разработки удобно выносить визуализацию коллайдеров, путей ИИ или логических зон на отдельный слой. Игнорируя этот слой для основной камеры, вы сможете включать и выключать его отображение через отдельную, "отладочную" камеру, которая рисуется поверх основной.

3. **Разделение контента:** Можно разделить фон, игровые объекты и эффекты на разные слои. Это позволит, например, отключить рендеринг слоя с частицами для камеры мини-карты, сэкономив ресурсы.

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

Метод camera.ignore() — это эффективный способ тонко управлять конвейером рендеринга в Phaser. Он позволяет гибко разделять визуальное отображение и логику объектов, что критически важно для создания сложных интерфейсов, систем отладки и многослойных сцен. **Идеи для экспериментов:** 1. Создайте две камеры и настройте для каждой свой набор игнорируемых слоёв. Переключайтесь между камерами, чтобы увидеть разное представление одной сцены. 2. Попробуйте динамически добавлять и удалять слой из игнора камеры с помощью camera.ignore() и camera.unignore() в runtime, например, по нажатию клавиши. 3. Проверьте, как сочетается игнорирование слоя с масками (setMask) и эффектами камеры (размытие, tint).