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

В игровой разработке часто нужно определить, пересекаются ли траектории снарядов, лазерные лучи или пути персонажей. Ручной расчёт таких пересечений — сложная и ресурсоёмкая задача. К счастью, Phaser 3 предоставляет готовые инструменты геометрических вычислений. В этой статье мы разберём, как с помощью одного вызова API найти точку пересечения двух линий и избежать распространённых ошибок в логике столкновений.

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

Живой запуск

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

Исходный код


function create()
{
    const line1 = new Phaser.Geom.Line(100, 100, 200, 200);
    const line2 = new Phaser.Geom.Line(300, 100, 300, 300);

    const result = Phaser.Geom.Intersects.GetLineToLine(line1, line2);

    console.log(result);
}

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

const game = new Phaser.Game(config);

Суть примера: функция GetLineToLine

Исходный код демонстрирует работу статического метода Phaser.Geom.Intersects.GetLineToLine. Этот метод принимает на вход два объекта типа Phaser.Geom.Line и возвращает точку их пересечения, если она существует.

Внутри метода происходит проверка математического условия пересечения двух отрезков в декартовой системе координат. Если отрезки параллельны или не пересекаются в своих границах, метод возвращает null.

const result = Phaser.Geom.Intersects.GetLineToLine(line1, line2);

Создание объектов Line

Перед вызовом метода пересечения необходимо создать объекты, представляющие геометрические линии. Конструктор Phaser.Geom.Line принимает четыре аргумента: координаты X и Y начальной точки, а затем координаты X и Y конечной точки отрезка.

В примере создаются две линии: диагональная от точки (100, 100) до (200, 200) и вертикальная от точки (300, 100) до (300, 300).

const line1 = new Phaser.Geom.Line(100, 100, 200, 200);
const line2 = new Phaser.Geom.Line(300, 100, 300, 300);

Анализ результата и логирование

Результат работы метода GetLineToLine выводится в консоль. Это может быть либо объект типа Phaser.Geom.Point с полями `xиy, либоnull`.

В данном конкретном примере линии не пересекаются (вертикальная линия находится далеко справа от диагональной), поэтому результатом будет null. Чтобы увидеть корректную точку пересечения, нужно расположить линии так, чтобы их отрезки действительно пересекались.

console.log(result);

Как использовать результат в игре

Возвращённое значение нужно всегда проверять перед использованием. Если пересечение есть, вы можете, например, создать эффект взрыва в этой точке, нанести урон или изменить траекторию объекта.

Вот практический шаблон для обработки результата:

const intersection = Phaser.Geom.Intersects.GetLineToLine(laserBeam, enemyPath);

if (intersection) {
    // Создаём анимацию взрыва в точке intersection.x, intersection.y
    this.add.sprite(intersection.x, intersection.y, 'explosion');
    // Наносим урон врагу
    enemy.takeDamage();
}

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

Метод Phaser.Geom.Intersects.GetLineToLine — это мощный и производительный инструмент для детекции пересечений. Он избавляет разработчика от необходимости писать сложную математику самостоятельно. **Идеи для экспериментов:** 1. Создайте интерактивные линии, управляемые курсором мыши, и в реальном времени выводите точку их пересечения на экран. 2. Используйте этот метод для проверки, пересекает ли траектория пули линию стены, чтобы реализовать рикошет. 3. Комбинируйте его с другими методами из Phaser.Geom.Intersects, например, для проверки пересечения линии с кругом (GetLineToCircle).