О чем этот пример
Расчёт нормали к линии — базовая, но мощная операция в игровой геометрии. Она позволяет получить перпендикуляр к отрезку, что критически важно для расчёта отскоков, определения направления движения вдоль стен, создания векторных эффектов и реализации простой 2D физики. В этой статье мы разберём пример из официальной документации Phaser, покажем, как работает `Phaser.Geom.Line.NormalAngle`, и объясним практическое применение этого метода в реальных игровых проектах.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
create ()
{
const graphics = this.add.graphics({ lineStyle: { width: 4, color: 0xaa00aa } });
const line = new Phaser.Geom.Line(400, 300, 550, 300);
const text = this.add.text(50, 50, '');
this.input.on('pointermove', pointer =>
{
line.x2 = pointer.x;
line.y2 = pointer.y;
redraw();
});
redraw();
function redraw ()
{
graphics.clear();
graphics.strokeLineShape(line);
const normalAngle = Phaser.Geom.Line.NormalAngle(line);
graphics.lineStyle(2, 0x00aa00);
graphics.lineBetween(400, 300, 400 + Math.cos(normalAngle) * 100, 300 + Math.sin(normalAngle) * 100);
text.setText(`Line Normal Angle: ${Phaser.Math.RadToDeg(normalAngle)}`);
}
}
}
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что такое нормаль к линии и зачем она нужна
Нормаль к линии — это вектор, перпендикулярный ей. В 2D-пространстве для любого отрезка существует два таких направления (влево и вправо от него). Нормаль используется повсеместно: от простого вычисления угла отражения снаряда от стены до определения, с какой стороны от препятствия находится игрок.
В контексте Phaser, метод Phaser.Geom.Line.NormalAngle(line) возвращает не сам вектор, а его угол в радианах. Это базовая, но точная информация, которую затем можно использовать для создания вектора направления или немедленного применения в графике и физике.
Разбор примера: Интерактивная визуализация
Исходный код создаёт сцену с линией, один конец которой закреплён, а второй следует за курсором мыши. В реальном времени вычисляется и отрисовывается нормаль.
Сначала создаются необходимые объекты: графический контейнер (graphics) для рисования, геометрическая линия (line) и текстовое поле (text) для вывода угла.
const graphics = this.add.graphics({ lineStyle: { width: 4, color: 0xaa00aa } });
const line = new Phaser.Geom.Line(400, 300, 550, 300);
const text = this.add.text(50, 50, '');
Слушатель события движения мыши обновляет конечную точку линии и вызывает функцию перерисовки.
this.input.on('pointermove', pointer => {
line.x2 = pointer.x;
line.y2 = pointer.y;
redraw();
});
Ядро примера: Функция redraw() и метод NormalAngle
Вся магия происходит в функции redraw(). После очистки холста она рисует саму линию.
graphics.clear();
graphics.strokeLineShape(line);
Затем вычисляется угол нормали. Это ключевой вызов.
const normalAngle = Phaser.Geom.Line.NormalAngle(line);
Полученный угол в радианах используется для отрисовки перпендикуляра. Мы вычисляем конечную точку для отрезка длиной 100 пикселей, используя тригонометрические функции Math.cos и Math.sin.
graphics.lineStyle(2, 0x00aa00);
graphics.lineBetween(400, 300,
400 + Math.cos(normalAngle) * 100,
300 + Math.sin(normalAngle) * 100);
Наконец, угол конвертируется в градусы (для удобства чтения) и выводится на экран.
text.setText(`Line Normal Angle: ${Phaser.Math.RadToDeg(normalAngle)}`);
Практическое применение в играх
1. **Физика отскока (Bouncing):** Чтобы отразить вектор скорости объекта от линии (стены), вам нужна её нормаль. По формуле отражения вы сможете рассчитать новый направляющий вектор. 2. **Скольжение вдоль поверхности:** Если персонаж движется вдоль стены, его направление часто корректируется проекцией вектора скорости на нормаль, чтобы не "залипать". 3. **Определение стороны:** Сравнив нормаль с вектором "от объекта к точке", можно определить, находится ли точка слева или справа от отрезка. Это полезно для AI и геометрических тестов. 4. **Генерация смещений:** Нормаль — это идеальное направление для смещения параллельных линий, создания контуров или эффектов "выдавливания" (extrude) для 2D-графики.
Что попробовать дальше
Метод Phaser.Geom.Line.NormalAngle предоставляет простой и эффективный способ получить перпендикулярное направление к отрезку, открывая дверь к реализации реалистичной 2D-физики и геометрических механик.
**Идеи для экспериментов:**
1. Модифицируйте пример, чтобы нормаль отрисовывалась из середины отрезка, а не из его начала.
2. Создайте сцену с несколькими статичными линиями-стенами и шариком, который от них реалистично отскакивает, используя рассчитанную нормаль для изменения его скорости.
3. Используйте нормаль для создания эффекта "свечения" или тени, отбрасываемой от линии в перпендикулярном направлении.
