О чем этот пример
Контейнеры (`Container`) в Phaser — мощный инструмент для группировки игровых объектов и управления ими как единым целым. В этой статье мы рассмотрим продвинутую технику: добавление системы частиц (`ParticleEmitter`) внутрь контейнера. Это позволяет создавать сложные визуальные эффекты, которые можно вращать, масштабировать и анимировать вместе с группой других спрайтов, открывая двери для создания динамичных фонов, заклинаний или реактивных двигателей, привязанных к объекту.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('lemming', 'assets/sprites/lemming.png');
}
create ()
{
// Our container
const container = this.add.container(400, 300);
// Our emitter
const emitter = this.add.particles(0, 0, 'lemming', {
lifespan: 2000,
speed: { min: 200, max: 400 },
angle: 330,
gravityY: 300
});
container.add(emitter);
// Rotate the container
this.tweens.add({
targets: container,
angle: 360,
duration: 6000,
yoyo: true,
repeat: -1
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#010101',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Зачем добавлять эмиттер в контейнер?
Обычно система частиц, созданная через this.add.particles(), существует в мировых координатах сцены. Добавив её в контейнер, вы «привязываете» её к локальной системе координат этого контейнера.
Это означает, что все свойства трансформации контейнера — его позиция, угол поворота (angle), масштаб — автоматически применяются и к испускаемым частицам. Частицы будут рождаться относительно центра контейнера и вращаться вместе с ним, что невозможно при независимом размещении эмиттера.
Разбор кода: создание контейнера и эмиттера
В методе create() сцены происходит основная настройка. Сначала создаётся пустой контейнер в центре экрана.
const container = this.add.container(400, 300);
Затем создаётся эмиттер частиц. Обратите внимание, что его начальные координаты (0, 0) теперь будут отсчитываться не от мирового начала координат, а от позиции контейнера, в который мы его позже поместим.
const emitter = this.add.particles(0, 0, 'lemming', {
lifespan: 2000,
speed: { min: 200, max: 400 },
angle: 330,
gravityY: 300
});
Ключевой момент — добавление эмиттера в контейнер с помощью метода .add(). Теперь эмиттер становится дочерним объектом контейнера.
container.add(emitter);
Анимация целой системы
Сила этого подхода раскрывается при анимации. Мы применяем твин (плавную анимацию) не к эмиттеру, а ко всему контейнеру.
this.tweens.add({
targets: container,
angle: 360,
duration: 6000,
yoyo: true,
repeat: -1
});
Твин вращает контейнер на 360 градусов. Поскольку эмиттер теперь часть контейнера, весь поток частиц также будет плавно вращаться по кругу, создавая эффект вихря или спирали. Параметры yoyo: true и repeat: -1 заставляют анимацию проигрываться в прямом и обратном направлении бесконечно.
Конфигурация игры и важные детали
Пример использует стандартную конфигурацию игры. Обратите внимание на backgroundColor: '#010101' — тёмный фон помогает лучше видеть светлые частицы.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#010101',
parent: 'phaser-example',
scene: Example
};
Важное замечание по API: метод this.add.particles() создаёт и возвращает объект типа ParticleEmitterManager. При добавлении в контейнер передаётся именно этот менеджер. Все его эмиттеры (в данном случае один) наследуют трансформации контейнера.
Что попробовать дальше
Добавление эмиттера частиц в контейнер — это простой, но мощный приём для создания сложных связанных визуальных эффектов в Phaser. Вы можете экспериментировать: добавьте в этот же контейнер спрайт корабля, чтобы частицы имитировали выхлоп, или разместите несколько контейнеров с разными эмиттерами для создания многослойного анимированного фона. Попробуйте анимировать не только angle, но и свойства scaleX, scaleY контейнера, чтобы частицы динамически меняли размер вместе с родительской группой.
