О чем этот пример
Работа с геометрией — важная часть игровой разработки, будь то расчёт траекторий, генерация уровней или создание визуальных эффектов. Класс `Phaser.Geom.Polygon` предоставляет мощные инструменты для манипуляций с многоугольниками. В этой статье мы разберём практическое применение метода `getPoints`, который позволяет дискретизировать контур полигона — получить массив точек, равномерно распределённых по его периметру. Этот подход полезен для точечной отрисовки контура, создания цепочек частиц вдоль фигуры или для последующего физического моделирования.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
create ()
{
const graphics = this.add.graphics({ lineStyle: { width: 2, color: 0x00ff00 }, fillStyle: { color: 0xff0000 }});
const polygon = new Phaser.Geom.Polygon([
400, 100,
200, 278,
340, 430,
650, 80
]);
const points = polygon.getPoints(32);
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);
Что делает метод getPoints?
Метод getPoints(quantity) объекта Phaser.Geom.Polygon выполняет простую, но полезную задачу: он возвращает массив объектов Phaser.Geom.Point. Каждая точка лежит на периметре полигона. Ключевая особенность — точки распределяются равномерно по всей длине контура, а не просто по вершинам. Это позволяет работать с полигоном как с плавной линией.
Аргумент quantity определяет, сколько точек мы хотим получить. Чем больше значение, тем выше «разрешение» контура — точки будут расположены ближе друг к другу. В исходном примере используется значение 32, что даёт достаточно детализированное представление формы.
Разбор примера: создание и визуализация
Рассмотрим код по порядку. Сначала создаётся полигон с четырьмя вершинами. Координаты передаются в конструктор простым плоским массивом в формате [x1, y1, x2, y2, ...].
const polygon = new Phaser.Geom.Polygon([
400, 100,
200, 278,
340, 430,
650, 80
]);
Далее вызывается целевой метод для получения 32 точек по периметру.
const points = polygon.getPoints(32);
Теперь в переменной points лежит массив из 32 объектов. Каждый объект имеет свойства `xиy. Чтобы их увидеть, пример последовательно рисует в каждой позиции маленький квадратик с помощью графики (Graphics`).
for (let i = 0; i < points.length; i++)
{
const p = points[i];
graphics.fillRect(p.x - 4, p.y - 4, 8, 8);
}
Обратите внимание на смещение на -4: метод fillRect рисует прямоугольник от указанной координаты, поэтому мы сдвигаем точку влево-вверх на половину размера квадрата (8/2=4), чтобы точка оказалась в его центре.
Практическое применение в играх
Зачем может понадобиться такой массив точек в реальном проекте? Вот несколько идей:
* **Траектории и патрулирование:** Полученные точки можно использовать как узлы пути для NPC или снаряда, движущегося вдоль сложной формы.
* **Визуальные эффекты:** На каждой точке можно создать частицу (Particle) или спрайт, создав эффект свечения, электрического разряда или пунктирного контура.
* **Коллайдеры для сложных форм:** Хотя для физики обычно используют более специализированные методы, массив точек может стать основой для построения пользовательского контура столкновений.
* **Генерация контента:** Равномерно распределённые точки подходят для расстановки декораций (камней, растений) вдоль заранее заданной границы области.
Важно: метод возвращает точки именно на периметре, а не внутри полигона. Для заполнения внутренности потребуются другие подходы, например, Phaser.Geom.Polygon.GetPoints с иным алгоритмом.
Влияние количества точек на результат
Давайте поэкспериментируем с аргументом quantity. Разное количество точек кардинально меняет результат.
// Мало точек — видна грубая структура периметра
const sparsePoints = polygon.getPoints(8);
// Много точек — контур выглядит почти сплошным
const densePoints = polygon.getPoints(128);
При малом количестве (например, 4-8) точки будут стоять в основном на длинных рёбрах, и форма может читаться плохо. При большом количестве (64-128) квадратики начнут сливаться, формируя почти непрерывную линию. Оптимальное значение зависит от задачи: для расстановки объектов хватит и 20-30, для плавной визуализации — больше 50.
Попробуйте в примере заменить число 32 на 8 или 64 и увидите разницу.
Что попробовать дальше
Метод getPoints — это ваш инструмент для превращения статичного полигона в динамичный набор координат, готовый к использованию в игровой логике. Он стирает грань между векторной формой и дискретными данными, открывая возможности для визуализации и симуляции.
**Идеи для экспериментов:**
1. Сделайте анимацию: перемещайте спрайт от одной полученной точки к следующей, создав движение по контуру.
2. Соедините точки не квадратами, а линиями, используя graphics.lineBetween, и сравните с прямой отрисовкой полигона.
3. Сгенерируйте полигон случайной формы и примените getPoints к нему, чтобы создать непредсказуемый патрульный путь.
