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

В игровой разработке часто требуется работать с геометрическими фигурами для расчёта зон поражения, областей взаимодействия или просто для визуализации. Встроенные геометрические инструменты Phaser позволяют легко вычислять свойства фигур, такие как площадь круга, без написания собственных формул. В этой статье мы разберём практический пример использования `Phaser.Geom.Circle.Area()` и его визуализации с помощью Graphics, что поможет вам эффективно управлять игровым пространством.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        const graphics = this.add.graphics({ lineStyle: { width: 2, color: 0x00ff00 }, fillStyle: { color: 0xff00ff } });

        const circle = new Phaser.Geom.Circle(40, 575, 25);

        function drawCircle ()
        {
            const area = Phaser.Geom.Circle.Area(circle);

            graphics.fillRect(circle.right + 5, circle.bottom, 50, -area / 50);
            graphics.strokeCircleShape(circle);
        }

        drawCircle(graphics, circle);

        circle.setTo(175, 550, 50);
        drawCircle(graphics, circle);

        circle.setTo(360, 525, 75);
        drawCircle(graphics, circle);

        circle.setTo(595, 500, 100);
        drawCircle(graphics, circle);
    }
}

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

const game = new Phaser.Game(config);

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

В методе create() сцены мы первым делом инициализируем объект Graphics, который будет отвечать за рисование. Этот объект настраивается с определённым стилем линий и заливки.

const graphics = this.add.graphics({ lineStyle: { width: 2, color: 0x00ff00 }, fillStyle: { color: 0xff00ff } });

Здесь lineStyle задаёт зелёный контур (0x00ff00) толщиной 2 пикселя, а fillStyle определяет пурпурный цвет (0xff00ff) для заливки. Этот объект graphics будет использоваться для всех последующих операций рисования в этом кадре.

Создание круга и функция отрисовки

Далее создаётся экземпляр круга с помощью класса Phaser.Geom.Circle. Конструктор принимает три аргумента: координаты центра по X и Y, а также радиус.

const circle = new Phaser.Geom.Circle(40, 575, 25);

Затем определяется функция drawCircle, которая инкапсулирует логику отрисовки и визуализации площади. Это хорошая практика для избежания дублирования кода.

function drawCircle ()
{
    const area = Phaser.Geom.Circle.Area(circle);
    graphics.fillRect(circle.right + 5, circle.bottom, 50, -area / 50);
    graphics.strokeCircleShape(circle);
}

Внутри функции: 1. Phaser.Geom.Circle.Area(circle) вычисляет площадь круга по классической формуле π * r². 2. graphics.fillRect(...) рисует прямоугольник, высота которого пропорциональна вычисленной площади. Обратите внимание, что высота задаётся отрицательным числом (-area / 50), чтобы прямоугольник "рос" вверх от точки circle.bottom. 3. graphics.strokeCircleShape(circle) обводит контур самого круга зелёной линией.

Множественная отрисовка с разными параметрами

Основная демонстрация заключается в последовательном изменении свойств одного и того же объекта circle и его повторной отрисовке. Метод setTo позволяет переопределить все параметры круга.

drawCircle(graphics, circle);

circle.setTo(175, 550, 50);
drawCircle(graphics, circle);

circle.setTo(360, 525, 75);
drawCircle(graphics, circle);

circle.setTo(595, 500, 100);
drawCircle(graphics, circle);

Каждый вызов setTo задаёт новые координаты центра и новый радиус. После каждого изменения вызывается drawCircle(), которая пересчитывает площадь для нового радиуса и отрисовывает обновлённые круг и столбик. Это наглядно показывает, как площадь круга увеличивается квадратично с увеличением радиуса (радиус 100 даёт площадь в 16 раз больше, чем радиус 25).

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

Код завершается стандартной для Phaser конфигурацией игры. В объекте config задаются размеры холста, автоматический выбор рендерера (WebGL или Canvas), элемент-родитель и наша сцена Example.

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

const game = new Phaser.Game(config);

Инициализация игры с этой конфигурацией запускает сцену и выполняет весь наш код отрисовки.

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

Использование Phaser.Geom.Circle.Area() — это простой и производительный способ получить площадь круга для игровой логики. Показанный подход с визуализацией через Graphics отлично подходит для отладки или создания обучающих материалов. Для экспериментов попробуйте изменить коэффициент деления площади при расчёте высоты столбика (/50), чтобы сделать зависимость более или менее заметной, или анимируйте изменение радиуса круга с помощью Tweens, постоянно вызывая drawCircle для создания динамической диаграммы.