О чем этот пример

При создании игр часто возникает задача работы со сложными формами. Разбивка многоугольника на простейшие элементы — треугольники — это ключевой шаг для решения множества задач: от создания сложных коллайдеров до реализации собственной физики и геометрических эффектов. Phaser предоставляет для этого удобный инструмент. В этой статье мы разберем метод `Triangle.BuildFromPolygon`, который автоматически преобразует любой многоугольник в набор треугольников. Это мощный, но часто упускаемый из виду инструмент в геометрическом арсенале Phaser, полезный для генерации уровней, разрушаемых объектов или визуализации областей.

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        const graphics = this.add.graphics({ lineStyle: { width: 1, color: 0x00ff00, alpha: 1 }, x: 64, y: 64 });

        const poly = [ 0,0, 400,0, 400,400, 0,400 ]; // rectangle

        const triangles = new Phaser.Geom.Triangle.BuildFromPolygon(poly);

        for (let i = 0; i < triangles.length; i++)
        {
            graphics.strokeTriangleShape(triangles[i]);
        }
    }
}

const config = {
    width: 800,
    height: 600,
    type: Phaser.AUTO,
    parent: 'phaser-example',
    scene: Example
};

const game = new Phaser.Game(config);

Что делает метод BuildFromPolygon?

Статический метод Phaser.Geom.Triangle.BuildFromPolygon принимает на вход плоский массив координат вершин полигона и возвращает массив объектов Phaser.Geom.Triangle. Каждый такой объект представляет собой один из треугольников, из которых состоит исходная фигура.

Этот процесс называется триангуляцией. Phaser использует простой, но эффективный алгоритм "уха" (ear clipping) для выпуклых или вогнутых многоугольников. Результат — разбиение сложной формы на примитивы, с которыми гораздо проще работать в дальнейшем.

// Исходный полигон — обычный квадрат, заданный плоским массивом [x1, y1, x2, y2, ...]
const poly = [ 0,0, 400,0, 400,400, 0,400 ];

// Магия триангуляции происходит здесь
const triangles = new Phaser.Geom.Triangle.BuildFromPolygon(poly);

Чтение и визуализация результата

Метод возвращает массив. Даже для такого простого полигона, как квадрат, результат будет содержать два треугольника. Это минимальное количество треугольников, необходимых для представления четырехугольника.

Для отрисовки результата мы можем перебрать массив triangles в цикле и использовать метод strokeTriangleShape у объекта Graphics. Этот метод принимает объект треугольника и рисует его контур.

// Создаем графический контекст для рисования
const graphics = this.add.graphics({
    lineStyle: { width: 1, color: 0x00ff00, alpha: 1 },
    x: 64,
    y: 64
});

// Перебираем все полученные треугольники и рисуем их
for (let i = 0; i < triangles.length; i++) {
    graphics.strokeTriangleShape(triangles[i]);
}

В результате на экране вы увидите квадрат, разделенный по диагонали на два зеленых треугольника.

Практическое применение: от коллайдеров до эффектов

Зачем это нужно? Треугольники — это фундаментальные примитивы. Вот несколько идей для их использования:

* **Сложные коллайдеры:** Вы можете создать составной коллайдер для нестандартного объекта, проверив пересечение с каждым его треугольником. * **Генерация меша:** Полученные треугольники — готовая сетка для заливки градиентом или текстурой. * **Логика областей:** Разбейте карту уровня на полигональные зоны, а затем на треугольники, чтобы точно определять, в какой зоне находится игрок. * **Разрушаемые объекты:** Изначальный полигон — это целый объект. После "попадания" вы можете физически разбить его, удалив один или несколько треугольников из массива.

Ключевой момент: метод работает с любым многоугольником. Попробуйте передать ему координаты звезды или буквы 'Ш'.

Важные ограничения и требования к данным

Чтобы метод BuildFromPolygon работал корректно, необходимо соблюдать несколько условий:

1. **Порядок вершин:** Координаты в массиве должны следовать по порядку (по или против часовой стрелки), описывая контур полигона без самопересечений. 2. **Плоский массив:** Данные должны быть в формате [x1, y1, x2, y2, x3, y3, ...]. Массив массивов [[x1,y1], ...] не подойдет. 3. **Минимум 3 вершины:** Очевидно, для создания треугольника нужны как минимум 3 точки (6 значений в массиве).

// Пример корректного многоугольника (треугольник)
const correctPoly = [ 100, 100, 300, 50, 200, 300 ];

// Пример НЕкорректных данных (массив массивов)
const incorrectPoly = [ [100, 100], [300, 50], [200, 300] ]; // Это вызовет ошибку.

Всегда проверяйте, что ваш полигон корректен, прежде чем передавать его на триангуляцию.

Что попробовать дальше

Метод Phaser.Geom.Triangle.BuildFromPolygon — это ваш надежный союзник для работы со сложной геометрией. Он превращает нетривиальную задачу разбиения полигона в одну строку кода, открывая путь к созданию динамичных коллайдеров, визуальных эффектов и игровой логики. **Идеи для экспериментов:** 1. Сгенерируйте случайный вогнутый полигон (например, "галочку") и визуализируйте его триангуляцию. 2. Реализуйте проверку попадания курсора в составную фигуру, проверяя попадание в каждый ее треугольник с помощью Phaser.Geom.Triangle.Contains. 3. Создайте анимацию "распада" объекта, постепенно удаляя треугольники из массива и перерисовывая оставшиеся.