О чем этот пример
В играх часто требуется определять пересечение сложных форм. Встроенный модуль геометрии Phaser позволяет эффективно проверять столкновения между различными фигурами, включая треугольники. Эта статья разбирает практический пример отслеживания пересечения двух вращающихся и перемещающихся треугольников, что может быть полезно для создания кастомных хитбоксов, зон поражения или геометрических головоломок.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
graphics;
triangleB;
triangle;
create ()
{
this.graphics = this.add.graphics();
// triangle = new Phaser.Geom.Triangle.BuildEquilateral(400, 320, 140);
this.triangle = new Phaser.Geom.Triangle.BuildEquilateral(400, 320, 40);
this.triangleB = new Phaser.Geom.Triangle(400, 200, 300, 300, 500, 300);
this.graphics.lineStyle(2, 0x00ff00);
this.graphics.strokeTriangleShape(this.triangleB);
this.graphics.lineStyle(2, 0xffff00);
this.graphics.strokeTriangleShape(this.triangle);
this.input.on('pointermove', pointer =>
{
Phaser.Geom.Triangle.CenterOn(this.triangle, pointer.x, pointer.y);
});
}
update ()
{
Phaser.Geom.Triangle.Rotate(this.triangleB, 0.02);
this.graphics.clear();
this.graphics.lineStyle(2, 0x00ff00);
this.graphics.strokeTriangleShape(this.triangleB);
if (Phaser.Geom.Intersects.TriangleToTriangle(this.triangle, this.triangleB))
{
this.graphics.lineStyle(2, 0xff0000);
}
else
{
this.graphics.lineStyle(2, 0xffff00);
}
this.graphics.strokeTriangleShape(this.triangle);
}
}
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Инициализация сцены и создание треугольников
В методе create() сцены происходит подготовка графики и создание геометрических объектов. Сначала мы создаем экземпляр Graphics для отрисовки линий.
Затем определяем два треугольника. Первый (this.triangle) создается с помощью фабричного метода Phaser.Geom.Triangle.BuildEquilateral, который строит равносторонний треугольник по центру и длине стороны. Второй треугольник (this.triangleB) создается явным указанием координат его трех вершин.
this.graphics = this.add.graphics();
this.triangle = new Phaser.Geom.Triangle.BuildEquilateral(400, 320, 40);
this.triangleB = new Phaser.Geom.Triangle(400, 200, 300, 300, 500, 300);
Сразу после создания треугольники отрисовываются на экране с разным цветом контура.
this.graphics.lineStyle(2, 0x00ff00);
this.graphics.strokeTriangleShape(this.triangleB);
this.graphics.lineStyle(2, 0xffff00);
this.graphics.strokeTriangleShape(this.triangle);
Интерактивность: движение треугольника за курсором
Чтобы сделать пример наглядным, первый треугольник привязан к движению указателя мыши. Для этого используется обработчик события 'pointermove'. При каждом движении мыши позиция треугольника this.triangle центрируется на координатах курсора с помощью статического метода Phaser.Geom.Triangle.CenterOn. Этот метод не изменяет форму или ориентацию треугольника, а лишь перемещает его целиком.
this.input.on('pointermove', pointer => {
Phaser.Geom.Triangle.CenterOn(this.triangle, pointer.x, pointer.y);
});
Таким образом, пользователь может водить одним треугольником по экрану, проверяя его пересечение со вторым.
Анимация и проверка пересечений в update()
Основная логика обновления кадра находится в методе update(). Здесь происходят три ключевые вещи: анимация, проверка столкновений и перерисовка.
Сначала второй треугольник (this.triangleB) непрерывно вращается вокруг своего центра. Это делает пример динамичным.
Phaser.Geom.Triangle.Rotate(this.triangleB, 0.02);
Перед отрисовкой нового кадра необходимо очистить старое изображение.
this.graphics.clear();
Затем снова отрисовывается неподвижный (но вращающийся) треугольник this.triangleB.
this.graphics.lineStyle(2, 0x00ff00);
this.graphics.strokeTriangleShape(this.triangleB);
Сердце примера: функция TriangleToTriangle
Самая важная строка кода – это вызов функции проверки пересечения. Статический метод Phaser.Geom.Intersects.TriangleToTriangle принимает два объекта треугольника и возвращает true, если они пересекаются (или соприкасаются), и false в противном случае.
if (Phaser.Geom.Intersects.TriangleToTriangle(this.triangle, this.triangleB))
В зависимости от результата проверки, меняется цвет контура для перемещаемого треугольника (this.triangle). При пересечении он становится красным, в остальное время – желтым. Это дает мгновенную визуальную обратную связь.
if (Phaser.Geom.Intersects.TriangleToTriangle(this.triangle, this.triangleB))
{
this.graphics.lineStyle(2, 0xff0000);
}
else
{
this.graphics.lineStyle(2, 0xffff00);
}
this.graphics.strokeTriangleShape(this.triangle);
Что попробовать дальше
Пример демонстрирует мощь и простоту геометрического модуля Phaser. Функция TriangleToTriangle избавляет разработчика от необходимости реализовывать сложные математические алгоритмы проверки пересечений. Для экспериментов попробуйте изменить форму треугольников на произвольную, добавить больше фигур и проверять пересечения между ними или использовать результат проверки не только для смены цвета, но и для игровой логики – например, нанесения урона или активации механизма.
