О чем этот пример
Создание естественных или геометрически точных расположений объектов — частая задача при разработке игр. Вручную расставлять десятки деревьев, врагов или элементов декора утомительно и подвержено ошибкам. В этой статье мы разберем, как использовать встроенный в Phaser 3 класс `Phaser.Actions` для моментального размещения группы спрайтов по окружности.
Версия 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('bg', 'assets/textures/soil.png');
this.load.image('tree', 'assets/sprites/tree.png');
}
create ()
{
this.add.tileSprite(400, 300, 800, 600, 'bg').setTileScale(0.25);
const circle = new Phaser.Geom.Circle(400, 300, 220);
const trees = [];
for (let i = 0; i < 32; i++)
{
trees.push(this.add.image(0, 0, 'tree'));
}
Phaser.Actions.PlaceOnCircle(trees, circle);
// Depth sort based on y value
trees.forEach(tree => {
tree.setDepth(tree.y);
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
pixelArt: true,
scene: Example
};
const game = new Phaser.Game(config);
Что делает код из примера?
Код загружает текстуру земли и спрайт дерева, затем создает фон с помощью TileSprite. Основная магия происходит в методе create():
1. Создается геометрический объект Phaser.Geom.Circle, который задает форму и положение для размещения объектов.
2. В цикле создается массив из 32 спрайтов дерева, но пока без заданных координат.
3. Одна строка кода с Phaser.Actions.PlaceOnCircle() мгновенно расставляет все спрайты из массива по заданной окружности.
4. Финальный цикл настраивает глубину отрисовки (depth) для каждого дерева в зависимости от его Y-координаты, создавая корректное перекрытие спрайтов.
Этот подход экономит десятки строк ручного расчета позиций с помощью тригонометрии.
Подробнее о Phaser.Actions.PlaceOnCircle
Метод PlaceOnCircle — это статический хелпер, который модифицирует свойство `xиy` у каждого элемента переданного массива. Он не требует создания специальных контейнеров или групп.
Phaser.Actions.PlaceOnCircle(itemsArray, circleGeometry);
* itemsArray: Массив любых объектов, у которых есть числовые свойства `xиy. Идеально подходят игровые объекты Phaser, такие какImageилиSprite`.
* circleGeometry: Экземпляр объекта Phaser.Geom.Circle, который определяет центр и радиус для размещения.
Код внутри метода равномерно распределяет элементы по полной окружности в 360 градусов. Первый элемент будет размещен на позиции 0° (самая правая точка круга), последний — чуть меньше 360°.
Создание геометрического круга
Ключ к управлению расположением — объект Phaser.Geom.Circle. Его параметры легко понять и изменить.
// new Phaser.Geom.Circle(x, y, radius)
const circle = new Phaser.Geom.Circle(400, 300, 220);
* `x,y`: Координаты центра круга на вашей сцене. В примере это центр экрана (800x600 / 2).
* radius: Радиус круга. Чем он больше, тем дальше от центра будут расположены спрайты.
Вы можете динамически менять эти параметры после создания круга, чтобы анимировать расположение объектов или реагировать на действия игрока.
Сортировка глубины для реалистичности
После размещения по кругу все деревья находятся в одной плоскости. Чтобы создать иллюзию 2.5D, где объекты на переднем плане перекрывают задние, используется сортировка по глубине.
trees.forEach(tree => {
tree.setDepth(tree.y);
});
Здесь для каждого дерева устанавливается свойство depth равное его Y-координате. Поскольку в системе координат Phaser ось Y направлена вниз, деревья в нижней части экрана (с большим значением `y`) получают большую глубину и будут отрисовываться поверх тех, что выше. Это стандартный прием для изометрических или видов сверху игр.
Практические идеи для ваших игр
PlaceOnCircle — это лишь один из многих полезных методов в классе Phaser.Actions. Вот как можно использовать эту технику:
* **Формирование врагов:** Создайте "круглую" атаку босса, где мини-враги появляются по окружности и движутся к центру.
* **Круговое меню:** Расположите иконки способностей или предметов вокруг аватара игрока.
* **Эффекты частиц:** Задайте начальную область эмиттера частиц в форме кольца.
* **Комбинирование действий:** Используйте PlaceOnCircle вместе с Phaser.Actions.RotateAround для создания вращающегося формирования.
// Пример: вращение объектов после размещения
Phaser.Actions.RotateAround(trees, {x: 400, y: 300}, 0.01);
// Эту строку нужно выполнять в update() для анимации.
Что попробовать дальше
Использование Phaser.Actions для размещения объектов — это мощный и эффективный подход, который избавляет от рутинных математических расчетов. Метод PlaceOnCircle позволяет одним вызовом решить задачу равномерного кругового распределения.
**Для экспериментов попробуйте:**
1. Заменить PlaceOnCircle на PlaceOnEllipse или PlaceOnRectangle для других форм.
2. Динамически менять радиус круга в update(), чтобы спрайты сжимались к центру или расходились.
3. Привязать положение круга к координатам спрайта игрока, создавая персональную зону эффектов.
