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

Столкновения — основа игровой механики. Проверка, находится ли точка (например, клик мыши или позиция объекта) на отрезке линии, — частая задача при создании интерфейсов, путей движения или триггеров. В этой статье мы разберем наглядный пример использования встроенного метода Phaser.Geom.Intersects.PointToLineSegment для точного и эффективного решения этой задачи. Вы научитесь визуализировать геометрические проверки в реальном времени, что поможет в отладке и создании сложных интерактивных сцен.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        const graphics = this.add.graphics();

        const line = new Phaser.Geom.Line(300, 200, 500, 400);
        const point = new Phaser.Math.Vector2(200, 100);

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

            point.x = Math.round(pointer.x / 10) * 10;
            point.y = Math.round(pointer.y / 10) * 10;

            redraw();
        });

        redraw();

        function redraw ()
        {
            graphics.clear();

            graphics.lineStyle(2, 0x00ff00);
            graphics.strokeLineShape(line);

            if (Phaser.Geom.Intersects.PointToLineSegment(point, line))
            {
                graphics.fillStyle(0xff0000);
            }
            else
            {
                graphics.fillStyle(0xffff00);
            }

            graphics.fillPointShape(point, 5);
        }
    }
}

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

const game = new Phaser.Game(config);

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

В методе create() создается графика для рисования, статичный отрезок линии и вектор для отслеживаемой точки. Ключевые объекты:

const graphics = this.add.graphics();
const line = new Phaser.Geom.Line(300, 200, 500, 400);
const point = new Phaser.Math.Vector2(200, 100);

- graphics — холст для рисования примитивов. - line — отрезок от точки (300, 200) до точки (500, 400). - point — вектор с начальными координатами (200, 100). Обратите внимание, что для проверки используется именно вектор (Vector2), а не простая пара координат.

Обработка перемещения указателя

Для интерактивности мы подписываемся на событие движения указателя (pointermove). Координаты точки привязываются к позиции курсора с небольшим сглаживанием (округление до сетки 10x10 пикселей), чтобы визуализация была четче.

this.input.on('pointermove', pointer => {
    point.x = Math.round(pointer.x / 10) * 10;
    point.y = Math.round(pointer.y / 10) * 10;
    redraw();
});

После каждого движения вызывается функция redraw(), которая перерисовывает сцену, основываясь на новых данных.

Магия проверки пересечения

Ядро примера — вызов метода Phaser.Geom.Intersects.PointToLineSegment. Он принимает два аргумента: вектор точки и объект линии, а возвращает true или false в зависимости от того, лежит ли точка на этом отрезке.

if (Phaser.Geom.Intersects.PointToLineSegment(point, line)) {
    graphics.fillStyle(0xff0000); // Красный цвет при пересечении
} else {
    graphics.fillStyle(0xffff00); // Желтый цвет в противном случае
}

Важно: метод проверяет именно принадлежность точки отрезку, а не бесконечной прямой.

Визуализация результата

Функция redraw() полностью очищает холст и заново рисует линию и точку. Цвет точки зависит от результата проверки.

function redraw () {
    graphics.clear();
    graphics.lineStyle(2, 0x00ff00);
    graphics.strokeLineShape(line);
    // ... проверка и установка fillStyle ...
    graphics.fillPointShape(point, 5);
}

- clear() — стирает все, нарисованное на этом холсте. - lineStyle(2, 0x00ff00) — задает зеленый цвет и толщину линии. - strokeLineShape(line) — рисует контур отрезка. - fillPointShape(point, 5) — рисует закрашенную точку радиусом 5 пикселей.

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

Использование встроенного метода PointToLineSegment избавляет от необходимости писать сложные геометрические вычисления вручную. Для экспериментов попробуйте: заменить статичную линию на движущуюся, создать несколько отрезков и проверять, на какой из них попала точка, или использовать эту проверку для определения, кликнул ли игрок по «проводу» или «дорожке» в вашей игре.