О чем этот пример
Работа с геометрией — важная часть разработки игр. Например, вам может понадобиться равномерно разместить объекты вдоль границы фигуры для создания патрулей, эффектов или UI-элементов. В Phaser для этого есть удобный метод `getPoints()` у геометрического объекта `Triangle`. В этой статье мы разберем, как им пользоваться, какие параметры он принимает и как визуализировать результат.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
create ()
{
const graphics = this.add.graphics({ lineStyle: { width: 1, color: 0x00ff00 }, fillStyle: { color: 0xffff00 }});
// triangle = new Phaser.Geom.Triangle.BuildEquilateral(400, 200, 300);
// triangle = new Phaser.Geom.Triangle.BuildRight(200, 400, 300, 200);
// Random
const x1 = Phaser.Math.Between(50, 400);
const y1 = Phaser.Math.Between(50, 300);
const x2 = Phaser.Math.Between(450, 750);
const y2 = Phaser.Math.Between(50, 300);
const x3 = Phaser.Math.Between(50, 750);
const y3 = Phaser.Math.Between(350, 550);
const triangle = new Phaser.Geom.Triangle(x1, y1, x2, y2, x3, y3);
graphics.strokeTriangleShape(triangle);
// Get 64 points around the triangle
const points = triangle.getPoints(32);
// Every point will be 50px apart (note the 'false' given for the quantity argument)
// If the stepRate doesn't divide equally into the triangle dimensions then you'll get offset values at the end
// var points = triangle.getPoints(false, 50);
for (let i = 0; i < points.length; i++)
{
const p = points[i];
graphics.fillRect(p.x - 4, p.y - 4, 8, 8);
}
}
}
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Создаем произвольный треугольник
Перед тем как получать точки, нужен сам треугольник. В примере используется конструктор Phaser.Geom.Triangle, принимающий координаты трех вершин.
const x1 = Phaser.Math.Between(50, 400);
const y1 = Phaser.Math.Between(50, 300);
const x2 = Phaser.Math.Between(450, 750);
const y2 = Phaser.Math.Between(50, 300);
const x3 = Phaser.Math.Between(50, 750);
const y3 = Phaser.Math.Between(350, 550);
const triangle = new Phaser.Geom.Triangle(x1, y1, x2, y2, x3, y3);
Для наглядности мы рисуем контур треугольника с помощью графического объекта Graphics и метода strokeTriangleShape().
Метод `getPoints()`: количество точек или шаг
Ключевой метод статьи — triangle.getPoints(). Он может работать в двух режимах, в зависимости от переданных аргументов.
**Первый режим:** Указываем количество точек на *каждой* стороне треугольника. Метод равномерно распределит их по периметру. В примере запрашивается 32 точки на сторону, но итоговое количество будет 64. Почему? Потому что каждая вершина принадлежит двум сторонам и метод, чтобы избежать дублирования точек в углах, возвращает массив, где общие вершины не повторяются.
// Получить 32 точки на каждую сторону (итого ~64 точки по периметру)
const points = triangle.getPoints(32);
**Второй режим:** Указываем шаг в пикселях между точками. Для этого первым аргументом передаем false, а вторым — желаемое расстояние.
// Получить точки, расположенные с шагом в 50 пикселей вдоль сторон
const points = triangle.getPoints(false, 50);
Важно: если длина стороны не кратна шагу, последняя точка на стороне может не совпасть с вершиной, что приведет к небольшому смещению интервала.
Визуализация результата
Метод getPoints() возвращает массив объектов с координатами `xиy`. Чтобы увидеть, где именно расположены точки, мы можем их нарисовать.
В примере используется цикл, который проходит по всем точкам и рисует в их координатах маленькие квадратики с помощью graphics.fillRect(). Центр квадрата смещается на половину его ширины и высоты, чтобы точка оказалась ровно посередине фигуры.
for (let i = 0; i < points.length; i++)
{
const p = points[i];
graphics.fillRect(p.x - 4, p.y - 4, 8, 8);
}
Таким образом, мы получаем четкую визуализацию того, как распределяются точки по периметру треугольника при разных настройках.
Практическое применение в играх
Зачем это может пригодиться? Вот несколько идей: * **Маршрут патруля:** Создать путь для NPC, который ходит вдоль треугольной зоны. * **Размещение объектов:** Равномерно расставить декорации (фонари, камни) вдоль границы области. * **Эффекты частиц:** Запустить частицы не из одной точки, а вдоль всей линии, например, для эффекта "энергетического щита". * **Построение сетки или зоны:** Использовать точки как опорные для более сложных расчетов или отрисовки.
Метод работает не только с Triangle, но и с другими геометрическими объектами Phaser, такими как Line, Rectangle и Circle, что делает его универсальным инструментом.
Что попробовать дальше
Метод getPoints() геометрического объекта Triangle — это мощный и гибкий инструмент для получения координат вдоль периметра фигуры. Вы можете контролировать детализацию, задавая либо точное количество точек на сторону, либо фиксированное расстояние между ними. Поэкспериментируйте: попробуйте анимировать полученные точки, создав вдоль них движение спрайтов, или скомбинируйте несколько треугольников для построения сложного пути.
