О чем этот пример
Визуальные эффекты оживляют игровой мир и усиливают обратную связь. Частицы (particle emitters) в Phaser 3 — мощный инструмент для создания взрывов, огня, дыма и магии. В этой статье мы разберем практический пример, где по клику мыши генерируется сложный многослойный взрыв. Вы научитесь создавать и настраивать несколько эмиттеров, комбинировать их в один эффект и управлять их активацией через пользовательский ввод. Это основа для создания любых динамических визуальных эффектов в вашей игре.
Версия 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.atlas('explosion', 'assets/particles/explosion.png', 'assets/particles/explosion.json');
}
create ()
{
const particles = this.add.particles('explosion');
// Setting { min: x, max: y } will pick a random value between min and max
// Setting { start: x, end: y } will ease between start and end
particles.createEmitter({
frame: [ 'smoke-puff', 'cloud', 'smoke-puff' ],
angle: { min: 240, max: 300 },
speed: { min: 200, max: 300 },
quantity: 6,
lifespan: 2000,
alpha: { start: 1, end: 0 },
scale: { start: 1.5, end: 0.5 },
on: false
});
particles.createEmitter({
frame: 'red',
angle: { start: 0, end: 360, steps: 32 },
lifespan: 1000,
speed: 400,
quantity: 32,
scale: { start: 0.3, end: 0 },
on: false
});
particles.createEmitter({
frame: 'stone',
angle: { min: 240, max: 300 },
speed: { min: 400, max: 600 },
quantity: { min: 2, max: 10 },
lifespan: 4000,
alpha: { start: 1, end: 0 },
scale: { min: 0.05, max: 0.4 },
rotate: { start: 0, end: 360, ease: 'Back.easeOut' },
gravityY: 800,
on: false
});
particles.createEmitter({
frame: 'muzzleflash2',
lifespan: 200,
scale: { start: 2, end: 0 },
rotate: { start: 0, end: 180 },
on: false
});
this.input.on('pointerdown', pointer =>
{
particles.emitParticleAt(pointer.x, pointer.y);
});
}
}
const config = {
type: Phaser.WEBGL,
width: 800,
height: 600,
backgroundColor: '#000',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Загрузка атласа частиц
Для работы с частицами в Phaser часто используют атласы текстур — это один файл изображения и JSON-файл с координатами каждого кадра (frame). Это эффективнее, чем загружать множество отдельных картинок.
В методе preload мы загружаем такой атлас под ключом 'explosion'. Код загружает изображение explosion.png и данные о кадрах из explosion.json.
this.load.atlas('explosion', 'assets/particles/explosion.png', 'assets/particles/explosion.json');
Создание менеджера частиц и эмиттеров
В методе create мы создаем систему частиц, которая будет управлять всеми эмиттерами. Затем мы создаем четыре разных эмиттера с уникальными параметрами. Ключевой параметр on: false означает, что эмиттеры не испускают частицы автоматически. Они будут активированы позже по команде.
const particles = this.add.particles('explosion');
Каждый вызов particles.createEmitter() создает новый эмиттер с заданным конфигом. Обратите внимание на гибкость настройки свойств:
- frame: определяет текстуру (спрайт) для частиц. Можно указать один кадр или массив кадров для случайного выбора.
- angle: направление вылета частиц. Можно задать случайный диапазон (min/max) или равномерное распределение по шагам (steps).
- speed, lifespan, quantity, scale, alpha, rotate: основные свойства, управляющие поведением и внешним видом.
- gravityY: имитация гравитации, заставляет частицы падать.
- ease: функция плавности (easing) для анимации свойств между start и end.
particles.createEmitter({
frame: [ 'smoke-puff', 'cloud', 'smoke-puff' ],
angle: { min: 240, max: 300 },
speed: { min: 200, max: 300 },
quantity: 6,
lifespan: 2000,
alpha: { start: 1, end: 0 },
scale: { start: 1.5, end: 0.5 },
on: false
});
Активация всех эмиттеров по клику
Вся магия происходит в обработчике события pointerdown. Когда пользователь кликает по холсту, мы вызываем метод emitParticleAt у менеджера частиц particles.
Этот метод активирует **все** созданные эмиттеры, которые принадлежат этому менеджеру, в указанной точке (координаты клика). Таким образом, одним вызовом мы запускаем целый каскад частиц от всех четырех эмиттеров, создавая эффект сложного, многослойного взрыва.
this.input.on('pointerdown', pointer =>
{
particles.emitParticleAt(pointer.x, pointer.y);
});
Конфигурация игры и запуск сцены
Код завершается стандартной для Phaser 3 конфигурацией игры. Мы указываем тип рендерера (WEBGL для лучшей производительности частиц), размеры холста, цвет фона, ID родительского HTML-элемента и класс нашей сцены Example.
Затем создается экземпляр игры new Phaser.Game(config), который инициализирует все системы и запускает нашу сцену.
const config = {
type: Phaser.WEBGL,
width: 800,
height: 600,
backgroundColor: '#000',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что попробовать дальше
Вы освоили базовый паттерн создания сложных частичных эффектов в Phaser 3: создание менеджера, настройка нескольких отключенных эмиттеров и их одновременная активация в нужной точке. Это основа для эффектов выстрелов, взрывов, подобранных бонусов или следов.
Для экспериментов попробуйте:
1. Изменить параметры эмиттеров (скорость, гравитацию, количество) для получения совершенно другого визуального стиля.
2. Привязать вызов emitParticleAt не к клику, а к столкновению (collide) игровых объектов.
3. Создавать разные менеджеры частиц (this.add.particles) для разных типов эффектов и управлять ими независимо.
