О чем этот пример
Плавные, органичные линии и траектории — основа визуального языка многих игр, от трасс гоночных симуляторов до магических заклинаний. Phaser предоставляет мощный, но простой инструмент для работы с ними: объект `Curve`. В этой статье мы разберем, как создавать кривые Безье третьего порядка, визуализировать их на сцене и динамически управлять их положением с помощью мыши. Этот навык пригодится для создания нелинейных путей движения, сложных интерфейсов и динамической анимации.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
create ()
{
const startPoint = new Phaser.Math.Vector2(0, 300);
const controlPoint1 = new Phaser.Math.Vector2(100, 100);
const controlPoint2 = new Phaser.Math.Vector2(200, 100);
const endPoint = new Phaser.Math.Vector2(300, 300);
const curve = new Phaser.Curves.CubicBezier(startPoint, controlPoint1, controlPoint2, endPoint);
const r = this.add.curve(400, 300, curve, 0x00aa00);
r.setStrokeStyle(4, 0xff0000);
// r.setAlpha(0.5);
// r.setAngle(20);
// r.setOrigin(1);
this.input.on('pointermove', pointer =>
{
r.x = pointer.x;
r.y = pointer.y;
});
}
}
const config = {
type: Phaser.WEBGL,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
Создание кривой: определяем узловые точки
Кривая Безье третьего порядка определяется четырьмя точками: начальной, конечной и двумя контрольными. Контрольные точки не лежат на самой кривой, но задают её форму, "притягивая" линию к себе. В Phaser для работы с точками удобно использовать класс Phaser.Math.Vector2.
const startPoint = new Phaser.Math.Vector2(0, 300);
const controlPoint1 = new Phaser.Math.Vector2(100, 100);
const controlPoint2 = new Phaser.Math.Vector2(200, 100);
const endPoint = new Phaser.Math.Vector2(300, 300);
Следующим шагом создаем объект кривой, передавая эти точки в конструктор Phaser.Curves.CubicBezier. Этот объект является математическим описанием кривой и пока не отображается на экране.
Визуализация кривой на сцене
Чтобы увидеть кривую, нужно создать игровой объект типа Curve. Для этого используется фабричный метод сцены this.add.curve(). Первые два аргумента задают мировые координаты, куда будет помещен центр этого графического объекта, третий аргумент — сама созданная нами кривая, а четвертый — цвет заливки.
const curve = new Phaser.Curves.CubicBezier(startPoint, controlPoint1, controlPoint2, endPoint);
const r = this.add.curve(400, 300, curve, 0x00aa00);
По умолчанию кривая отрисовывается с заливкой. Чтобы сделать видимым только контур (обводку), используем метод setStrokeStyle. Первый аргумент — толщина линии в пикселях, второй — цвет.
r.setStrokeStyle(4, 0xff0000);
Теперь на сцене отобразится красная кривая линия толщиной 4 пикселя.
Динамическое управление положением
Объект Curve, созданный через this.add.curve(), является наследником Phaser.GameObjects.GameObject. Это значит, что мы можем управлять его стандартными свойствами, такими как позиция (`x,y), прозрачность или угол поворота. В примере привязка к движению мыши реализована через слушатель событияpointermove`.
this.input.on('pointermove', pointer => {
r.x = pointer.x;
r.y = pointer.y;
});
Каждый раз при движении курсора координаты объекта `r` обновляются, и вся кривая плавно перемещается по сцене, следуя за указателем. Это демонстрирует, что кривая жестко привязана к позиции своего игрового объекта.
Эксперименты со свойствами объекта
Код содержит несколько закомментированных строк, которые показывают другие возможности объекта. Раскомментируйте их по очереди, чтобы увидеть эффект.
Метод setAlpha изменяет прозрачность всего объекта. Значение 0.5 сделает его полупрозрачным.
// r.setAlpha(0.5);
Метод setAngle поворачивает объект вокруг его точки происхождения (origin). Угол задается в градусах.
// r.setAngle(20);
Метод setOrigin изменяет точку привязки (origin) объекта. Значение `1установит её в правый нижний угол. Все трансформации (позиция, поворот) будут отсчитываться от этой новой точки. Это особенно заметно при повороте (setAngle`) и в нашем примере с движением мыши — объект будет "привязан" к курсору своим нижним правым углом.
// r.setOrigin(1);
Что попробовать дальше
Кривые Безье в Phaser — это гибкий инструмент для описания сложных нелинейных путей. Вы научились создавать их, настраивать стиль отображения и управлять ими как обычными игровыми объектами. Для экспериментов попробуйте: анимировать контрольные точки для создания "живой", дышащей линии; использовать кривую как путь для движения спрайта с помощью Follower; или создать несколько связанных кривых для рисования сложных символов и узоров прямо во время игры.
