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

Геометрия в Phaser — это не просто статичные фигуры, а основа для динамичной и живой графики. Этот пример демонстрирует, как с помощью методов `Phaser.Geom.Circle.Clone()` и `CircumferencePoint()` можно создать сложную анимированную композицию из простых кругов. Такой подход полезен для генерации фонов, визуальных эффектов или абстрактных анимаций в играх, когда нужно управлять множеством объектов с минимальными затратами ресурсов.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    circles;
    graphics;

    create ()
    {
        this.graphics = this.add.graphics({ lineStyle: { color: 0x00ff00 } });

        let circle = new Phaser.Geom.Circle(400, 300, 0);

        this.circles = [ circle ];

        for (let i = 0; i < 80; i++)
        {
            circle = Phaser.Geom.Circle.Clone(circle);
            circle.radius += 1;

            Phaser.Geom.Circle.CircumferencePoint(circle, i / 20 * Phaser.Math.PI2, circle);

            this.circles.push(circle);
        }
    }

    update ()
    {
        this.graphics.clear();

        for (let i = 0; i < this.circles.length; i++)
        {
            this.circles[i].radius += 1;
            if (this.circles[i].radius > 800)
            {
                this.circles[i].radius = 0;
            }

            this.graphics.strokeCircleShape(this.circles[i]);
        }
    }
}

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

const game = new Phaser.Game(config);

Подготовка сцены и базового круга

В методе create() происходит инициализация, необходимая для последующей анимации. Сначала создается объект Graphics для отрисовки контуров.

this.graphics = this.add.graphics({ lineStyle: { color: 0x00ff00 } });

Затем создается исходный круг с нулевым радиусом в центре экрана. Он станет основой для всей последующей цепочки клонов.

let circle = new Phaser.Geom.Circle(400, 300, 0);
this.circles = [ circle ];

Создание цепочки клонированных кругов

В цикле создается 80 новых кругов. Ключевой момент — каждый новый круг не создается с нуля, а является клоном предыдущего. Метод Phaser.Geom.Circle.Clone() создает новый объект Circle, полностью копируя свойства текущего.

circle = Phaser.Geom.Circle.Clone(circle);
circle.radius += 1;

После клонирования радиус нового круга увеличивается на 1. Затем метод Phaser.Geom.Circle.CircumferencePoint() используется для смещения центра круга. Этот метод вычисляет точку на окружности круга по заданному углу (в данном случае угол зависит от индекса `i) и перезаписывает координатыxиy` самого круга этими значениями, эффективно перемещая его.

Phaser.Geom.Circle.CircumferencePoint(circle, i / 20 * Phaser.Math.PI2, circle);

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

Анимация в реальном времени

Метод update() отвечает за непрерывную анимацию. Сначала очищается холст от предыдущего кадра.

this.graphics.clear();

Затем в цикле для каждого круга в массиве this.circles радиус увеличивается на 1. Если радиус превышает 800 пикселей, он сбрасывается до нуля, создавая бесконечную пульсацию.

this.circles[i].radius += 1;
if (this.circles[i].radius > 800)
{
    this.circles[i].radius = 0;
}

Наконец, каждый круг отрисовывается на холсте с помощью метода strokeCircleShape().

this.graphics.strokeCircleShape(this.circles[i]);

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

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

Стандартная конфигурация Phaser задает размеры холста, автоматический выбор рендерера и указывает наш класс Example в качестве основной сцены.

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

const game = new Phaser.Game(config);

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

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

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