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

Определение столкновений между геометрическими фигурами — основа для игровой механики, от простых препятствий до сложных хитбоксов. В этой статье разберем, как в Phaser работает проверка пересечения треугольника и отрезка. Вы научитесь динамически отслеживать коллизии, визуализировать их и использовать этот метод в своих проектах для создания интерактивных объектов и преград.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    graphics;
    triangle;
    line;

    create ()
    {
        this.graphics = this.add.graphics();

        this.triangle = new Phaser.Geom.Triangle.BuildEquilateral(400, 200, 200);
        this.line = new Phaser.Geom.Line(260, 200, 450, 450);

        this.graphics.lineStyle(2, 0x00ff00);
        this.graphics.strokeTriangleShape(this.triangle);
        this.graphics.lineStyle(2, 0xffff00);
        this.graphics.strokeLineShape(this.line);

        this.input.on('pointermove', pointer =>
        {

            this.line.x2 = pointer.x;
            this.line.y2 = pointer.y;

        });
    }

    update ()
    {
        Phaser.Geom.Triangle.Rotate(this.triangle, 0.02);

        this.graphics.clear();
        this.graphics.fillStyle(0xffffff);
        this.graphics.lineStyle(2, 0x00ff00);
        this.graphics.strokeTriangleShape(this.triangle);

        if (Phaser.Geom.Intersects.TriangleToLine(this.triangle, this.line))
        {
            this.graphics.lineStyle(2, 0xff0000);
        }
        else
        {
            this.graphics.lineStyle(2, 0xffff00);
        }

        this.graphics.strokeLineShape(this.line);
    }
}

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

const game = new Phaser.Game(config);

Подготовка сцены и создание объектов

В методе create() инициализируются основные объекты: графика для отрисовки, треугольник и линия. Треугольник создается как равносторонний с помощью фабричного метода, а линия задается начальной и конечной точками.

create ()
{
    this.graphics = this.add.graphics();

    this.triangle = new Phaser.Geom.Triangle.BuildEquilateral(400, 200, 200);
    this.line = new Phaser.Geom.Line(260, 200, 450, 450);

    this.graphics.lineStyle(2, 0x00ff00);
    this.graphics.strokeTriangleShape(this.triangle);
    this.graphics.lineStyle(2, 0xffff00);
    this.graphics.strokeLineShape(this.line);
}

Ключевые моменты: this.add.graphics() создает холст для рисования, Phaser.Geom.Triangle.BuildEquilateral строит треугольник по центру и длине стороны, а Phaser.Geom.Line определяет отрезок. Стили линий задаются через lineStyle, а strokeTriangleShape и strokeLineShape отрисовывают контуры.

Динамическое управление линией

Чтобы линия реагировала на действия игрока, мы привязываем ее конечную точку к курсору мыши. Для этого используется слушатель события pointermove.

this.input.on('pointermove', pointer =>
{
    this.line.x2 = pointer.x;
    this.line.y2 = pointer.y;
});

При каждом движении мыши координаты x2 и y2 линии обновляются. Это позволяет в реальном времени менять геометрию отрезка и проверять его взаимодействие с другими фигурами.

Анимация и проверка пересечений

В update() происходит вращение треугольника и проверка его пересечения с линией. Если пересечение обнаружено, цвет линии меняется на красный.

update ()
{
    Phaser.Geom.Triangle.Rotate(this.triangle, 0.02);

    this.graphics.clear();
    this.graphics.fillStyle(0xffffff);
    this.graphics.lineStyle(2, 0x00ff00);
    this.graphics.strokeTriangleShape(this.triangle);

    if (Phaser.Geom.Intersects.TriangleToLine(this.triangle, this.line))
    {
        this.graphics.lineStyle(2, 0xff0000);
    }
    else
    {
        this.graphics.lineStyle(2, 0xffff00);
    }

    this.graphics.strokeLineShape(this.line);
}

Phaser.Geom.Triangle.Rotate поворачивает треугольник на небольшой угол каждый кадр. this.graphics.clear() очищает холст перед перерисовкой. Важнейший вызов — Phaser.Geom.Intersects.TriangleToLine, который возвращает true или false в зависимости от наличия пересечения. На основе этого результата выбирается цвет для линии.

Настройка игры и запуск

Конфигурационный объект определяет основные параметры игры: размеры, тип рендерера и сцену.

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

const game = new Phaser.Game(config);

Phaser.AUTO автоматически выбирает между WebGL и Canvas. Указание scene: Example говорит движку, какую сцену использовать при старте.

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

Метод Phaser.Geom.Intersects.TriangleToLine предоставляет простой способ проверки коллизий между сложными фигурами. Для экспериментов попробуйте заменить треугольник на полигон через Phaser.Geom.Polygon и использовать Intersects.PolygonToLine, или добавьте несколько линий для создания сетки препятствий. Это основа для систем обнаружения выстрелов, границ уровня или зон взаимодействия.