О чем этот пример

Использование кривых Безье и сплайнов — мощный инструмент в арсенале геймдева. Вместо создания сложных спрайтовых анимаций или горы спрайтов для траекторий, вы можете генерировать плавные, гибкие пути прямо в коде. Это пригодится для создания траекторий снарядов, патрульных маршрутов врагов, плавных интерфейсных линий или основ для генерации уровней. В этой статье на примере класса `Phaser.Curves.Spline` и игрового объекта 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.Spline([
            100, 500,
            260, 450,
            300, 250,
            550, 145,
            745, 256
        ]);

        const r = this.add.curve(400, 300, curve);

        r.setStrokeStyle(2, 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);

Создание объекта Curve и определение сплайна

Основная магия происходит в методе create сцены. Сначала мы создаем сплайн — плавную кривую, проходящую через заданные точки. В Phaser для этого используется класс Phaser.Curves.Spline. Он принимает массив чисел, где каждая пара значений представляет собой координаты X и Y контрольной точки.

Затем, чтобы отобразить эту кривую на сцене, мы используем фабричный метод this.add.curve(). Этот метод создает специальный игровой объект — Curve. Он принимает начальные мировые координаты (x, y) для позиционирования самой кривой и объект кривой (в нашем случае — сплайн) в качестве третьего аргумента.

const curve = new Phaser.Curves.Spline([
    100, 500,
    260, 450,
    300, 250,
    550, 145,
    745, 256
]);

const r = this.add.curve(400, 300, curve);

Стилизация и свойства кривой

По умолчанию кривая рисуется черным цветом. Чтобы сделать её видимой, необходимо задать стиль обводки с помощью метода setStrokeStyle. Первый параметр — толщина линии в пикселях, второй — цвет в числовом формате (hex).

Объект Curve наследуется от GameObject и обладает многими стандартными свойствами, которые закомментированы в примере. Вы можете экспериментировать с ними, раскомментировав строки: - setAlpha изменяет прозрачность всей кривой. - setAngle поворачивает кривую вокруг её точки начала (origin). - setOrigin меняет точку начала (anchor point) объекта. Значение (1, 1) сместит её в правый нижний угол bounding box'а кривой, что изменит эффект от позиционирования и вращения.

r.setStrokeStyle(2, 0xff0000);
// r.setAlpha(0.5);
// r.setAngle(20);
// r.setOrigin(1);

Интерактивность: привязка кривой к курсору

Самая интересная часть примера — это добавление динамики. Мы подписываемся на событие перемещения указателя (pointermove) системы ввода Phaser (this.input). В обработчике события мы просто обновляем мировые координаты `xиyнашего объектаCurve(переменнаяr`), устанавливая их равными координатам курсора.

Важно понимать: мы перемещаем не точки сплайна, а весь игровой объект Curve, внутри которого отрисована наша кривая. Сама форма кривой (её контрольные точки) остаётся неизменной относительно объекта. Это эффективно и позволяет легко анимировать сложные траектории.

this.input.on('pointermove', pointer => {
    r.x = pointer.x;
    r.y = pointer.y;
});

Что попробовать дальше

Как видите, с помощью всего нескольких строк кода в Phaser 3 можно создавать и управлять сложными векторными формами. Объект Curve — это полноценный игровой объект, который можно анимировать, трансформировать и использовать в физических взаимодействиях. **Идеи для экспериментов:** 1. Свяжите контрольные точки сплайна с позициями других игровых объектов (дружественных юнитов, планет) для создания динамических соединительных линий. 2. Используйте curve.getPoints(quantity) для получения массива точек вдоль кривой и разместите по этим точкам спрайты, создав эффект «поезда» или пунктирной траектории. 3. Анимируйте отдельные контрольные точки сплайна с помощью Tween, чтобы кривая «ожила» и плавно меняла свою форму прямо во время игры.