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

Визуализация форм и контуров — фундаментальная задача в игровой разработке, будь то создание интерфейсов, отладка коллизий или генерация procedural-графики. Phaser предоставляет мощный и гибкий объект `Graphics` для рисования примитивов в реальном времени. В этой статье мы разберем, как с помощью метода `strokePath()` нарисовать произвольный замкнутый контур. Этот подход дает полный контроль над каждым сегментом линии, позволяя создавать стрелки, границы сложных областей или схематические изображения прямо в основном игровом цикле.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    graphics;

    create ()
    {
        this.graphics = this.add.graphics();

        const color = 0xffff00;
        const thickness = 4;
        const alpha = 1;

        this.graphics.lineStyle(thickness, color, alpha);

        this.graphics.beginPath();

        this.graphics.moveTo(400, 100);
        this.graphics.lineTo(200, 278);
        this.graphics.lineTo(340, 430);
        this.graphics.lineTo(650, 80);

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

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

const game = new Phaser.Game(config);

Подготовка холста: создание Graphics

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

this.graphics = this.add.graphics();

После создания this.graphics становится игровым объектом (Game Object), который можно добавлять на сцену, перемещать и трансформировать, как и любой другой спрайт.

Настройка стиля линии

Перед рисованием нужно определить, как будет выглядеть наша линия. Для этого используется метод lineStyle(). Он задает толщину, цвет и прозрачность для всех последующих операций рисования линий, пока стиль не будет изменен.

const color = 0xffff00; // Желтый цвет в HEX-формате
const thickness = 4;    // Толщина линии в пикселях
const alpha = 1;        // Полная непрозрачность (1 = 100%)

this.graphics.lineStyle(thickness, color, alpha);

Параметр alpha полезен для создания полупрозрачных контуров, например, для областей-подсказок.

Определение пути: beginPath, moveTo, lineTo

Рисование контура происходит в несколько этапов. Сначала мы объявляем начало нового пути, затем последовательно указываем его вершины.

this.graphics.beginPath(); // Начало определения нового пути

this.graphics.moveTo(400, 100); // Перемещаем "перо" в начальную точку (x, y)
this.graphics.lineTo(200, 278);  // Рисуем линию от текущей точки к новой
this.graphics.lineTo(340, 430);  // Продолжаем путь следующей линией
this.graphics.lineTo(650, 80);   // И еще одной

Важно: moveTo() не рисует линию, а только перемещает виртуальное перо. lineTo() рисует линию из текущей позиции пера в указанную точку, которая затем становится новой текущей позицией.

Замыкание и обводка контура

После того как все точки пути заданы, его можно замкнуть и отрисовать с заданным ранее стилем линии.

this.graphics.closePath(); // Автоматически рисует линию от последней точки к первой
this.graphics.strokePath(); // Выполняет обводку (отрисовку) всего накопленного пути

Метод closePath() очень удобен — он избавляет от необходимости вручную вызывать lineTo() для возврата в начальную точку. Метод strokePath() применяет стиль линии (lineStyle) ко всему описанному пути и выводит результат на экран. Без этого вызова контур будет определен, но не виден.

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

Весь код рисования помещается в метод create() сцены, который выполняется один раз при ее создании. Для запуска необходимо создать конфигурацию игры и экземпляр Phaser.Game.

const config = {
    width: 800,
    height: 600,
    type: Phaser.CANVAS, // Используем Canvas рендерер
    parent: 'phaser-example', // ID HTML-элемента для встраивания
    scene: Example // Наша основная сцена
};

const game = new Phaser.Game(config);

Указание type: Phaser.CANVAS гарантирует, что рисование через Graphics будет работать даже в средах без WebGL поддержки.

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

Методы beginPath(), moveTo(), lineTo() и strokePath() объекта Graphics образуют базовый, но мощный инструмент для программного рисования в Phaser. Вы можете управлять каждым сегментом контура независимо. **Идеи для экспериментов:** 1. Анимируйте контур, меняя координаты точек в методе update(). 2. Используйте lineTo() для визуализации пути движения NPC или траектории снаряда в режиме отладки. 3. Создайте сетку или схему уровня, генерируя точки в цикле. 4. Комбинируйте strokePath() с fillPath() для создания закрашенных фигур с контуром.