О чем этот пример
Система частиц — мощный инструмент для создания визуальных эффектов: огня, дыма, магии или осколков. В Phaser 3 есть несколько способов их создания, каждый со своей спецификой. Понимание разницы между `this.add.particles` и `this.make.particles` позволит вам выбирать оптимальный метод для разных сценариев в игре, делая код чище и эффективнее. В этой статье мы разберем два подхода на конкретном примере, создающем два идентичных эмиттера частиц. Вы узнаете, когда использовать фабричный метод, а когда — создание через игровой объект, и как тонко настраивать их поведение.
Версия 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('megaset', 'assets/atlas/megaset-0.png', 'assets/atlas/megaset-0.json');
this.load.image('mask2', 'assets/particles/glass.png');
}
create ()
{
const a = this.add.particles('mask2', null, {
x: 200,
y: 590,
angle: { min: 180, max: 360 },
speed: 200,
gravityY: -350,
quantity: 1,
scale: { min: 0.1, max: 1 }
});
const m = this.make.particles({
key: 'mask2',
add: true,
emitters: [
{
x: 600,
y: 590,
angle: { min: 180, max: 360 },
speed: 200,
gravityY: -350,
scale: { min: 0.1, max: 1 }
}
]
});
}
}
const config = {
type: Phaser.CANVAS,
width: 800,
height: 600,
backgroundColor: '#000',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Подготовка ассетов: атлас и текстура частиц
Перед созданием эмиттеров необходимо загрузить графические ресурсы. В методе preload сцена загружает два изображения.
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.atlas('megaset', 'assets/atlas/megaset-0.png', 'assets/atlas/megaset-0.json');
this.load.image('mask2', 'assets/particles/glass.png');
Первая строка задает базовый URL для всех последующих загрузок, что удобно, если все ресурсы лежат в одной директории. Затем загружается атлас megaset (хотя в данном примере он не используется для частиц) и отдельное изображение mask2 с прозрачным PNG-файлом стекла, которое будет служить текстурой для каждой частицы.
Создание эмиттера через Game Object Factory (add.particles)
Первый и самый распространенный способ — использование фабрики игровых объектов (this.add). Метод this.add.particles создает и сразу добавляет в сцену объект типа ParticleEmitterManager с одним или несколькими эмиттерами.
const a = this.add.particles('mask2', null, {
x: 200,
y: 590,
angle: { min: 180, max: 360 },
speed: 200,
gravityY: -350,
quantity: 1,
scale: { min: 0.1, max: 1 }
});
Здесь 'mask2' — ключ текстуры частицы. Второй аргумент (null) означает, что мы не передаем массив конфигураций для нескольких эмиттеров, а вместо этого третий аргумент — объект конфигурации для единственного эмиттера. Параметры задают его положение (`x,y), направление разлета частиц (в диапазоне от 180 до 360 градусов, то есть вверх и влево), начальную скорость, силу гравитации (gravityY: -350заставляет частицы подниматься), количество частиц, испускаемых за один выброс (quantity: 1), и случайный масштаб. Возвращаемый объектa` уже является частью сцены и будет автоматически обновляться и отрисовываться.
Создание эмиттера через Game Object Creator (make.particles)
Второй подход использует конструктор игровых объектов (this.make). Метод this.make.particles создает объект ParticleEmitterManager, но не добавляет его на сцену автоматически. Это дает больше контроля над его жизненным циклом.
const m = this.make.particles({
key: 'mask2',
add: true,
emitters: [
{
x: 600,
y: 590,
angle: { min: 180, max: 360 },
speed: 200,
gravityY: -350,
scale: { min: 0.1, max: 1 }
}
]
});
Конфигурация передается одним объектом. Ключевое отличие — наличие свойства add: true, которое указывает конструктору самому добавить созданный объект в сцену. Эмиттеры задаются массивом emitters. Обратите внимание, что в этом способе параметр quantity не указан, и эмиттер будет использовать значение по умолчанию. Возвращаемый объект `mидентичен объектуa` из первого способа, но процесс его создания более гибкий.
Сравнение подходов и их применение
Оба метода создают визуально одинаковые эмиттеры в разных частях экрана (X: 200 и X: 600). Однако их внутренняя логика разная.
- `this.add.particles` — это "быстрый старт". Он идеален, когда вам нужно сразу создать и отобразить эффект. Вызывается в один шаг.
- `this.make.particles` — это "контролируемое создание". Он полезен, когда объект нужно создать, но добавить на сцену позже (например, в пул объектов), или когда вы хотите передать его в другой менеджер перед добавлением. Установка `add: false` позволит вам самостоятельно вызвать `this.add.existing(m)` в нужный момент.
Важно: в примере через make.particles не задан параметр quantity. Если поведение эмиттеров должно быть идентичным, это свойство нужно указывать явно в обоих случаях.
Разбор параметров конфигурации эмиттера
Конфигурационный объект — сердце настройки эффекта. Давайте детально разберем ключевые параметры, использованные в коде.
{
x: 600, // Стартовая X-координата источника частиц
y: 590, // Стартовая Y-координата источника частиц
angle: { min: 180, max: 360 }, // Диапазон углов вылета. 0° - вправо.
speed: 200, // Начальная скорость частицы в пикселях в секунду.
gravityY: -350, // Вертикальное ускорение. Отрицательное значение тянет вверх.
quantity: 1, // Частиц за один выброс (только в первом эмиттере).
scale: { min: 0.1, max: 1 } // Случайный начальный масштаб частицы.
}
Комбинация angle от 180° до 360° (веер влево-вверх) и отрицательной gravityY создает эффект фонтана или разлетающихся вверх осколков, которые затем падают под действием положительной гравитации движка (если она включена). scale от 0.1 до 1 добавляет визуальное разнообразие.
Что попробовать дальше
Оба метода, this.add.particles и this.make.particles, являются валидными способами создания системы частиц в Phaser 3. Выбор зависит от задачи: используйте add для немедленного отображения, а make — для более сложного управления жизненным циклом объекта.
**Идеи для экспериментов:**
1. Измените gravityY на положительное значение (например, 100), чтобы частицы сразу падали вниз.
2. Добавьте свойство lifespan для контроля длительности жизни частицы.
3. Создайте эмиттер через make.particles с add: false и добавьте его на сцену по клику мыши.
4. Испытайте другие текстуры из загруженного атласа megaset, указав ключ фрейма вместо null или 'mask2'.
