О чем этот пример
Создание плавных и сложных траекторий движения — частая задача в разработке игр: полёт снаряда, патрулирование врага, движение камеры. Встроенный в Phaser класс `CubicBezier` позволяет легко описывать такие пути с помощью кубических кривых Безье, используя всего четыре точки. В этой статье мы разберём пример, где объект плавно движется по заданной кривой, и научимся применять этот подход в своих проектах.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
graphics;
curve;
path;
create ()
{
this.graphics = this.add.graphics();
this.path = { t: 0, vec: new Phaser.Math.Vector2() };
const startPoint = new Phaser.Math.Vector2(100, 500);
const controlPoint1 = new Phaser.Math.Vector2(50, 100);
const controlPoint2 = new Phaser.Math.Vector2(600, 100);
const endPoint = new Phaser.Math.Vector2(700, 500);
this.curve = new Phaser.Curves.CubicBezier(startPoint, controlPoint1, controlPoint2, endPoint);
this.tweens.add({
targets: this.path,
t: 1,
ease: 'Sine.easeInOut',
duration: 2000,
yoyo: true,
repeat: -1
});
}
update ()
{
this.graphics.clear();
this.graphics.lineStyle(1, 0x00ff00, 1);
this.curve.draw(this.graphics);
this.curve.getPoint(this.path.t, this.path.vec);
this.graphics.fillStyle(0xff0000, 1);
this.graphics.fillCircle(this.path.vec.x, this.path.vec.y, 16);
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Подготовка сцены и создание кривой
В методе create() мы подготавливаем всё необходимое для работы с графикой и анимацией. Сначала создаётся объект Graphics для отрисовки линий и фигур.
Затем определяется объект path, который будет хранить текущую позицию на кривой (параметр `t` от 0 до 1) и вектор для расчётов.
Четыре вектора задают контрольные точки кривой Безье: начальную, две контрольные и конечную. Именно они определяют форму траектории.
this.graphics = this.add.graphics();
this.path = { t: 0, vec: new Phaser.Math.Vector2() };
const startPoint = new Phaser.Math.Vector2(100, 500);
const controlPoint1 = new Phaser.Math.Vector2(50, 100);
const controlPoint2 = new Phaser.Math.Vector2(600, 100);
const endPoint = new Phaser.Math.Vector2(700, 500);
this.curve = new Phaser.Curves.CubicBezier(startPoint, controlPoint1, controlPoint2, endPoint);
Анимация параметра вдоль кривой
Чтобы объект двигался по кривой, нам нужно анимировать параметр `t. Приt = 0объект находится в начале кривой, приt = 1` — в конце.
Здесь на помощь приходит система твинов Phaser. Мы создаём твин, который циклически меняет значение this.path.t от 0 до 1 и обратно (yoyo: true).
this.tweens.add({
targets: this.path,
t: 1,
ease: 'Sine.easeInOut',
duration: 2000,
yoyo: true,
repeat: -1
});
Параметр ease: 'Sine.easeInOut' обеспечивает плавное ускорение и замедление движения, что делает анимацию более естественной.
Отрисовка кривой и объекта в update
Каждый кадр в методе update() мы перерисовываем сцену. Сначала очищаем холст Graphics.
Затем задаём стиль линии и рисуем саму кривую Безье для визуализации траектории.
this.graphics.clear();
this.graphics.lineStyle(1, 0x00ff00, 1);
this.curve.draw(this.graphics);
Далее, используя текущее значение this.path.t, мы получаем координаты точки на кривой с помощью метода curve.getPoint(). Результат записывается в вектор this.path.vec.
this.curve.getPoint(this.path.t, this.path.vec);
Наконец, в этой позиции отрисовывается красный круг, представляющий движущийся объект.
this.graphics.fillStyle(0xff0000, 1);
this.graphics.fillCircle(this.path.vec.x, this.path.vec.y, 16);
Конфигурация игры и запуск
Это стандартная конфигурация для примера Phaser. В ней задаются размеры холста, цвет фона и указывается класс нашей сцены.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что попробовать дальше
Кубические кривые Безье в Phaser — мощный и простой инструмент для создания сложных предопределённых траекторий. Экспериментируйте: попробуйте привязать к движению по кривой спрайт врага или снаряда, измените контрольные точки для создания петель или резких поворотов, используйте несколько кривых для составных маршрутов или примените этот метод для плавного перемещения игровой камеры между точками интереса.
