О чем этот пример

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

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.55.2.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


class Example extends Phaser.Scene
{
    particles;

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.atlas('flares', 'assets/particles/flares.png', 'assets/particles/flares.json');
    }

    create ()
    {
        // this.cameras.main.setAlpha(0.4);

        this.particles = this.add.particles('flares');

        this.particles.createEmitter({
            frame: 'blue',
            x: -100,
            y: 0,
            lifespan: 2000,
            speed: { min: 400, max: 600 },
            angle: 330,
            gravityY: 300,
            scale: { start: 0.4, end: 0 },
            quantity: 2,
            blendMode: 'ADD'
        });

        this.particles.createEmitter({
            frame: 'red',
            x: 100,
            y: 0,
            lifespan: 2000,
            speed: { min: 400, max: 600 },
            angle: 330,
            gravityY: 300,
            scale: { start: 0.4, end: 0 },
            quantity: 2,
            blendMode: 'ADD'
        });

        this.particles.setPosition(400, 300);
    }

    update ()
    {
        this.particles.rotation -= 0.01;
    }
}

const config = {
    type: Phaser.WEBGL,
    width: 800,
    height: 600,
    backgroundColor: '#000',
    parent: 'phaser-example',
    scene: Example
};

const game = new Phaser.Game(config);

Создание менеджера частиц

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

this.particles = this.add.particles('flares');

Здесь this.add.particles('flares') создает менеджер и загружает в него атлас с именем 'flares'. Все последующие эмиттеры будут использовать частицы из этого атласа.

Добавление эмиттеров в менеджер

Эмиттеры создаются не через this.add.particles, а через метод .createEmitter() самого менеджера. Это ключевой момент: теперь они принадлежат ему.

this.particles.createEmitter({
    frame: 'blue',
    x: -100,
    y: 0,
    lifespan: 2000,
    speed: { min: 400, max: 600 },
    angle: 330,
    gravityY: 300,
    scale: { start: 0.4, end: 0 },
    quantity: 2,
    blendMode: 'ADD'
});

Обратите внимание на свойства x: -100 и x: 100 у синего и красного эмиттеров. Эти координаты заданы относительно позиции самого менеджера частиц (this.particles). Изначально менеджер находится в точке (0, 0) сцены.

Глобальное позиционирование менеджера

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

this.particles.setPosition(400, 300);

Вызов this.particles.setPosition(400, 300) перемещает весь менеджер, а следовательно, и оба эмиттера, в центр экрана. Теперь синий эмиттер будет находиться в точке (300, 300), а красный — в (500, 300), потому что их локальные координаты (-100 и 100) прибавляются к глобальной позиции менеджера.

Глобальное вращение эффекта

Самая мощная особенность этого подхода — возможность вращать всю систему частиц как единый визуальный объект. Это делается в методе update().

update ()
{
    this.particles.rotation -= 0.01;
}

Каждый кадр мы уменьшаем свойство rotation менеджера this.particles. Вращается не текстура каждой частицы, а вся система координат, к которой привязаны эмиттеры. В результате два потока частиц начинают вращаться по кругу вокруг центра менеджера, создавая эффект вращающегося двойного факела.

Что попробовать дальше

Использование ParticleEmitterManager превращает набор частиц в структурированный, трансформируемый объект. Вы можете легко анимировать его положение, вращение и масштаб, создавая сложные координированные эффекты. Для экспериментов попробуйте: анимировать масштаб менеджера (this.particles.scaleX/Y) для "пульсирующего" эффекта; привязать менеджер к спрайту игрока, чтобы эффект следовал за ним; или создать несколько менеджеров для независимого управления разными типами визуальных эффектов на сцене.