О чем этот пример
Эффекты частиц — это один из самых простых способов добавить живости и атмосферы в вашу игру. Но равномерный поток одинаковых частиц часто выглядит неестественно. В этой статье мы разберем пример, который показывает, как использовать генератор случайных чисел внутри конфигурации эмиттера частиц Phaser 3, чтобы создать более органичный и динамичный эффект. Вы научитесь управлять начальной позицией частиц по оси 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('slime', 'assets/particles/slime.png');
}
create ()
{
this.add.image(400, 300, 'bg');
// Picks a random value between the first and second array elements
this.add.particles(0, 0, 'slime', {
x: { random: [ 80, 720 ] },
lifespan: 2500,
gravityY: 200,
frequency: 80,
scale: { min: 0.6, max: 1.1 },
blendMode: 'ADD'
});
this.add.image(-100, 0, 'platform').setOrigin(0, 0);
this.add.image(412, 0, 'platform').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);
Загрузка ресурсов: основа для визуализации
Всё начинается с метода preload. Здесь мы загружаем три изображения, которые будут использоваться в сцене. Обратите внимание на использование this.load.setBaseURL() — это удобный способ задать базовый путь для всех последующих загрузок, что избавляет от необходимости писать полные URL для каждого ресурса.
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('slime', 'assets/particles/slime.png');
}
Первое изображение ('bg') станет фоном. Второе ('platform') — частью статичного окружения. А ключевой ресурс для нашей системы частиц — это текстура 'slime', которая будет использоваться для каждой создаваемой частицы.
Создание сцены: фон и декорации
В методе create мы сначала размещаем фоновое изображение по центру области отображения. Координаты (400, 300) соответствуют центру холста размером 800x600 пикселей, заданного в конфигурации игры.
this.add.image(400, 300, 'bg');
Затем мы добавляем два изображения платформ. Использование метода setOrigin(0, 0) устанавливает точку привязки (origin) изображения в его левый верхний угол. Это позволяет легко позиционировать их, начиная от координат (-100, 0) и (412, 0), создавая иллюзию длинной платформы, разорванной посередине.
this.add.image(-100, 0, 'platform').setOrigin(0, 0);
this.add.image(412, 0, 'platform').setOrigin(0, 0);
Сердце примера: конфигурация эмиттера частиц
Самая важная часть кода — это создание эмиттера частиц с помощью метода this.add.particles(). Первые три аргумента — это начальные координаты эмиттера (0, 0) и ключ текстуры ('slime').
Четвертый аргумент — это объект конфигурации, определяющий поведение всех частиц в этом эмиттере.
this.add.particles(0, 0, 'slime', {
x: { random: [ 80, 720 ] },
lifespan: 2500,
gravityY: 200,
frequency: 80,
scale: { min: 0.6, max: 1.1 },
blendMode: 'ADD'
});
Давайте разберем каждый параметр:
* `x: { random: [80, 720] }` — это ключевой параметр для нашей задачи. Вместо фиксированного значения, координата X для рождающейся частицы будет выбираться случайным образом из диапазона между 80 и 720 пикселями. Это создает эффект, будто частицы появляются по всей ширине экрана, а не из одной точки.
* `lifespan: 2500` — время жизни частицы в миллисекундах (2.5 секунды).
* `gravityY: 200` — сила гравитации, которая будет тянуть частицы вниз, создавая эффект падения.
* `frequency: 80` — интервал между испусканием частиц в миллисекундах. Частица будет создаваться каждые 80 мс.
* `scale: { min: 0.6, max: 1.1 }` — масштаб каждой частицы также будет случайным в заданном диапазоне, добавляя визуальное разнообразие.
* `blendMode: 'ADD'` — режим наложения цвета. `'ADD'` делает яркие области (как у текстуры `slime`) еще ярче при наложении, создавая эффект свечения.
Запуск игры: базовая конфигурация
Код вне класса Example содержит стандартную конфигурацию объекта игры Phaser. Мы указываем тип рендерера (Phaser.AUTO), размеры холста, цвет фона (который будет перекрыт нашим изображением), ID родительского HTML-элемента и нашу сцену.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#000',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Инициализация new Phaser.Game(config) создает и запускает игровой экземпляр, который начинает выполнять жизненный цикл нашей сцены (preload, create, update).
Что попробовать дальше
Использование объекта { random: [min, max] } для свойств эмиттера — это мощный и элегантный способ внести разнообразие в систему частиц, не усложняя логику сцены. Phaser сам обрабатывает случайность при создании каждой новой частицы. Для экспериментов попробуйте применить тот же принцип к другим свойствам: задайте случайный angle для разлета частиц веером, speedY для разной скорости падения или tint для разноцветного эффекта. Вы можете комбинировать несколько случайных свойств в одном эмиттере, чтобы создать чрезвычайно сложные и живые визуальные эффекты с минимальным количеством кода.
