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

Дуги — фундаментальные примитивы для создания интерфейсов, прогресс-баров, эффектов и визуализаций в играх. Phaser предоставляет мощный и гибкий метод `this.add.arc()` для их отрисовки прямо на канвасе, без необходимости загружать текстуры. Эта статья покажет, как создавать, стилизовать и анимировать дуги, используя возможности рендерера.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('bg', 'assets/skies/background1.png');
    }

    create ()
    {
        this.add.image(400, 300, 'bg');

        const r1 = this.add.arc(200, 200, 80, 0, 240, false, 0x6666ff);

        const r2 = this.add.arc(400, 200, 80, 240, 360, false, 0x9966ff);

        r2.setStrokeStyle(4, 0xefc53f);

        const r3 = this.add.arc(600, 200, 80, 180, 360, false);

        r3.setStrokeStyle(2, 0x1a65ac);

        const r4 = this.add.arc(200, 400, 80, 0, 180, false, 0xff6699);

        const r5 = this.add.arc(400, 400, 80, 90, 240, true, 0xff33cc);

        const r6 = this.add.arc(600, 400, 80, 0, 180, false, 0xff66ff);

        //  WebGL only
        r6.setIterations(0.2);

        this.tweens.add({

            targets: r4,
            scaleX: 0.25,
            scaleY: 0.5,
            yoyo: true,
            repeat: -1,
            ease: 'Sine.easeInOut'

        });

        this.tweens.add({

            targets: r5,
            alpha: 0.2,
            yoyo: true,
            repeat: -1,
            ease: 'Sine.easeInOut'

        });

        this.tweens.add({

            targets: r6,
            angle: 90,
            yoyo: true,
            repeat: -1,
            ease: 'Sine.easeInOut'

        });
    }
}

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

const game = new Phaser.Game(config);

Создание базовой дуги

Метод this.add.arc() создает и добавляет на сцену новый игровой объект типа Arc. Его основные параметры управляют геометрией и внешним видом фигуры.

const r1 = this.add.arc(200, 200, 80, 0, 240, false, 0x6666ff);

Разберем аргументы по порядку: 1. **X, Y (200, 200)** — координаты центра дуги. 2. **Радиус (80)** — расстояние от центра до кривой. 3. **Начальный угол (0)** — угол в градусах, откуда начинается дуга. Ноль соответствует направлению "на восток" (3 часа). 4. **Конечный угол (240)** — угол в градусах, где дуга заканчивается. 5. **Закрыта ли дуга (false)** — если true, Phaser соединит концы дуги с центром, создавая сектор ("кусок пирога"). 6. **Цвет заливки (0x6666ff)** — шестнадцатеричный цвет, которым будет залита внутренняя область дуги. Если цвет не указан, дуга будет отрисована только контуром.

Стилизация: контур и заливка

По умолчанию дуга рисуется с заливкой. Вы можете управлять толщиной и цветом ее контура с помощью метода setStrokeStyle().

r2.setStrokeStyle(4, 0xefc53f);

Здесь мы задаем дуге r2 контур толщиной 4 пикселя золотистого цвета (0xefc53f). Этот метод применяется к уже созданному объекту.

Если при создании не указать цвет заливки, дуга будет отрисована только контуром с текущим стилем линии.

const r3 = this.add.arc(600, 200, 80, 180, 360, false);
r3.setStrokeStyle(2, 0x1a65ac);

В этом примере r3 создается без заливки, а затем ей задается тонкий синий контур.

Создание сектора и анти-часовой порядок

Пятый аргумент метода arc отвечает за создание не просто дуги, а целого сектора.

const r5 = this.add.arc(400, 400, 80, 90, 240, true, 0xff33cc);

Ключевое отличие здесь — параметр true. Он указывает Phaser соединить конечные точки дуги с центром, создавая замкнутую фигуру в форме "куска пирога".

Важно отметить, что углы в Phaser задаются в градусах и отсчитываются **по часовой стрелке**. Угол 0° — это направление вправо. Таким образом, дуга от 90° до 240° будет проходить через нижнюю часть круга.

Анимация свойств дуги

Как и любой другой игровой объект в Phaser, дуги можно анимировать с помощью системы Tween. Вы можете изменять стандартные свойства, такие как масштаб, прозрачность и угол поворота.

this.tweens.add({
    targets: r4,
    scaleX: 0.25,
    scaleY: 0.5,
    yoyo: true,
    repeat: -1,
    ease: 'Sine.easeInOut'
});

Этот твин анимирует дугу r4, сжимая ее по горизонтали до 25% и по вертикали до 50% от исходного размера. Параметры yoyo: true и repeat: -1 заставляют анимацию колебаться и повторяться бесконечно.

this.tweens.add({
    targets: r6,
    angle: 90,
    yoyo: true,
    repeat: -1,
    ease: 'Sine.easeInOut'
});

Здесь анимируется свойство angle дуги r6. Вращение происходит вокруг точки центра, заданной при создании (600, 400).

Особенности WebGL-рендеринга (`setIterations`)

Пример использует специфичный для WebGL метод setIterations(). Он управляет сглаживанием контура дуги при рендеринге через WebGL.

//  WebGL only
r6.setIterations(0.2);

Значение 0.2 увеличивает количество итераций для расчета формы контура, что может сделать его более гладким, особенно при больших радиусах или сложных преобразованиях. **Важно:** Этот метод работает только при использовании WebGL-рендерера (например, Phaser.WEBGL). При рендеринге на Canvas он не окажет эффекта.

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

Метод this.add.arc() в Phaser — это прямой путь к созданию динамических круговых интерфейсов и эффектов прямо в коде. Вы научились управлять их формой, цветом, контуром и анимировать основные свойства. **Идеи для экспериментов:** 1. Создайте прогресс-бар, заполняющийся по дуге, используя твин для изменения конечного угла. 2. Скомбинируйте несколько полупрозрачных дуг с разными радиусами для создания сложных световых эффектов или ауры вокруг персонажа. 3. Используйте дуги в качестве траекторий для движения других объектов, вычисляя позицию по углу с помощью тригонометрии.