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

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

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('crate', 'assets/sprites/crate.png');
    }

    create ()
    {
        const particles = this.add.particles('crate');

        const emitter = particles.createEmitter();

        emitter.setPosition(400, 300);
        emitter.setSpeed(200);
        emitter.setLifespan(3000);
        emitter.setScale(0.5);

        /*
        var emitter = particles.createEmitter({
            x: 400, y: 300,
            lifespan: 3000,
            speed: 200,
            quantity: 1,
            scale: 0.5
        });

        //  Overrides the 0.5 scale set in the config object above
        emitter.setScale(2);
        */
    }
}

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

const game = new Phaser.Game(config);

Базовый пример: создание эмиттера

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

Сначала в методе preload загрузим текстуру, а в create — инициализируем систему.

const particles = this.add.particles('crate');
const emitter = particles.createEmitter();

Теперь у нас есть эмиттер, но он еще не настроен. По умолчанию частицы не испускаются и не имеют физики.

Настройка через методы: `setScale` и другие

Самый прямой и читаемый способ настройки — использование методов сеттеров (setter methods) эмиттера. Они позволяют задавать параметры по отдельности.

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

emitter.setPosition(400, 300);
emitter.setSpeed(200);
emitter.setLifespan(3000);
emitter.setScale(0.5);

Вызов emitter.setScale(0.5) устанавливает коэффициент масштабирования для всех испускаемых частиц. Значение 0.5 означает, что каждая частица будет отрисована в половину от своего исходного размера. Эти методы применяются немедленно и влияют на все последующие частицы.

Альтернатива: конфигурационный объект

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

var emitter = particles.createEmitter({
    x: 400, y: 300,
    lifespan: 3000,
    speed: 200,
    quantity: 1,
    scale: 0.5
});

Параметр scale в этом объекте выполняет ту же роль, что и вызов setScale(0.5). Однако здесь есть важный нюанс, связанный с приоритетом.

Приоритет настроек: метод побеждает конфиг

В коде примера закомментирован блок, который демонстрирует ключевую особенность API Phaser. Если после создания эмиттера через конфиг вызвать метод setScale, то значение из метода переопределит значение из конфигурационного объекта.

//  Overrides the 0.5 scale set in the config object above
emitter.setScale(2);

В этом случае, несмотря на то, что в конфиге был задан scale: 0.5, немедленный вызов setScale(2) установит масштаб в `2` (увеличение в два раза). Это происходит потому, что методы-сеттеры изменяют текущие, "живые" свойства эмиттера, в то время как конфиг задает только начальные значения. Запомните это правило: **поздний вызов метода всегда имеет приоритет над значением в конфиге**.

Практические сценарии использования

Понимание этого механизма открывает возможности для динамических эффектов.

* **Постепенное изменение эффекта:** Вы можете создать эмиттер с базовым конфигом, а затем, в зависимости от игровой логики (усиление персонажа, смена погоды), менять масштаб частиц на лету с помощью setScale. * **Анимация масштаба:** Используйте Tweens или собственный код в update, чтобы плавно изменять scale эмиттера, создавая эффекты "пульсации" или "затухания". * **Разные профили эффектов:** Создайте несколько пресетов-конфигов для одного менеджера частиц (пыль, искры, дым), а затем применяйте их, не забывая сбрасывать или переопределять параметры вроде scale методами при необходимости.

// Пример: изменение масштаба при клике
this.input.on('pointerdown', () => {
    // Динамически увеличим размер частиц
    emitter.setScale(emitter.scaleX + 0.1);
});

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

Управление масштабом частиц в Phaser — гибкий процесс. Используйте конфигурационный объект для удобной начальной настройки, а методы вроде setScale — для динамического контроля во время выполнения. Главное правило: значение, установленное методом, перезаписывает значение из конфига. Для экспериментов попробуйте создать эмиттер, который меняет scale в зависимости от расстояния до курсора, или реализуйте эффект взрыва, где частицы сначала быстро увеличиваются, а потом уменьшаются, используя цепочку твинов.