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

Частицы — это мощный инструмент для создания динамичной атмосферы в играх. С помощью системы Particle Emitter в Phaser 3 можно легко реализовать сложные визуальные эффекты, такие как огонь, дым или магические всполохи, которые оживят любую сцену. В этой статье мы разберем пример создания трех разных огненных эффектов из одного и того же атласа текстур, изучим ключевые параметры эмиттера и научимся управлять их поведением для достижения желаемого визуального результата.

Версия 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.atlas('flares', 'assets/particles/flares.png', 'assets/particles/flares.json');
    }

    create ()
    {
        const flame = this.add.particles(150, 550, 'flares',
        {
            frame: 'white',
            color: [ 0xfacc22, 0xf89800, 0xf83600, 0x9f0404 ],
            colorEase: 'quad.out',
            lifespan: 2400,
            angle: { min: -100, max: -80 },
            scale: { start: 0.70, end: 0, ease: 'sine.out' },
            speed: 100,
            advance: 2000,
            blendMode: 'ADD'
        });

        const wisp = this.add.particles(400, 550, 'flares',
        {
            frame: 'white',
            color: [ 0x96e0da, 0x937ef3 ],
            colorEase: 'quart.out',
            lifespan: 1500,
            angle: { min: -100, max: -80 },
            scale: { start: 1, end: 0, ease: 'sine.in' },
            speed: { min: 250, max: 350 },
            advance: 2000,
            blendMode: 'ADD'
        });

        const smokey = this.add.particles(650, 550, 'flares',
        {
            frame: 'white',
            color: [ 0x040d61, 0xfacc22, 0xf89800, 0xf83600, 0x9f0404, 0x4b4a4f, 0x353438, 0x040404 ],
            lifespan: 1500,
            angle: { min: -100, max: -80 },
            scale: 0.75,
            speed: { min: 200, max: 300 },
            advance: 2000,
            blendMode: 'ADD'
        });
    }
}

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

const game = new Phaser.Game(config);

Загрузка ресурсов и настройка сцены

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

В методе preload() мы загружаем атлас с именем 'flares'. Он содержит набор разноцветных вспышек, идеально подходящих для эффектов огня, дыма и магии.

this.load.atlas('flares', 'assets/particles/flares.png', 'assets/particles/flares.json');

После загрузки ресурсов в методе create() мы создаем три отдельных эмиттера частиц. Конфигурация сцены и игры задается в объекте config, который передается в конструктор Phaser.Game. Важно отметить параметр blendMode: 'ADD' в настройках эмиттеров — он отвечает за аддитивное наложение цветов, что делает огненные эффекты яркими и реалистичными.

Эмиттер основного пламени (Flame)

Первый эмиттер создает эффект устойчивого желто-оранжевого пламени. Он расположен в точке (150, 550). Давайте разберем его ключевые параметры.

const flame = this.add.particles(150, 550, 'flares',
{
    frame: 'white',
    color: [ 0xfacc22, 0xf89800, 0xf83600, 0x9f0404 ],
    colorEase: 'quad.out',
    lifespan: 2400,
    angle: { min: -100, max: -80 },
    scale: { start: 0.70, end: 0, ease: 'sine.out' },
    speed: 100,
    advance: 2000,
    blendMode: 'ADD'
});

* frame: 'white': Указывает, что все частицы будут использовать белый кадр из атласа. Их итоговый цвет задается параметром color. * color: Массив цветов в HEX-формате. Частицы будут плавно перетекать по этим цветам в течение своей жизни, создавая градиент от светло-желтого к темно-красному. * colorEase: 'quad.out': Определяет функцию плавности (easing) для перехода между цветами. 'quad.out' означает, что переход начнется быстро, а к концу замедлится. * lifespan: 2400: Время жизни каждой частицы в миллисекундах. * angle: Частицы будут вылетать под углом от -100 до -80 градусов (то есть почти вертикально вверх, но с небольшим разбросом). * scale: Частицы начнут с размера 70% от исходного и будут уменьшаться до 0. Уменьшение будет происходить по кривой 'sine.out'. * speed: 100: Постоянная скорость движения частиц. * advance: 2000: Этот параметр «прокручивает» таймер эмиттера на 2000 мс вперед при создании. Это позволяет эффекту сразу появиться в полную силу, а не начинаться с нуля.

Эмиттер синего язычка пламени (Wisp)

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

const wisp = this.add.particles(400, 550, 'flares',
{
    frame: 'white',
    color: [ 0x96e0da, 0x937ef3 ],
    colorEase: 'quart.out',
    lifespan: 1500,
    angle: { min: -100, max: -80 },
    scale: { start: 1, end: 0, ease: 'sine.in' },
    speed: { min: 250, max: 350 },
    advance: 2000,
    blendMode: 'ADD'
});

Основные отличия от первого эмиттера: * color: Используется палитра от голубовато-бирюзового (0x96e0da) до фиолетового (0x937ef3). * scale: Частицы начинаются с полного размера (start: 1) и исчезают до нуля. Кривая 'sine.in' означает, что уменьшение будет медленным в начале и быстрым в конце. * speed: Здесь скорость не постоянная, а случайная в диапазоне от 250 до 350. Это делает поток частиц более хаотичным и динамичным. * lifespan: Время жизни частиц меньше (1500 мс), чем у основного пламени, что создает эффект более быстрого и прерывистого горения.

Эмиттер дыма (Smokey)

Третий эмиттер создает эффект густого, многоцветного дыма, исходящего от огня. Он сочетает в себе черты двух предыдущих, но без анимации размера.

const smokey = this.add.particles(650, 550, 'flares',
{
    frame: 'white',
    color: [ 0x040d61, 0xfacc22, 0xf89800, 0xf83600, 0x9f0404, 0x4b4a4f, 0x353438, 0x040404 ],
    lifespan: 1500,
    angle: { min: -100, max: -80 },
    scale: 0.75,
    speed: { min: 200, max: 300 },
    advance: 2000,
    blendMode: 'ADD'
});

Ключевые особенности этого эмиттера: * color: Очень длинный массив цветов. Частица за свою жизнь пройдет путь от темно-синего (0x040d61) через все оттенки пламени (желтый, оранжевый, красный) и закончит оттенками серого и черного. Это имитирует процесс, когда дым, только что оторвавшийся от пламени, еще горячий и окрашенный, а затем остывает и темнеет. * scale: 0.75: Размер частиц постоянен на протяжении всей их жизни. Это характерно для плотного, клубящегося дыма, который не так быстро рассеивается, как пламя. * Отсутствует colorEase: Переход между многочисленными цветами будет происходить линейно, равномерно распределяясь по времени жизни частицы.

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

Используя всего один атлас текстур и гибкую систему параметров Particle Emitter, можно создавать огромное разнообразие атмосферных эффектов. Экспериментируйте: попробуйте изменить значения lifespan, speed и angle, чтобы получить струю пламени, развевающийся на ветру огонь костра или вулканический выброс. Добавьте гравитацию (gravityY) или силу ветра (accelerationX), чтобы частицы двигались по дуге. Комбинируя несколько простых эмиттеров, как в нашем примере, вы сможете создавать сложные и захватывающие визуальные композиции для своих игр.