О чем этот пример
Эмиттеры частиц — ключ к созданию визуальных эффектов в играх: от огня и магии до взрывов и погодных явлений. Одна из самых частых задач — контроль размера частиц. В Phaser.js для этого есть несколько подходов, и понимание их различий критически важно. Эта статья на практическом примере покажет, как правильно задавать начальный масштаб частиц, динамически его менять и избегать типичных ошибок, связанных с приоритетом настроек.
Версия 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.image('crate', 'assets/sprites/crate.png');
}
create ()
{
const particles = this.add.particles('crate');
const emitter = particles.createEmitter();
emitter.setPosition(400, 300);
emitter.setSpeed(200);
emitter.setLifespan(3000);
emitter.setScale(0.5);
/*
var emitter = particles.createEmitter({
x: 400, y: 300,
lifespan: 3000,
speed: 200,
quantity: 1,
scale: 0.5
});
// Overrides the 0.5 scale set in the config object above
emitter.setScale(2);
*/
}
}
const config = {
type: Phaser.WEBGL,
width: 800,
height: 600,
backgroundColor: '#000',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Базовый пример: создание эмиттера
В основе любого эффекта частиц в Phaser лежат два объекта: менеджер частиц (ParticleEmitterManager) и сам эмиттер (ParticleEmitter). Давайте создадим простой эмиттер, испускающий спрайты ящика из центра экрана.
Сначала в методе preload загрузим текстуру, а в create — инициализируем систему.
const particles = this.add.particles('crate');
const emitter = particles.createEmitter();
Теперь у нас есть эмиттер, но он еще не настроен. По умолчанию частицы не испускаются и не имеют физики.
Настройка через методы: `setScale` и другие
Самый прямой и читаемый способ настройки — использование методов сеттеров (setter methods) эмиттера. Они позволяют задавать параметры по отдельности.
В нашем примере мы позиционируем эмиттер, задаем скорость, время жизни частиц и, что самое важное, их начальный масштаб.
emitter.setPosition(400, 300);
emitter.setSpeed(200);
emitter.setLifespan(3000);
emitter.setScale(0.5);
Вызов emitter.setScale(0.5) устанавливает коэффициент масштабирования для всех испускаемых частиц. Значение 0.5 означает, что каждая частица будет отрисована в половину от своего исходного размера. Эти методы применяются немедленно и влияют на все последующие частицы.
Альтернатива: конфигурационный объект
Phaser также позволяет передать все настройки сразу при создании эмиттера через конфигурационный объект. Это удобно для централизованного управления параметрами.
var emitter = particles.createEmitter({
x: 400, y: 300,
lifespan: 3000,
speed: 200,
quantity: 1,
scale: 0.5
});
Параметр scale в этом объекте выполняет ту же роль, что и вызов setScale(0.5). Однако здесь есть важный нюанс, связанный с приоритетом.
Приоритет настроек: метод побеждает конфиг
В коде примера закомментирован блок, который демонстрирует ключевую особенность API Phaser. Если после создания эмиттера через конфиг вызвать метод setScale, то значение из метода переопределит значение из конфигурационного объекта.
// Overrides the 0.5 scale set in the config object above
emitter.setScale(2);
В этом случае, несмотря на то, что в конфиге был задан scale: 0.5, немедленный вызов setScale(2) установит масштаб в `2` (увеличение в два раза). Это происходит потому, что методы-сеттеры изменяют текущие, "живые" свойства эмиттера, в то время как конфиг задает только начальные значения. Запомните это правило: **поздний вызов метода всегда имеет приоритет над значением в конфиге**.
Практические сценарии использования
Понимание этого механизма открывает возможности для динамических эффектов.
* **Постепенное изменение эффекта:** Вы можете создать эмиттер с базовым конфигом, а затем, в зависимости от игровой логики (усиление персонажа, смена погоды), менять масштаб частиц на лету с помощью setScale.
* **Анимация масштаба:** Используйте Tweens или собственный код в update, чтобы плавно изменять scale эмиттера, создавая эффекты "пульсации" или "затухания".
* **Разные профили эффектов:** Создайте несколько пресетов-конфигов для одного менеджера частиц (пыль, искры, дым), а затем применяйте их, не забывая сбрасывать или переопределять параметры вроде scale методами при необходимости.
// Пример: изменение масштаба при клике
this.input.on('pointerdown', () => {
// Динамически увеличим размер частиц
emitter.setScale(emitter.scaleX + 0.1);
});
Что попробовать дальше
Управление масштабом частиц в Phaser — гибкий процесс. Используйте конфигурационный объект для удобной начальной настройки, а методы вроде setScale — для динамического контроля во время выполнения. Главное правило: значение, установленное методом, перезаписывает значение из конфига. Для экспериментов попробуйте создать эмиттер, который меняет scale в зависимости от расстояния до курсора, или реализуйте эффект взрыва, где частицы сначала быстро увеличиваются, а потом уменьшаются, используя цепочку твинов.
