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

Работа с геометрическими фигурами — фундамент для создания интерфейсов, эффектов и визуализации в играх. Класс `Phaser.GameObjects.Shape` предоставляет мощный и производительный способ рисования примитивов прямо на канвасе, минуя загрузку текстур. В этой статье на примере кругов разберем, как создавать фигуры, настраивать их внешний вид (заливку, обводку) и оживлять с помощью твинов. Этот подход идеален для прототипирования, создания динамических индикаторов и нестандартных графических элементов.

Версия 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.circle(200, 200, 80, 0x6666ff);

        const r2 = this.add.circle(400, 200, 80, 0x9966ff);

        r2.setStrokeStyle(4, 0xefc53f);

        const r3 = this.add.circle(600, 200, 80);

        r3.setStrokeStyle(2, 0x1a65ac);

        const r4 = this.add.circle(200, 400, 80, 0xff6699);

        const r5 = this.add.circle(400, 400, 80, 0xff33cc);

        const r6 = this.add.circle(600, 400, 80, 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);

Создание базовых кругов

Класс Phaser.GameObjects.Shape является родительским для всех геометрических примитивов, включая круг. В Phaser 3 создать круг можно прямо из фабрики игровых объектов сцены, используя метод this.add.circle().

const r1 = this.add.circle(200, 200, 80, 0x6666ff);

Этот метод принимает четыре основных аргумента: координаты X и Y центра круга, его радиус и цвет заливки в числовом формате (HEX). Цвет — опциональный параметр. Если его не указать, круг будет создан без заливки, что полезно для создания контурных фигур.

Настройка обводки и WebGL-эффектов

Помимо сплошной заливки, круг можно очертить контуром. Для этого используется метод setStrokeStyle(), который доступен для всех Shape-объектов.

r2.setStrokeStyle(4, 0xefc53f);

Первый параметр — толщина линии в пикселях, второй — её цвет. Этот метод нужно вызывать отдельно после создания объекта.

При рендеринге через WebGL (когда config.type установлен в Phaser.WEBGL или Phaser.AUTO с поддержкой WebGL) для фигур становятся доступны дополнительные эффекты, такие как сглаживание границ (антиалиасинг). Метод setIterations() управляет качеством этого сглаживания.

//  WebGL only
r6.setIterations(0.2);

Чем ниже значение (например, 0.2), тем более «мягкими» и размытыми становятся края фигуры. При значении по умолчанию края будут чёткими.

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

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

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

В этом примере мы анимируем масштаб по осям X и Y независимо, создавая эффект пульсации и сжатия. Параметр yoyo: true заставляет анимацию проигрываться в обратном порядке, а repeat: -1 делает её бесконечной.

Вы можете анимировать и другие свойства: * alpha — для плавного исчезновения и появления. * angle — для вращения фигуры (важно: вращается не содержимое круга, а сам объект, как контейнер). * `x,y` — для перемещения.

// Анимация прозрачности
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'
});

Структура сцены и конфигурация

Весь код примера упакован в класс сцены, унаследованный от Phaser.Scene. Это стандартная практика в Phaser 3.

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');
        // ... основной код создания кругов и твинов
    }
}

Метод preload() используется для загрузки фонового изображения. В методе create() происходит инициализация всех игровых объектов. Конфигурационный объект игры передаётся в конструктор Phaser.Game.

const config = {
    type: Phaser.AUTO, // Автовыбор рендерера (Canvas или WebGL)
    parent: 'phaser-example', // ID HTML-элемента для встраивания
    width: 800,
    height: 600,
    scene: Example // Основная сцена
};
const game = new Phaser.Game(config);

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

Shape-объекты, в частности круги, — это гибкий инструмент для отрисовки векторной графики прямо в игре. Они не требуют ресурсов на загрузку текстур и отлично поддаются программной модификации и анимации. Для экспериментов попробуйте: создать интерактивный круг, меняющий цвет по клику; скомбинировать несколько кругов с разной прозрачностью для создания сложных световых эффектов; или использовать setScale и setAlpha в реальном времени в ответ на игровые события, например, для отображения урона или заряда способности.