О чем этот пример
Эмиттеры частиц в Phaser отлично подходят для создания статических эффектов, но как сделать их динамичными и реагирующими на окружение? В этой статье мы разберем пример использования Particle Processors (обработчиков частиц) — мощного механизма, который позволяет программно изменять поведение каждой частицы во время её жизни. Вы научитесь создавать сложные, «живые» эффекты, такие как имитация ветра, притяжения или других сил, которые меняются со временем, что критически важно для атмосферных погодных явлений, магических заклинаний или физических симуляций в вашей игре.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.55.2.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
SECOND = 1000;
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 lowWind = {
tween: this.tweens.addCounter({
from: -5,
to: 5,
duration: 11 * this.SECOND,
loop: Phaser.FOREVER,
ease: 'Sine.easeInOut'
}),
processor: {
active: true,
update: function (particle)
{
particle.velocityX += lowWind.tween.getValue();
}
}
};
const highWind = {
tween: this.tweens.addCounter({
from: -10,
to: 10,
duration: 4 * this.SECOND,
loop: Phaser.FOREVER,
ease: 'Sine.easeInOut'
}),
processor: {
active: true,
update: function (particle)
{
particle.velocityX += highWind.tween.getValue();
}
}
};
const particles = this.add.particles('flares');
particles.addGravityWell(lowWind.processor);
particles.addGravityWell(highWind.processor);
particles.createEmitter({
frame: [ 'red', 'yellow' ],
x: 600,
y: 400,
lifespan: 4000,
speed: 200,
scale: { start: 0.7, end: 0 },
blendMode: 'ADD'
});
}
}
const config = {
type: Phaser.WEBGL,
width: 800,
height: 600,
backgroundColor: '#000',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что такое Particle Processor?
Particle Processor (обработчик частиц) в Phaser — это объект с методом update, который вызывается для каждой активной частицы в каждом кадре. Это ваш крючок в жизненный цикл частицы, позволяющий изменять её свойства, такие как скорость, положение или масштаб, в реальном времени.
В отличие от предустановленных эмиттеров, процессоры дают полный контроль. В примере мы используем их как гравитационные колодцы (addGravityWell), но не для притяжения к точке, а для приложения горизонтальной силы, имитирующей ветер.
Ключевые требования к объекту-процессору:
const myProcessor = {
active: true, // Включен ли процессор
update: function (particle) {
// Ваша логика изменения частицы здесь
// particle.velocityX, particle.x и т.д.
}
};
Создание динамической силы с помощью Tweens
Чтобы сила ветра менялась плавно и циклически, мы используем систему твинов Phaser. Вместо простого значения мы создаем Tween для счетчика (addCounter), который колеблется между двумя числами.
Создаем два «ветра»: медленный и быстрый. Каждый ветер — это объект, содержащий твин и процессор, который использует текущее значение этого твина.
const lowWind = {
tween: this.tweens.addCounter({
from: -5, // Начальное значение силы
to: 5, // Конечное значение силы
duration: 11 * this.SECOND, // Длительность цикла
loop: Phaser.FOREVER, // Бесконечное повторение
ease: 'Sine.easeInOut' // Плавная синусоидальная интерполяция
}),
processor: {
active: true,
update: function (particle) {
// Применяем текущее значение твина к горизонтальной скорости частицы
particle.velocityX += lowWind.tween.getValue();
}
}
};
Метод getValue() возвращает текущее число в анимации твина. Добавляя его к particle.velocityX, мы постоянно ускоряем или замедляем частицу по оси X, создавая эффект порывов ветра.
Интеграция процессоров в эмиттер частиц
После создания объектов-процессоров их необходимо зарегистрировать в системе частиц. Хотя метод называется addGravityWell, он является универсальным способом добавления любого Particle Processor к менеджеру частиц.
// Создаем менеджер частиц для атласа 'flares'
const particles = this.add.particles('flares');
// Добавляем наши процессоры ("колодцы") к менеджеру
particles.addGravityWell(lowWind.processor);
particles.addGravityWell(highWind.processor);
Теперь в каждом кадре для каждой частицы будут последовательно вызваны методы update из lowWind.processor и highWind.processor. Их воздействия суммируются, создавая сложную результирующую силу.
Настройка и запуск эмиттера
Завершающий шаг — создание самого эмиттера, который будет испускать частицы. Эмиттер привязан к ранее созданному менеджеру particles, который уже содержит наши процессоры.
particles.createEmitter({
frame: [ 'red', 'yellow' ], // Кадры из атласа для частиц
x: 600, // Точка испускания по X
y: 400, // Точка испускания по Y
lifespan: 4000, // Время жизни частицы в мс
speed: 200, // Начальная скорость
scale: { start: 0.7, end: 0 }, // Уменьшение масштаба до 0
blendMode: 'ADD' // Режим наложения для яркого свечения
});
Частицы будут рождаться с начальной скоростью 200 пикселей в секунду, но их траектория будет немедленно и постоянно изменяться под действием наших «ветров», реализованных через процессоры.
Что попробовать дальше
Комбинация Particle Processors и системы твинов открывает двери для создания невероятно динамичных и сложных партикловых систем в Phaser. Вы можете управлять не только ветром, но и создавать поля притяжения, сопротивления среды, хаотичные вихри или управляемые магниты. Для экспериментов попробуйте: изменить твины на случайные колебания (Phaser.Math.Between), привязывать силу процессора к здоровью игрока, создавать процессор, который отталкивает частицы от курсора мыши, или комбинировать влияние на несколько свойств частицы (скорость, угол, альфа-канал) одновременно.
