О чем этот пример
Создание визуально интересных эффектов, таких как водопад или фейерверк, часто требует не просто хаотичного разброса частиц, а управляемой случайности. В этом примере мы рассмотрим, как использовать свойства `start`, `end` и `random` в конфигурации эмиттера частиц Phaser 3 для генерации частиц в случайных точках вдоль заданного отрезка, но с последующей упорядоченной визуализацией. Этот приём позволяет создавать сложные, динамичные эффекты, сохраняя контроль над их поведением и производительностью.
Версия 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/normal-maps/stones.png');
this.load.image('gem', 'assets/normal-maps/gem2.png');
}
create ()
{
this.add.image(400, 300, 'bg');
this.add.particles(0, 570, 'gem', {
x: { start: 0, end: 750, random: true },
scale: 0.5,
lifespan: 2500,
gravityY: -200,
quantity: 2,
sortProperty: 'y',
sortOrderAsc: false
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#000',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Разбор сцены и загрузки ресурсов
Класс Example расширяет Phaser.Scene — основную единицу организации кода в Phaser. В методе preload мы загружаем два изображения, используя публичное хранилище примеров Phaser.
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('bg', 'assets/normal-maps/stones.png');
this.load.image('gem', 'assets/normal-maps/gem2.png');
Первое изображение (bg) — это фоновая текстура камней. Второе (gem) — спрайт «самоцвета», который будет использоваться в качестве текстуры для каждой частицы. Метод load.image регистрирует эти ассеты под заданными ключами для последующего использования.
Создание фона и эмиттера частиц
В методе create мы сначала добавляем фоновое изображение в центр сцены с координатами (400, 300).
this.add.image(400, 300, 'bg');
Затем создаётся эмиттер частиц с помощью метода this.add.particles. Первые два аргумента (0, 570) задают исходную точку эмиттера на сцене. Третий аргумент ('gem') — ключ текстуры частицы. Четвёртый аргумент — объект конфигурации, определяющий поведение эмиттера и частиц.
Конфигурация эмиттера: случайность по оси X
Сердце эффекта — настройка свойства `x` для частиц. Вместо фиксированного значения мы используем объект с тремя параметрами.
x: { start: 0, end: 750, random: true },
Эта запись означает: для каждой вновь созданной частицы её координата X будет выбрана случайным образом (random: true) в диапазоне от start (0) до end (750). Таким образом, частицы будут появляться не в одной точке (0, 570), а в любой точке вдоль горизонтальной линии от левого края почти до правого края сцены (поскольку ширина сцены 800 пикселей). Это создаёт иллюзию широкого источника эмиссии, например, вершины водопада.
Дополнительные параметры и сортировка
Остальные параметры конфигурации fine-tune поведение системы частиц.
scale: 0.5,
lifespan: 2500,
gravityY: -200,
quantity: 2,
sortProperty: 'y',
sortOrderAsc: false
- scale: 0.5: Уменьшает размер всех частиц вдвое.
- lifespan: 2500: Частица будет «жить» 2500 миллисекунд (2.5 секунды), после чего исчезнет.
- gravityY: -200: Задаёт отрицательную гравитацию по оси Y. Значение -200 означает силу, тянущую частицы вверх, что вместе с начальной позицией внизу экрана создаёт эффект фонтана или водопада, текущего вверх.
- quantity: 2: Определяет, сколько частиц испускается за каждый цикл эмиссии. Небольшое значение обеспечивает разреженный, элегантный поток.
- sortProperty: 'y' и sortOrderAsc: false: Эти параметры включают сортировку частиц по их координате Y в порядке убывания (false для sortOrderAsc). Это критически важный приём для правильного отображения частиц, летящих друг за другом. Без сортировки частицы могут отрисовываться в порядке создания, что приведёт к визуальным артефактам, когда более далёкие (по Y) частицы перекрывают более близкие. Сортировка по Y гарантирует, что частицы, находящиеся «выше» (с меньшим значением Y, так как система координат начинается сверху), будут отрисованы поверх тех, что «ниже», создавая корректную глубину.
Настройка игры (Config)
Объект config определяет основные параметры игрового экземпляра Phaser.Game.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#000',
parent: 'phaser-example',
scene: Example
};
- type: Phaser.AUTO: Позволяет Phaser самостоятельно выбрать рендерер (WebGL или Canvas).
- width и height: Устанавливают размер игрового холста.
- backgroundColor: '#000': Чёрный фон, который будет виден до загрузки и отрисовки фона.
- parent: 'phaser-example': ID HTML-элемента, в который будет встроен canvas. В реальном проекте нужно заменить на соответствующий ID в вашем index.html.
- scene: Example: Указывает, что экземпляр нашего класса Example будет начальной сценой.
Инициализация игры происходит строкой new Phaser.Game(config).
Что попробовать дальше
Комбинируя управляемую случайность (start, end, random) с физическими свойствами (gravityY) и корректной сортировкой (sortProperty), мы создаём динамичный и визуально упорядоченный эффект парящих самоцветов. Для экспериментов попробуйте:
1. Изменить gravityY на положительное значение (например, 200), чтобы частицы падали вниз.
2. Добавить случайность для свойства scale или lifespan, используя аналогичный объект конфигурации.
3. Применить sortOrderAsc: true, чтобы увидеть, как инвертируется порядок отрисовки и «ломается» восприятие глубины.
4. Заменить текстуру gem на текстуру огня или дыма и настроить параметры для создания эффекта костра.
