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

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

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        const graphics = this.add.graphics();

        graphics.fillStyle(0xffff00, 1);

        graphics.slice(400, 300, 200, Phaser.Math.DegToRad(340), Phaser.Math.DegToRad(20), true);

        graphics.fillPath();
    }
}

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

const game = new Phaser.Game(config);

Основы: объект Graphics

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

Для начала работы нужно создать экземпляр Graphics в методе create сцены.

Анализ кода: шаг за шагом

Давайте разберем пример, который рисует желтую арку, напоминающую рот Пакмана.

Сначала создается объект Graphics и задается цвет заливки.

const graphics = this.add.graphics();
graphics.fillStyle(0xffff00, 1);

Метод this.add.graphics() добавляет объект на сцену. fillStyle(0xffff00, 1) устанавливает цвет заливки (желтый) и альфа-канал (полная непрозрачность).

Далее определяется форма фигуры — сектор (slice) или арка.

graphics.slice(400, 300, 200, Phaser.Math.DegToRad(340), Phaser.Math.DegToRad(20), true);

Метод slice описывает контур. Его параметры: 1. **400, 300:** Координаты X и Y центра арки. 2. **200:** Радиус арки. 3. **Phaser.Math.DegToRad(340):** Начальный угол в радианах. Мы используем вспомогательную функцию DegToRad для перевода 340 градусов. 4. **Phaser.Math.DegToRad(20):** Конечный угол в радианах (20 градусов). 5. **true:** Отрисовка по часовой стрелке.

И, наконец, команда на отрисовку (заливку) описанного контура.

graphics.fillPath();

Без вызова fillPath() (или strokePath() для контура) фигура не появится на экране. Все команды типа slice или lineTo только запоминают путь, который нужно отрендерить этим методом.

Как это работает: от пути к пикселям

Работа с Graphics следует парадигме "путь-заливка". Сначала вы последовательно описываете геометрический путь с помощью команд вроде slice, lineTo, arc или circle. Эти команды только сохраняют математическое описание фигуры в памяти.

Затем вы вызываете либо fillPath() для заливки внутренней области текущим fillStyle, либо strokePath() для обводки контура текущим lineStyle. Именно этот вызов и отправляет финальную инструкцию на отрисовку. Это разделение позволяет гибко комбинировать и модифицировать пути перед их финальной визуализацией.

Идеи для модификации и применения

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

**Анимация:** Добавьте в метод update сцены изменение углов или радиуса, чтобы арка открывалась и закрывалась.

update(time, delta) {
    this.graphics.clear(); // Очистить предыдущий кадр
    this.graphics.fillStyle(0xffff00, 1);
    // Динамически меняем угол, например, с помощью Math.sin(time)
    const currentAngle = Phaser.Math.DegToRad(340) + Math.sin(time * 0.001) * 0.5;
    this.graphics.slice(400, 300, 200, currentAngle, Phaser.Math.DegToRad(20), true);
    this.graphics.fillPath();
}

**Создание спрайта:** Фигуру Graphics можно превратить в текстуру и использовать как обычный спрайт, что полезно для статичных, но генерируемых объектов.

const graphics = this.add.graphics();
// ... нарисовать что-то в graphics
const texture = graphics.generateTexture('pacmanHead', 800, 600);
this.add.image(100, 100, 'pacmanHead');

**Применения:** Помимо прототипов, Graphics отлично подходит для полос здоровья, радиусов атак, указателей, простых эффектов (вспышек, волн) и отладки коллайдеров.

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

Объект Graphics в Phaser — это ваш швейцарский нож для создания динамической векторной графики прямо в коде. Начиная с простой арки, вы можете строить сложные фигуры, анимировать их и даже генерировать текстуры для спрайтов. Для экспериментов попробуйте: заменить slice на circle или triangle; добавить обводку lineStyle перед strokePath; создать составную фигуру из нескольких путей. Это откроет путь к созданию уникальной игровой графики без редакторов.