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

В играх часто требуется работать с геометрическими объектами: проверять столкновения, искать центры масс или окружностей. Знание таких методов, как `Phaser.Geom.Triangle.CircumCenter`, позволяет решать эти задачи без изобретения велосипеда. В этой статье мы разберем, как найти точку, равноудаленную от всех вершин треугольника — его центр описанной окружности, и наглядно отрисуем результат. Это полезно для создания зон влияния, расстановки объектов на карте или визуализации геометрических построений.

Версия 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 } });

        //  Create a little random triangle

        const x1 = Phaser.Math.Between(300, 350);
        const y1 = Phaser.Math.Between(300, 350);

        const x2 = Phaser.Math.Between(400, 450);
        const y2 = Phaser.Math.Between(200, 300);

        const x3 = Phaser.Math.Between(500, 550);
        const y3 = Phaser.Math.Between(300, 350);

        const triangle = new Phaser.Geom.Triangle(x1, y1, x2, y2, x3, y3);

        graphics.fillTriangleShape(triangle);

        //  Get the circumcircle of the triangle

        const circumcircle = Phaser.Geom.Triangle.CircumCircle(triangle);

        //  Draw the circumcircle

        graphics.strokeCircleShape(circumcircle);

        //  Get the circumcenter of the triangle

        const circumcenter = Phaser.Geom.Triangle.CircumCenter(triangle);

        //  Draw the circumcenter

        graphics.fillStyle(0xffff00);
        graphics.fillPointShape(circumcenter, 4);
    }
}

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

const game = new Phaser.Game(config);

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

В методе create() сцены мы первым делом создаем объект graphics для рисования. Ему задаются стили линии и заливки. Далее, используя генератор случайных чисел Phaser.Math.Between, мы определяем координаты трех точек на плоскости. Эти точки становятся вершинами нового объекта Phaser.Geom.Triangle. С помощью graphics.fillTriangleShape() мы отрисовываем получившийся треугольник на экране.

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

const x1 = Phaser.Math.Between(300, 350);
const y1 = Phaser.Math.Between(300, 350);

const x2 = Phaser.Math.Between(400, 450);
const y2 = Phaser.Math.Between(200, 300);

const x3 = Phaser.Math.Between(500, 550);
const y3 = Phaser.Math.Between(300, 350);

const triangle = new Phaser.Geom.Triangle(x1, y1, x2, y2, x3, y3);

graphics.fillTriangleShape(triangle);

Построение описанной окружности

Описанная окружность — это окружность, проходящая через все три вершины треугольника. Ее центр находится на пересечении серединных перпендикуляров. Вместо ручных вычислений мы используем встроенный метод Phaser.Geom.Triangle.CircumCircle. Он принимает треугольник в качестве аргумента и возвращает объект Phaser.Geom.Circle, содержащий координаты центра и радиус. После получения объекта окружности мы рисуем ее контур с помощью graphics.strokeCircleShape().

const circumcircle = Phaser.Geom.Triangle.CircumCircle(triangle);

graphics.strokeCircleShape(circumcircle);

Получение и отрисовка центра окружности

Центр описанной окружности (circumcenter) можно получить напрямую, без промежуточного создания объекта Circle. Для этого служит метод Phaser.Geom.Triangle.CircumCenter. Он возвращает объект Phaser.Geom.Point с координатами искомой точки. Чтобы визуально выделить ее на сцене, мы меняем стиль заливки у graphics и рисуем точку заданного размера методом fillPointShape.

const circumcenter = Phaser.Geom.Triangle.CircumCenter(triangle);

graphics.fillStyle(0xffff00);
graphics.fillPointShape(circumcenter, 4);

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

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

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

const game = new Phaser.Game(config);

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

Методы CircumCircle и CircumCenter из модуля Phaser.Geom.Triangle предоставляют готовое решение для работы с описанной окружностью. Вы можете экспериментировать: сделать вершины треугольника перетаскиваемыми спрайтами и в реальном времени пересчитывать позицию центра или использовать эту точку как цель для камеры или место появления игрового объекта. Это открывает возможности для динамической геометрии в вашем проекте.