О чем этот пример
При создании игр часто возникает задача разместить множество объектов (врагов, бонусов, декораций) в определённой области не вручную, а случайным образом. Phaser предоставляет для этого простой и эффективный инструмент — `Phaser.Actions.RandomRectangle`. Эта статья покажет, как с его помощью одним вызовом заполнить прямоугольную зону сотнями спрайтов, что незаменимо для генерации уровней, создания партикловых эффектов или расстановки игровых элементов.
Версия 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 });
const rect = new Phaser.Geom.Rectangle(300, 300, 300, 100);
// Randomly position the sprites within the rectangle
Phaser.Actions.RandomRectangle(group.getChildren(), rect);
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Подготовка сцены и создание группы спрайтов
Вся магия происходит в методе create() нашей сцены. Первым делом нам нужно создать множество объектов, которые мы будем распределять. Вместо ручного создания каждого спрайта используется мощный механизм групп (Group).
const group = this.add.group({ key: 'orb', frameQuantity: 300 });
Этот код создаёт группу и сразу наполняет её 300 спрайтами, используя изображение 'orb', загруженное в preload(). Важный нюанс: все созданные спрайты изначально имеют координаты (0, 0) и накладываются друг на друга в верхнем левом углу холста.
Определение целевой области
Чтобы распределить спрайты, нужно задать границы области. Для этого создаётся объект Phaser.Geom.Rectangle.
const rect = new Phaser.Geom.Rectangle(300, 300, 300, 100);
Конструктор принимает четыре параметра: координаты X и Y левого верхнего угла прямоугольника, а затем его ширину и высоту. В нашем примере создаётся горизонтальная область шириной 300 пикселей и высотой 100 пикселей, начинающаяся в точке (300, 300).
Случайное распределение объектов
Самый важный шаг — вызов метода Phaser.Actions.RandomRectangle. Этот метод является частью статического класса Phaser.Actions, предназначенного для массовых операций над объектами.
Phaser.Actions.RandomRectangle(group.getChildren(), rect);
Метод принимает два аргумента. Первый — массив объектов для изменения. Мы получаем его через group.getChildren(). Второй — созданный нами прямоугольник rect. Внутри метод перебирает все переданные объекты и присваивает каждому случайные координаты `xиy`, которые гарантированно попадают внутрь заданного прямоугольника.
Как это работает под капотом?
После вызова RandomRectangle координаты `xиy` каждого спрайта в группе перезаписываются. Новые значения вычисляются по простой формуле:
- x = rect.x + Math.random() * rect.width
- y = rect.y + Math.random() * rect.height
Math.random() генерирует число от 0 до 1, которое масштабируется на ширину и высоту прямоугольника и прибавляется к его начальным координатам. Это обеспечивает равномерное случайное распределение по всей площади фигуры. Все изменения применяются мгновенно за один проход.
Что попробовать дальше
Phaser.Actions.RandomRectangle — это лаконичный и производительный способ заполнить игровую область объектами. Он идеален для создания полей астероидов, рощ деревьев, толп персонажей или облаков частиц. Для экспериментов попробуйте изменить размеры и положение прямоугольника, анимацию спрайтов после распределения или комбинируйте этот вызов с другими методами из Phaser.Actions, например, Call для назначения каждому объекту уникального поведения.
