О чем этот пример
Столкновения — основа игровой механики. Проверка, находится ли точка (например, клик мыши или позиция объекта) на отрезке линии, — частая задача при создании интерфейсов, путей движения или триггеров. В этой статье мы разберем наглядный пример использования встроенного метода 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 избавляет от необходимости писать сложные геометрические вычисления вручную. Для экспериментов попробуйте: заменить статичную линию на движущуюся, создать несколько отрезков и проверять, на какой из них попала точка, или использовать эту проверку для определения, кликнул ли игрок по «проводу» или «дорожке» в вашей игре.
