О чем этот пример
Визуальные эффекты — это душа любой игры. Статичные частицы выглядят скучно, а динамические, переливающиеся цветом, способны оживить любой взрыв, огонь или магическое заклинание. В этой статье мы разберем, как создавать сложные эффекты частиц в 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);
Загрузка атласа частиц
В основе всех наших эффектов лежит один спрайт-лист (атлас) под названием 'flares'. Он содержит различные текстуры для частиц, но мы будем использовать только один кадр — 'white'. Это белый квадрат, который мы затем будем окрашивать программно. Такой подход экономит ресурсы и дает полный контроль над цветом.
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.atlas('flares', 'assets/particles/flares.png', 'assets/particles/flares.json');
Создание цветного пламени
Первый эмиттер имитирует языки пламени. Ключевой параметр здесь — color. Мы передаем массив из четырех hex-цветов. Частицы будут плавно перетекать из одного цвета в другой по заданной кривой (colorEase). Параметр advance ускоряет стартовую фазу жизни частицы, создавая эффект «выстрела».
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' // Режим наложения «Добавление» для свечения
});
Эффект холодного огонька (wisp)
Второй эмиттер создает эффект магического или холодного пламени. Обратите внимание на два отличия от первого: более холодная палитра цветов и случайная скорость (speed: { min: 250, max: 350 }). Это делает частицы более «живыми» и непредсказуемыми. Кривая colorEase: 'quart.out' обеспечивает более резкий переход цвета в начале жизни частицы.
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' }, // Исчезновение по кривой 'in'
speed: { min: 250, max: 350 }, // Случайная скорость
advance: 2000,
blendMode: 'ADD'
});
Имитация густого дыма
Третий эмиттер создает эффект дыма от огня. Здесь используется более сложная палитра из восьми цветов, плавно переходящая от темно-синего через оттенки пламени к черному и серому. Важное отличие — отсутствие colorEase и scale.ease. Частицы не меняют размер плавно, а просто исчезают (scale: 0.75), что вместе с более темными цветами создает иллюзию плотного, клубящегося дыма.
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'
});
Секреты настройки: Blend Mode и Advance
Два параметра критически важны для качественного эффекта.
* blendMode: 'ADD' (Режим наложения «Добавление»): Частицы не перекрывают друг друга, а их цвета складываются. Это создает эффект свечения и наложения, идеальный для огня, света и магии. Без этого параметра частицы будут выглядеть как непрозрачные круги.
* advance: 2000: Этот параметр «проматывает» таймер жизни частицы вперед на 2000 мс при ее создании. Фактически, частица рождается уже в середине своего жизненного цикла. Это позволяет сразу получить полноценный эффект (например, яркое пламя), а не ждать, пока частица «разгорится» от нуля.
// Это ключевые параметры для «сочного» эффекта
blendMode: 'ADD',
advance: 2000
Что попробовать дальше
Используя всего один спрайт и мощный API this.add.particles, вы можете создавать десятки уникальных визуальных эффектов. Экспериментируйте: попробуйте менять порядок цветов в массиве color, комбинируйте разные кривые (ease) для scale и colorEase, изменяйте blendMode на NORMAL или MULTIPLY для других типов эффектов (например, дыма без свечения). Не бойтесь создавать эмиттеры, которые следуют за игровым персонажем, — это оживит вашу игру.
