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

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

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        const ellipse = new Phaser.Geom.Ellipse(400, 5, 10, 10);

        const graphics = this.add.graphics({ lineStyle: { color: 0x00aaaa } });
        graphics.strokeEllipseShape(ellipse);

        for (let i = 0; i < 37; i++)
        {
            ellipse.setTo(ellipse.x, ellipse.y + 19, ellipse.width + 12, ellipse.height + 6);
            graphics.strokeEllipseShape(ellipse);
        }
    }
}

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

const game = new Phaser.Game(config);

Подготовка сцены и создание эллипса

В методе create() сцены мы инициализируем наш первый эллипс. Ключевой класс здесь — Phaser.Geom.Ellipse. Его конструктор принимает четыре аргумента: координаты центра по осям X и Y, а затем ширину и высоту фигуры.

Сразу после создания эллипса мы рисуем его контур на сцене. Для этого используется объект Graphics, который является инструментом для рисования примитивов.

const ellipse = new Phaser.Geom.Ellipse(400, 5, 10, 10);

const graphics = this.add.graphics({ lineStyle: { color: 0x00aaaa } });
graphics.strokeEllipseShape(ellipse);

Как работает метод `setTo`

Метод setTo — это основной способ изменить все свойства эллипса одновременно. Он не создает новый объект, а перезаписывает параметры существующего. Это важно для производительности.

Метод принимает те же четыре аргумента, что и конструктор: x, y, width, height. В исходном примере мы видим, как на каждом шаге цикла значения этих параметров увеличиваются.

ellipse.setTo(ellipse.x, ellipse.y + 19, ellipse.width + 12, ellipse.height + 6);

Здесь эллипс смещается вниз и равномерно расширяется. После каждого вызова setTo обновленная фигура сразу же отрисовывается с помощью graphics.strokeEllipseShape(ellipse).

Цикл анимации и инкрементальное изменение

Динамический эффект достигается за счет цикла for. На каждой итерации мы вычисляем новые значения для эллипса, основываясь на его текущих свойствах.

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

for (let i = 0; i < 37; i++)
{
    ellipse.setTo(ellipse.x, ellipse.y + 19, ellipse.width + 12, ellipse.height + 6);
    graphics.strokeEllipseShape(ellipse);
}

В результате на экране появляется последовательность из 37 концентрических эллипсов, образующих визуальный туннель или воронку.

Настройка конфигурации игры (config)

Код примера завершается стандартной для Phaser 3 конфигурацией игры. В объекте config задаются базовые параметры: размер холста, тип рендерера, идентификатор родительского DOM-элемента и класс основной сцены.

Именно здесь создается экземпляр игры new Phaser.Game(config), который запускает весь процесс.

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

const game = new Phaser.Game(config);

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

Метод setTo для геометрических объектов в Phaser — это мощный и простой инструмент для динамического изменения мира. Он лежит в основе многих эффектов, где форма или положение объекта должны меняться со временем. **Идеи для экспериментов:** 1. Измените формулу в цикле, чтобы эллипс сужался, двигался по диагонали или вращался вокруг точки. 2. Попробуйте привязать изменения к вводу пользователя (например, размер эллипса — к нажатию клавиши). 3. Используйте не Graphics, а спрайт с физическим телом, и применяйте setTo к его hitbox для создания нестандартных коллайдеров.