О чем этот пример
Эмиттеры частиц в Phaser — мощный инструмент для создания эффектов, но иногда одного источника недостаточно. В этой статье мы разберем пример, где массив координат `x` заставляет частицы появляться из нескольких точек одновременно. Этот прием полезен для создания сложных анимаций, вроде пара из нескольких труб или дождя из разных участков экрана, без необходимости создавать отдельный эмиттер для каждого источника.
Версия 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.image('bg', 'assets/skies/darkstone.png');
this.load.image('platform', 'assets/particles/platform.png');
this.load.image('pipe', 'assets/particles/pipe.png');
this.load.image('slime', 'assets/particles/slime.png');
}
create ()
{
this.add.image(400, 300, 'bg');
this.add.image(-100, 0, 'platform').setOrigin(0, 0);
this.add.image(412, 0, 'platform').setOrigin(0, 0);
// This emitter will randomly emit a particle from one of the x coordinates in the given array
// which just so happen to align perfectly with the pipe sprites we positioned below
this.add.particles(0, 150, 'slime', {
x: [ 62, 162, 262, 538, 638, 738 ],
lifespan: 2500,
gravityY: 200,
frequency: 80,
scale: { min: 0.6, max: 1.1 },
blendMode: 'ADD'
});
this.add.image(30, 10, 'pipe').setOrigin(0, 0);
this.add.image(130, 10, 'pipe').setOrigin(0, 0);
this.add.image(230, 10, 'pipe').setOrigin(0, 0);
this.add.image(506, 10, 'pipe').setOrigin(0, 0);
this.add.image(606, 10, 'pipe').setOrigin(0, 0);
this.add.image(706, 10, 'pipe').setOrigin(0, 0);
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#000',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Концепция: один эмиттер, несколько точек выброса
Обычно ParticleEmitter испускает частицы из одной точки, заданной параметрами `xиy`. Однако, если передать массивы координат вместо одиночных значений, эмиттер будет случайным образом выбирать позицию для каждой новой частицы из предоставленного набора.
В нашем примере это используется для создания иллюзии, что зеленые частицы "слизи" одновременно вытекают из шести разных труб.
x: [ 62, 162, 262, 538, 638, 738 ],
При каждом выбросе новая частица получит одну из шести координат по оси X. Это экономит ресурсы и упрощает управление эффектом.
Разбор загрузки и подготовки сцены
В методе preload() загружаются все необходимые изображения. Обратите внимание на использование setBaseURL — это удобно для указания базового пути для всех последующих загрузок.
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('bg', 'assets/skies/darkstone.png');
this.load.image('platform', 'assets/particles/platform.png');
this.load.image('pipe', 'assets/particles/pipe.png');
this.load.image('slime', 'assets/particles/slime.png');
В create() сначала добавляется фон и платформы. Затем, и это ключевой момент, создается эмиттер частиц ДО того, как на сцену добавлены изображения труб. Координаты в массиве `x` подобраны так, чтобы точно совпадать с позициями будущих труб. Частицы будут появляться как бы из-за них.
Детальная настройка Particle Emitter
Эмиттер создается с помощью метода this.add.particles. Первые два аргумента (0, 150) — это базовая позиция эмиттера. Однако, так как параметр `x` переопределен массивом, эти координаты по X игнорируются. Y-координата (150) остается общей для всех точек выброса.
Разберем конфигурационный объект:
{
x: [ 62, 162, 262, 538, 638, 738 ], // Массив точек появления
lifespan: 2500, // Время жизни частицы в миллисекундах
gravityY: 200, // Сила гравитации, тянет частицы вниз
frequency: 80, // Интервал между выбросами частиц (меньше = чаще)
scale: { min: 0.6, max: 1.1 }, // Случайный размер частицы в заданном диапазоне
blendMode: 'ADD' // Режим наложения, дает яркое, "светящееся" свечение
}
Параметр gravityY заставляет частицы падать, создавая эффект стекающей жидкости. blendMode: 'ADD' делает их более яркими и полупрозрачными при наложении друг на друга.
Визуальное совмещение: частицы и статичные объекты
После создания эмиттера на сцену добавляются изображения труб (pipe). Их позиции (setOrigin(0, 0) устанавливает точку отсчета в левый верхний угол) должны в точности соответствовать координатам из массива `x` в конфиге эмиттера. Это создает убедительную картину: частицы появляются прямо из отверстий труб.
this.add.image(30, 10, 'pipe').setOrigin(0, 0);
// ... и так далее для остальных пяти труб
Такое разделение логики (эмиттер) и графики (трубы) делает код чище и позволяет легко менять один элемент, не трогая другой.
Что попробовать дальше
Использование массивов в параметрах эмиттера — это простой и эффективный способ создать сложный, многопоточный эффект с минимальным кодом. Вы можете экспериментировать: попробуйте задать массивы и для `y, чтобы создать сетку источников. Добавьте случайность вgravityYилиangle` для более хаотичного движения. Этот прием отлично подойдет для создания огня из нескольких факелов, фонтанов или роя насекомых, появляющихся с разных сторон экрана.
