О чем этот пример
Создание игровых сцен часто требует размещения десятков или сотен объектов в определенной области. Делать это вручную — долго и неэффективно. В этой статье мы разберем, как с помощью одного вызова `Phaser.Actions.RandomEllipse` можно мгновенно распределить множество спрайтов внутри эллипса, создав интересные визуальные эффекты или скопления объектов, например, стаю птиц или россыпь звёзд. Этот метод не только экономит время, но и добавляет вашей сцене элемент естественной, управляемой случайности.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
constructor ()
{
super();
}
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('orb', 'assets/sprites/orb-blue.png');
}
create ()
{
// Create 300 sprites (they all start life at 0x0)
const group = this.add.group({ key: 'orb', frameQuantity: 300 });
this.ellipse = new Phaser.Geom.Ellipse(400, 300, 100, 200);
// Randomly position the sprites within the ellipse
Phaser.Actions.RandomEllipse(group.getChildren(), this.ellipse);
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Подготовка сцены и создание группы спрайтов
Первый шаг — загрузка ресурса и создание множества одинаковых объектов. Вместо ручного создания каждого спрайта мы используем Group, который отлично подходит для управления множеством однотипных объектов.
В методе preload загружается одно изображение. Затем, в create, с помощью конфигурационного объекта создается группа из 300 спрайтов. Все они изначально имеют координаты (0, 0). Ключевой параметр frameQuantity указывает, сколько копий спрайта 'orb' нужно создать.
const group = this.add.group({ key: 'orb', frameQuantity: 300 });
Определение области размещения: геометрия эллипса
Чтобы случайным образом распределить спрайты, нужно задать границы области. В Phaser для этого есть объекты геометрии. Мы создаем экземпляр Phaser.Geom.Ellipse.
Конструктор принимает четыре аргумента: координаты центра по осям X и Y, а затем ширину и высоту эллипса. В нашем примере эллипс расположен в центре экрана (400, 300) и имеет ширину 100 и высоту 200 пикселей. Этот объект будет использоваться как маска для размещения.
this.ellipse = new Phaser.Geom.Ellipse(400, 300, 100, 200);
Массовое распределение объектов: Phaser.Actions.RandomEllipse
Самый важный этап — применение действия (Action) к массиву объектов. Phaser.Actions.RandomEllipse — это статический метод, который принимает массив игровых объектов (в нашем случае — детей группы) и объект Ellipse. Он перебирает все объекты в массиве и задает каждой случайную позицию (x, y) внутри заданного эллипса.
Метод group.getChildren() возвращает массив всех спрайтов, созданных в группе. После вызова действия все 300 сфер мгновенно "разбросаны" внутри эллиптической области.
Phaser.Actions.RandomEllipse(group.getChildren(), this.ellipse);
Сборка всего вместе: конфигурация игры
Для запуска примера необходима стандартная конфигурация игры Phaser. В ней указывается тип рендерера, размеры холста, цвет фона, ID родительского HTML-элемента и класс нашей сцены Example. Создание экземпляра Phaser.Game с этой конфигурацией инициирует выполнение всех описанных методов: preload, create и далее игрового цикла.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что попробовать дальше
Использование Phaser.Actions.RandomEllipse — это мощный и лаконичный способ наполнить сцену объектами по заданной форме. Для экспериментов попробуйте изменить параметры эллипса (сделать его кругом или очень вытянутым), анимировать сам эллипс, перемещая его центр, и затем повторно применять действие для создания динамических скоплений. Также можно комбинировать это действие с другими, например, RandomCircle или PlaceOnCircle, для создания более сложных паттернов расстановки.
