Контейнеры (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'
});
Движение контейнера анимирует все объекты сразу, при этом их собственные анимации могут продолжаться независимо.
Контейнеры в Phaser позволяют создавать гибкую и масштабируемую структуру сцены, управлять группами объектов как единым целым и упрощают работу с анимацией, позиционированием и интерактивностью.