Path: составные кривые и движение по ним

В библиотеке Phaser объекты типа Path предназначены для создания траекторий, по которым могут двигаться спрайты, камеры или другие объекты сцены. Path представляет собой последовательность сегментов, которые могут быть линейными, кривыми Безье или эллиптическими дугами. Ключевое преимущество использования Path заключается в возможности анимировать объекты по сложным маршрутам без необходимости вручную рассчитывать каждую координату.


Создание Path и добавление сегментов

Объект Path создается с помощью конструктора Phaser.Curves.Path:

let path = new Phaser.Curves.Path(x, y);

Параметры x и y задают начальную точку траектории. После создания Path можно расширять сегментами:

  • Линейные сегменты:
path.lineTo(x, y);

Создает прямую линию от текущей точки до указанной координаты.

  • Квадратичные кривые Безье:
path.quadraticBezierTo(cx, cy, x, y);

cx, cy — контрольная точка, x, y — конечная точка кривой. Кривая проходит через контрольную точку, сглаживая переход между начальной и конечной точками.

  • Кубические кривые Безье:
path.cubicBezierTo(cx1, cy1, cx2, cy2, x, y);

Позволяет создать более сложную кривую с двумя контрольными точками.

  • Эллиптические дуги:
path.ellipseTo(width, height, startAngle, endAngle, clockwise);

Создает сегмент дуги. Параметры startAngle и endAngle задаются в радианах, clockwise определяет направление движения.


Применение Path к объектам

После создания траектории можно перемещать по ней спрайты с помощью класса Phaser.GameObjects.PathFollower. Это облегчает анимацию движения без ручного расчета координат.

let sprite = this.add.follower(path, startX, startY, 'spriteKey');
sprite.startFollow({
    duration: 4000,
    repeat: -1,
    yoyo: true,
    rotateToPath: true
});

Ключевые параметры startFollow:

  • duration — время прохождения пути в миллисекундах.
  • repeat — количество повторов (-1 — бесконечно).
  • yoyo — обратное движение после достижения конца пути.
  • rotateToPath — автоматический поворот спрайта вдоль кривой.

Работа с длиной Path и положением на кривой

Phaser позволяет вычислять длину Path и позиции объектов вдоль него:

let length = path.getLength();
let point = path.getPoint(t); // t от 0 до 1
  • getLength() возвращает полную длину траектории в пикселях.
  • getPoint(t) возвращает координаты точки на траектории, где t — нормализованное значение прогресса (0 — начало, 1 — конец).
  • getPointAt(distance) возвращает координаты точки на определенном расстоянии вдоль траектории.

Эти методы позволяют синхронизировать движение нескольких объектов или вычислять положение объектов без PathFollower.


Соединение нескольких Path и сложные маршруты

Можно комбинировать несколько Path, создавая сложные маршруты:

let path1 = new Phaser.Curves.Path(100, 100);
path1.lineTo(200, 100);

let path2 = new Phaser.Curves.Path(200, 100);
path2.quadraticBezierTo(250, 50, 300, 100);

let combinedPath = new Phaser.Curves.Path(100, 100);
combinedPath.add(path1.curves[0]);
combinedPath.add(path2.curves[0]);

Каждый сегмент Path сохраняется в массиве curves. Это позволяет динамически изменять траекторию, добавляя или удаляя сегменты во время выполнения игры.


Анимация и управление движением

Path предоставляет гибкие способы управления движением объектов:

  • Изменение скорости на лету:
sprite.pathTween.timeScale = 2; // ускорение в 2 раза
  • Получение текущей позиции и направления:
let t = sprite.pathFollower.t; // текущий прогресс (0–1)
let point = sprite.pathFollower.getPoint(t);
let tangent = sprite.pathFollower.getTangent(t); // направление движения
  • Прерывание и продолжение движения:
sprite.stopFollow();
sprite.startFollow({ duration: 2000, from: 0.5 }); // продолжение с середины пути

Визуализация Path

Для отладки удобно визуализировать траектории с помощью Graphics:

let graphics = this.add.graphics();
graphics.lineStyle(2, 0xff0000, 1);
path.draw(graphics);
  • lineStyle(width, color, alpha) задает стиль линии.
  • Метод draw() автоматически проходит по всем сегментам Path и отображает их.

Практические советы

  • Для плавных анимаций использовать кривые Безье вместо линейных сегментов.
  • Разделять длинные маршруты на несколько Path для удобного управления и повторного использования сегментов.
  • Комбинировать Path с Tween для создания эффекта ускорения и замедления движения.
  • Использовать rotateToPath только для объектов с явно выраженным направлением, например, транспортных средств или персонажей.

Path в Phaser — мощный инструмент для создания сложных и плавных анимаций движения, позволяющий объединять простые линии, кривые Безье и дуги в единый маршрут с полной поддержкой динамического управления.