Глубина объекта: depth и setDepth

В библиотеке Phaser порядок отображения объектов на сцене определяется понятием глубины (depth). Глубина отвечает за то, какие объекты будут визуально находиться над другими. По умолчанию все объекты создаются с глубиной 0, и чем выше значение глубины, тем выше объект находится на слое рендеринга.

Свойство depth

Свойство depth является числовым атрибутом любого Game Object. Оно задаёт базовый уровень слоя, на котором объект будет отрисован:

let sprite = this.add.sprite(100, 100, 'player');
sprite.depth = 5;

В примере выше спрайт будет отрисован поверх объектов с меньшей глубиной. Если два объекта имеют одинаковую глубину, Phaser использует порядок добавления на сцену — более поздние объекты будут выше ранних.

Особенности свойства depth:

  • Можно присваивать как целые, так и дробные значения (1, 2.5).
  • Значение может быть отрицательным, что позволяет размещать объект под базовым слоем.
  • Изменение depth во время выполнения сцены автоматически обновляет порядок рендеринга.

Метод setDepth()

Метод setDepth() служит удобным способом изменить глубину объекта без прямого присваивания свойства. Синтаксис:

sprite.setDepth(10);

Преимущество метода в том, что он возвращает сам объект, что позволяет строить цепочки вызовов:

this.add.sprite(50, 50, 'enemy').setScale(2).setDepth(15).setTint(0xff0000);

Взаимодействие объектов с разной глубиной

Глубина объектов влияет не только на визуальный порядок, но и на взаимодействие с Input Manager. Например, если несколько интерактивных объектов накладываются, Phaser обрабатывает события начиная с объектов с большей глубиной.

let button1 = this.add.sprite(200, 200, 'button').setInteractive().setDepth(5);
let button2 = this.add.sprite(210, 210, 'button').setInteractive().setDepth(10);

button1.on('pointerdown', () => console.log('Нижняя кнопка'));
button2.on('pointerdown', () => console.log('Верхняя кнопка'));

При клике в области пересечения сработает событие button2, так как её глубина выше.

Группы и контейнеры

Глубина объектов в Phaser также применяется к группам и контейнерам. Установка глубины контейнера изменяет порядок всех входящих в него объектов:

let container = this.add.container(400, 300);
container.add([sprite, enemy]);
container.setDepth(20);

В этом случае и sprite, и enemy будут отрисованы поверх других объектов сцены с меньшей глубиной, но их относительная глубина внутри контейнера сохраняется.

Сравнение с z-index в CSS

Концепция глубины Phaser аналогична z-index в веб-разработке, но с одной особенностью: Phaser автоматически перерассчитывает порядок рендеринга при изменении depth, что делает динамическое управление слоями простым и эффективным. В отличие от CSS, где изменение z-index может требовать изменения DOM-структуры, Phaser оперирует внутренними массивами объектов сцены.

Практические рекомендации

  • Для статических объектов (фон, задний план) использовать низкие значения глубины (-10, 0), для динамических объектов — более высокие (5–50).
  • Для UI-элементов и панелей всегда использовать максимальные значения глубины, чтобы они оставались поверх игровых объектов.
  • При анимации объектов, которые могут менять положение относительно других, удобно динамически изменять глубину через setDepth().

Итоговый подход к управлению глубиной

Использование depth и setDepth() позволяет:

  1. Контролировать визуальный порядок объектов на сцене.
  2. Обеспечивать корректное взаимодействие с пользовательскими событиями.
  3. Легко структурировать сложные сцены с множеством слоёв и контейнеров.

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