Трансформации внутри контейнеров

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

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

Пример создания контейнера:

const container = this.add.container(400, 300);
const sprite1 = this.add.sprite(0, 0, 'player');
const sprite2 = this.add.sprite(100, 50, 'enemy');

container.add([sprite1, sprite2]);

В этом примере sprite1 и sprite2 будут перемещаться, вращаться и масштабироваться вместе с контейнером.


Позиция и локальные координаты

Каждый объект внутри контейнера имеет локальные координаты, которые отсчитываются относительно контейнера, а не сцены.

  • Позиция контейнера определяет смещение всех его дочерних объектов относительно глобальной сцены.
  • Локальные координаты объекта внутри контейнера позволяют строить композиции без сложных вычислений мировых координат.
sprite1.x = 50; // смещение относительно контейнера
sprite1.y = 20;
console.log(sprite1.getWorldTransformMatrix()); // матрица для глобальной позиции

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


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

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

container.setScale(2);
container.setRotation(Math.PI / 4);
  • При масштабировании контейнера дочерние объекты увеличиваются пропорционально.
  • Вращение контейнера поворачивает все объекты относительно центра контейнера, определяемого его координатами.

Важно учитывать, что порядок применения трансформаций: сначала локальные трансформации объекта, затем трансформации контейнера. Это влияет на конечное положение и ориентацию объектов в сцене.


Группировка и управление видимостью

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

container.setVisible(false); // скрывает все дочерние объекты
container.setAlpha(0.5);     // устанавливает прозрачность для всех объектов

Контейнеры можно использовать для реализации слоёв интерфейса, сцен с несколькими персонажами или для логического объединения элементов UI.


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

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

const weaponContainer = this.add.container(20, 0);
weaponContainer.add(weaponSprite);

container.add(weaponContainer);

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


Управление интерактивностью

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

sprite1.setInteractive();
sprite1.on('pointerdown', () => {
    console.log('Нажат спрайт внутри контейнера');
});

Чтобы контейнер реагировал на события, необходимо использовать метод setInteractive для него или для его дочерних объектов, либо применять специальные хитбоксы (Phaser.GameObjects.Zone) для всей группы.


Анимации внутри контейнеров

Все анимации дочерних объектов работают независимо, но наследуют трансформации контейнера. Это позволяет создавать сложные композиции:

this.tweens.add({
    targets: container,
    x: 600,
    y: 400,
    duration: 2000,
    ease: 'Power2'
});

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


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

  1. Использовать контейнеры для логической группировки объектов — персонажи с оружием, группы врагов, слои UI.
  2. Стараться минимизировать вложенность — слишком глубокие иерархии могут негативно влиять на производительность.
  3. Не использовать контейнер для простого хранения данных — контейнеры предназначены именно для визуальных объектов.
  4. Проверять координаты и вращение дочерних объектов при сложных композициях, чтобы избежать неожиданных трансформаций.

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