О чем этот пример
Работа с геометрией — мощный инструмент в арсенале разработчика игр. Она позволяет реализовывать сложную логику взаимодействия, создавать визуальные эффекты и проводить вычисления для ИИ. В этой статье мы разберем, как с помощью встроенных возможностей Phaser найти описанную окружность для произвольного треугольника — это может пригодиться для генерации уровней, расстановки объектов или визуальной отладки коллизий.
Версия 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);
}
}
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что такое описанная окружность?
Описанная окружность (circumcircle) — это окружность, проходящая через все три вершины треугольника. Её центр находится в точке пересечения серединных перпендикуляров сторон. Понимание этой геометрической конструкции полезно не только в теории: в играх она может определять зону влияния объекта, область патрулирования или границу для случайного размещения предметов вокруг ключевой точки.
Phaser предоставляет готовый метод Phaser.Geom.Triangle.CircumCircle() для её вычисления, избавляя нас от рутинных математических операций.
Создание сцены и графического контекста
Всё начинается с создания класса сцены, наследующего от Phaser.Scene. В методе create() мы инициализируем графический объект Graphics, который будет отвечать за отрисовку.
create ()
{
const graphics = this.add.graphics({ lineStyle: { width: 2, color: 0x00ff00 }, fillStyle: { color: 0xff00ff } });
}
Здесь lineStyle задаёт стиль контура (ширина 2 пикселя, зелёный цвет), а fillStyle — стиль заливки (пурпурный цвет). Этот объект graphics мы будем использовать для всех последующих рисовальных операций.
Генерация случайного треугольника
Для демонстрации создадим треугольник со случайными координатами вершин в определённых диапазонах. Это делает пример наглядным и воспроизводимым.
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);
Функция Phaser.Math.Between(min, max) возвращает случайное целое число в заданном диапазоне. Полученные координаты передаются в конструктор Phaser.Geom.Triangle, создавая новый геометрический объект.
Отрисовка треугольника и вычисление окружности
Сначала заливаем наш треугольник, используя метод fillTriangleShape() объекта graphics.
graphics.fillTriangleShape(triangle);
Затем ключевой шаг — получаем описанную окружность. Метод CircumCircle() — это статическая функция класса Phaser.Geom.Triangle. Она принимает объект треугольника в качестве единственного аргумента и возвращает объект типа Phaser.Geom.Circle, содержащий свойства `x,y(координаты центра) иradius` (радиус).
const circumcircle = Phaser.Geom.Triangle.CircumCircle(triangle);
Визуализация результата
Теперь, когда окружность вычислена, её можно нарисовать поверх треугольника. Для этого используется метод strokeCircleShape().
graphics.strokeCircleShape(circumcircle);
В результате на экране появится пурпурный треугольник, обведённый зелёной окружностью, которая точно проходит через все его вершины. Это наглядно демонстрирует корректность работы геометрического модуля Phaser.
Конфигурация и запуск игры
Как и в любом проекте на Phaser, нам необходимо создать конфигурационный объект и инициализировать игру.
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Объект config определяет базовые параметры: размеры canvas, графический бэкенд (Phaser.AUTO), ID родительского HTML-элемента и главную сцену. Создание экземпляра Phaser.Game с этой конфигурацией запускает весь жизненный цикл приложения.
Что попробовать дальше
Метод Phaser.Geom.Triangle.CircumCircle() — это отличный пример того, как Phaser упрощает сложные геометрические задачи. Полученную окружность можно использовать не только для отрисовки. Попробуйте применить её на практике: например, размещать противников по границе этой окружности, использовать радиус для проверки расстояния до игрока или анимировать центр окружности, создавая интересные визуальные паттерны. Экспериментируйте, подставляя разные координаты вершин, и наблюдайте, как изменяется положение и размер описанной окружности.
