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

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

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        const polygon = new Phaser.Geom.Polygon([
            400, 100,
            200, 278,
            340, 430,
            650, 80
        ]);

        const graphics = this.add.graphics({ x: 0, y: 0 });

        graphics.lineStyle(2, 0x00aa00);

        graphics.beginPath();

        graphics.moveTo(polygon.points[0].x, polygon.points[0].y);

        for (let i = 1; i < polygon.points.length; i++)
        {
            graphics.lineTo(polygon.points[i].x, polygon.points[i].y);
        }

        graphics.closePath();
        graphics.strokePath();
    }
}

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

const game = new Phaser.Game(config);

Создание экземпляра полигона

Класс Phaser.Geom.Polygon позволяет описать произвольный многоугольник. Его конструктор принимает массив чисел, где каждая пара значений представляет собой координаты X и Y одной вершины.

const polygon = new Phaser.Geom.Polygon([
    400, 100, // Точка 1 (x, y)
    200, 278, // Точка 2
    340, 430, // Точка 3
    650, 80   // Точка 4
]);

В данном примере создается четырехугольник. Порядок точек важен, так как он определяет, как будут соединяться вершины. Phaser автоматически конвертирует этот плоский массив в массив объектов Phaser.Geom.Point, доступный через свойство polygon.points.

Подготовка графического контекста

Для отрисовки примитивов в Phaser используется объект Graphics. Он работает как канвас для векторной графики. Создадим его в начале сцены, указав начальное смещение (в нашем случае — 0).

const graphics = this.add.graphics({ x: 0, y: 0 });

Далее задаем стиль линии для будущего контура полигона. Метод lineStyle принимает толщину линии (в пикселях) и цвет в числовом формате (hex).

graphics.lineStyle(2, 0x00aa00);

Перед началом рисования необходимо вызвать beginPath(). Это сообщает системе, что мы начинаем новый векторный путь.

graphics.beginPath();

Рисование контура по точкам

Отрисовка контура полигона — это последовательное соединение его вершин линиями. Сначала мы перемещаем "перо" к первой точке без рисования с помощью moveTo.

graphics.moveTo(polygon.points[0].x, polygon.points[0].y);

Затем в цикле проходим по всем остальным точкам массива polygon.points и рисуем линию к каждой следующей вершине командой lineTo.

for (let i = 1; i < polygon.points.length; i++)
{
    graphics.lineTo(polygon.points[i].x, polygon.points[i].y);
}

После соединения всех вершин нужно замкнуть фигуру, вернувшись к начальной точке. Метод closePath() делает это автоматически.

graphics.closePath();

И, наконец, чтобы увидеть нарисованный контур на экране, необходимо вызвать strokePath(), который выполняет обводку по заданному пути.

graphics.strokePath();

Конфигурация и запуск игры

Код примера завершается стандартной для Phaser конфигурацией игры. В ней задается размер холста, указывается тип рендерера (Phaser.AUTO выбирает между WebGL и Canvas) и определяется основная сцена.

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

const game = new Phaser.Game(config);

После создания экземпляра Phaser.Game с этой конфигурацией автоматически запускается жизненный цикл сцены, вызывается метод create(), и на экране отрисовывается зеленый полигон.

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

Вы освоили базовый принцип создания и отрисовки полигонов в Phaser. Этот навык открывает путь к более сложным задачам. Для экспериментов попробуйте

  1. Заполнить полигон цветом с помощью graphics.fillPath() после задания стиля заливки fillStyle
  2. Использовать Phaser.Geom.Polygon.Contains для проверки, находится ли курсор или игрок внутри этой области
  3. Динамически изменять координаты точек в методе update(), чтобы создать анимированную деформирующуюся фигуру