Контейнеры: Container и вложенные трансформации

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


Создание контейнера

Контейнер создаётся с помощью конструктора сцены:

const container = this.add.container(x, y);

где x и y — координаты положения контейнера на сцене. Все объекты, добавленные в контейнер, будут позиционироваться относительно этих координат.

Добавление объектов в контейнер:

const sprite = this.add.sprite(0, 0, 'player');
const text = this.add.text(50, 20, 'Игрок', { fontSize: '16px', fill: '#fff' });

container.add([sprite, text]);

После этого любые изменения свойств контейнера автоматически применяются ко всем его дочерним объектам.


Позиционирование и вложенные координаты

Контейнер создаёт собственную локальную систему координат. Позиции дочерних объектов задаются относительно контейнера. Это позволяет перемещать группу объектов одной командой:

container.x += 10;
container.y += 5;

Дочерние объекты смещаются вместе с контейнером, сохраняя свои локальные координаты.

Важно: позиция дочернего объекта относительно контейнера не изменяет его глобальное положение на сцене напрямую. Для получения глобальной позиции используется свойство getWorldTransformMatrix().

const matrix = container.getWorldTransformMatrix();
const worldPoint = matrix.transformPoint(child.x, child.y);

Масштабирование и вращение

Контейнер может масштабироваться и вращаться, влияя на все вложенные объекты:

container.scaleX = 2;
container.scaleY = 2;
container.rotation = Math.PI / 4;
  • Масштабирование увеличивает или уменьшает размеры всех дочерних объектов пропорционально.
  • Вращение поворачивает все объекты вокруг точки (0, 0) контейнера.

Особенности вложенной трансформации:

  1. Вращение дочернего объекта учитывает вращение контейнера.
  2. Масштаб дочернего объекта умножается на масштаб контейнера.
  3. Изменение позиции контейнера перемещает все дочерние объекты вместе с ним.
sprite.rotation = Math.PI / 6; // локальное вращение
container.rotation = Math.PI / 4; // глобальное вращение всей группы

Результирующее вращение объекта — комбинация локального и родительского вращения.


Управление глубиной и видимостью

Контейнер поддерживает свойства visible и alpha, влияющие на все дочерние объекты:

container.visible = false; // скрывает все объекты
container.alpha = 0.5; // устанавливает прозрачность

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


Добавление и удаление объектов динамически

Контейнер позволяет добавлять или удалять объекты после создания:

container.add(sprite);
container.remove(text, true); // true — уничтожает объект при удалении

Удалённые объекты могут быть повторно добавлены в другой контейнер. Это удобно для управления игровыми группами или анимациями.


Вложенные контейнеры

Phaser поддерживает контейнеры внутри контейнеров. Вложенные контейнеры создают иерархию трансформаций:

const parentContainer = this.add.container(100, 100);
const childContainer = this.add.container(50, 50);

const sprite = this.add.sprite(0, 0, 'enemy');
childContainer.add(sprite);
parentContainer.add(childContainer);
  • Движение parentContainer смещает childContainer и sprite.
  • Вращение или масштаб parentContainer также влияет на все дочерние контейнеры.
  • Локальные трансформации дочернего контейнера применяются поверх трансформаций родителя.

Преимущество вложенных контейнеров — возможность строить сложные структуры, например, персонажа с оружием, костюмами или отдельными эффектами.


Практические советы

  • Для производительности избегать чрезмерного вложения контейнеров. Глубокие иерархии усложняют расчёт трансформаций.
  • Использовать контейнеры для UI-элементов, групп врагов, анимаций частиц.
  • Для анимаций удобно комбинировать вращение контейнера с анимацией отдельных спрайтов внутри.

Методы и полезные свойства Container

Метод/Свойство Назначение
add() Добавляет объект или массив объектов в контейнер
remove() Удаляет объект из контейнера
removeAll() Удаляет все дочерние объекты
getAll() Возвращает массив всех дочерних объектов
list Прямой доступ к массиву дочерних объектов
x, y Позиция контейнера на сцене
scaleX, scaleY Масштаб контейнера
rotation Вращение контейнера в радианах
visible Видимость контейнера
alpha Прозрачность контейнера
getWorldTransformMatrix() Получает матрицу трансформации для вычисления глобальных координат

Контейнеры в Phaser создают мощный механизм для группировки и трансформации игровых объектов. Управление вложенными объектами, комбинирование локальных и глобальных трансформаций позволяет создавать сложные сцены и анимации с минимальными усилиями.