О чем этот пример
Эффекты частиц — это мощный инструмент для визуального оформления игр, будь то магические заклинания, следы от выстрелов или природные явления. Однако стандартный выброс частиц в случайной точке часто выглядит слишком хаотично. Использование заранее заданных траекторий (путей) для эмиттера позволяет создавать сложные, управляемые и предсказуемые визуальные эффекты, которые точно вписываются в геймплей. В этой статье мы разберем, как заставить частицы следовать по круговой траектории, используя систему путей (Curves) и эмиттеров частиц 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('flares', 'assets/particles/flares.png', 'assets/particles/flares.json');
}
create ()
{
const path = new Phaser.Curves.Path(400, 300).circleTo(100).moveTo(400, 300).circleTo(100, true, 180);
const particles = this.add.particles('flares');
particles.createEmitter({
frame: { frames: [ 'red', 'green', 'blue' ], cycle: true },
scale: { start: 0.5, end: 0 },
blendMode: 'ADD',
emitZone: { type: 'edge', source: path, quantity: 48, yoyo: false }
});
}
}
const config = {
type: Phaser.WEBGL,
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('flares', 'assets/particles/flares.png', 'assets/particles/flares.json');
}
Метод this.load.setBaseURL() задает базовый URL для всех последующих загрузок. Метод this.load.atlas() загружает изображение flares.png и файл данных flares.json, который описывает, где находятся отдельные кадры (например, 'red', 'green', 'blue') внутри этого изображения.
Создание кривой-пути для движения частиц
В Phaser 3 класс Phaser.Curves.Path позволяет создавать сложные составные пути из различных типов кривых. Частицы будут появляться вдоль этого пути.
const path = new Phaser.Curves.Path(400, 300).circleTo(100).moveTo(400, 300).circleTo(100, true, 180);
Разберем эту цепочку вызовов по порядку:
1. new Phaser.Curves.Path(400, 300) — создает объект пути, начиная его в точке с координатами x:400, y:300 (центр экрана при разрешении 800x600).
2. .circleTo(100) — добавляет к пути полную окружность радиусом 100 пикселей.
3. .moveTo(400, 300) — возвращает «перо» пути обратно в исходную центральную точку, не рисуя при этом линию.
4. .circleTo(100, true, 180) — добавляет вторую окружность. Параметры true и 180 указывают, что окружность должна рисоваться по часовой стрелке (clockwise: true) и ее угол составит 180 градусов, то есть это будет полукруг.
В результате получается фигура, похожая на цифру «8» или знак бесконечности.
Настройка менеджера и эмиттера частиц
Сначала создается менеджер частиц, который отвечает за отрисовку всех эмиттеров, использующих заданный текстуру.
const particles = this.add.particles('flares');
Затем в этом менеджере создается эмиттер — объект, который непосредственно генерирует, обновляет и управляет частицами.
particles.createEmitter({
frame: { frames: [ 'red', 'green', 'blue' ], cycle: true },
scale: { start: 0.5, end: 0 },
blendMode: 'ADD',
emitZone: { type: 'edge', source: path, quantity: 48, yoyo: false }
});
Конфигурация эмиттера:
- frame: Определяет, какие кадры из атласа будут использоваться. Массив ['red', 'green', 'blue'] и флаг cycle: true заставляют частицы циклически менять свой цвет с красного на зеленый, затем на синий.
- scale: Задает изменение размера частицы за время ее жизни от 0.5 до `0` (полное исчезновение).
- blendMode: 'ADD' — режим наложения, при котором цвета частиц складываются, создавая яркие, светящиеся эффекты.
- emitZone — ключевой параметр. Его тип 'edge' означает, что частицы будут появляться равномерно вдоль всей границы (края) заданного источника (source: path). Параметр quantity: 48 определяет общее количество точек эмиссии вдоль этого пути, то есть одновременно по фигуре будет распределено 48 частиц.
Конфигурация и запуск игры
Сцена готова, осталось создать экземпляр игры с базовой конфигурацией.
const config = {
type: Phaser.WEBGL, // Использование WebGL для лучшей производительности и поддержки blendMode 'ADD'
width: 800,
height: 600,
backgroundColor: '#000', // Черный фон для контраста со светящимися частицами
parent: 'phaser-example', // ID HTML-элемента, в который будет встроен canvas
scene: Example // Класс основной сцены
};
const game = new Phaser.Game(config);
Важно использовать type: Phaser.WEBGL, так как режим наложения 'ADD' для частиц корректно работает только в WebGL-рендерере.
Что попробовать дальше
Использование путей в качестве зоны эмиссии — это простой, но невероятно мощный прием для создания структурированных и красивых эффектов частиц. Вы можете заменить circleTo на lineTo, splineThrough или ellipseTo для создания траекторий любой сложности: волн, спиралей, орбит планет или паттернов заклинаний.
**Идеи для экспериментов:**
1. Измените параметр quantity в emitZone, чтобы увидеть, как количество точек эмиссии влияет на плотность эффекта.
2. Попробуйте использовать emitZone с типом 'random' вместо 'edge', передав ему тот же путь в качестве source. Частицы будут появляться в случайных точках внутри площади, ограниченной этой фигурой.
3. Анимируйте саму кривую path с помощью getPoint и tween, чтобы создать движущийся источник частиц, например, след за двигающимся кораблем.
