О чем этот пример
Создание нелинейных траекторий движения — ключ к оживлению игрового мира. Встроенные механики Phaser 3 для работы с путями (Paths) позволяют легко задавать сложные маршруты для персонажей, врагов или камеры, экономя время на ручном программировании анимации. В этой статье мы разберем пример, где спрайт лемминга движется по гладкой сплайновой кривой, автоматически поворачиваясь вдоль её направления, что создает эффект естественного и правдоподобного движения.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('lemming', 'assets/sprites/lemming.png');
}
create ()
{
const points = [
50, 300, 179, 449, 394, 498, 593, 455,
701, 338, 692, 190, 603, 76, 423, 41,
272, 78, 181, 186, 230, 328, 416, 395,
565, 327, 550, 202, 467, 149, 355, 164,
343, 254, 428, 303
];
const curve = new Phaser.Curves.Spline(points);
const graphics = this.add.graphics();
graphics.lineStyle(1, 0xffffff, 0.5);
curve.draw(graphics, 128);
graphics.fillStyle(0x00ff00, 0.5);
for (let i = 0; i < curve.points.length; i++)
{
graphics.fillCircle(curve.points[i].x, curve.points[i].y, 4);
}
const lemming = this.add.follower(curve, 50, 300, 'lemming');
lemming.startFollow({
duration: 10000,
yoyo: true,
repeat: -1,
rotateToPath: true,
verticalAdjust: true
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Создание кривой пути
Основой для движения объекта служит кривая, или Path. В Phaser 3 для этого есть несколько классов. В примере используется Phaser.Curves.Spline, который создает плавную кривую, проходящую через заданные контрольные точки.
Массив points содержит пары координат X и Y. Это и есть наши контрольные точки, через которые будет проходить кривая.
const points = [
50, 300, 179, 449, 394, 498, 593, 455,
701, 338, 692, 190, 603, 76, 423, 41,
272, 78, 181, 186, 230, 328, 416, 395,
565, 327, 550, 202, 467, 149, 355, 164,
343, 254, 428, 303
];
const curve = new Phaser.Curves.Spline(points);
Визуализация пути и точек
Для отладки и наглядности полезно видеть, как именно проходит наш путь. Для этого используется объект Graphics. Сначала мы задаем стиль линии и рисуем саму кривую с помощью метода curve.draw(). Аргумент 128 определяет количество сегментов для отрисовки — чем больше, тем глаже будет выглядеть кривая.
Затем зелеными кружочками отрисовываются сами контрольные точки, чтобы видеть, через какие координаты проходит сплайн.
const graphics = this.add.graphics();
graphics.lineStyle(1, 0xffffff, 0.5);
curve.draw(graphics, 128);
graphics.fillStyle(0x00ff00, 0.5);
for (let i = 0; i < curve.points.length; i++)
{
graphics.fillCircle(curve.points[i].x, curve.points[i].y, 4);
}
Создание преследователя пути (Follower)
Ключевой объект для анимации движения по пути — это Follower. Он создается с помощью фабричного метода this.add.follower(). В него передается созданная ранее кривая (curve), начальные координаты (они должны совпадать с первой точкой кривой для плавного старта) и ключ текстуры спрайта.
Объект lemming теперь является контейнером, который "знает" о своем пути и может по нему двигаться.
const lemming = this.add.follower(curve, 50, 300, 'lemming');
Запуск движения с поворотом
Движение запускается методом lemming.startFollow(), который принимает объект конфигурации. Именно здесь настраивается поведение анимации.
- duration: Время в миллисекундах, за которое follower пройдет весь путь от начала до конца.
- yoyo: Если true, объект, дойдя до конца пути, развернется и пойдет обратно.
- repeat: Количество повторений (-1 для бесконечного повтора).
- rotateToPath: Самая важная для нашей задачи настройка. При значении true спрайт будет автоматически поворачиваться так, чтобы его направление "взгляда" совпадало с касательной к пути в текущей точке. Это создает иллюзию, что лемминг поворачивает за поворотом дороги.
- verticalAdjust: Опция, которая немного смещает точку вращения спрайта для более естественного выравнивания относительно пути.
lemming.startFollow({
duration: 10000,
yoyo: true,
repeat: -1,
rotateToPath: true,
verticalAdjust: true
});
Что попробовать дальше
Использование Phaser.Curves в паре с Follower и опцией rotateToPath — это мощный и лаконичный способ анимировать движение по сложным траекториям. Для экспериментов попробуйте изменить форму кривой, добавив или убрав контрольные точки. Поиграйте с параметрами duration и ease (не использован в примере) для изменения скорости и плавности хода. Можно создать несколько последовательных кривых и заставить follower переходить с одной на другую, создавая многоэтапные маршруты для патрулирования врагов или квестовых путешествий героя.
