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

Работа с кривыми — важный навык для создания плавных траекторий движения, путей для врагов или генерации сложных форм. В этой статье мы разберем, как использовать класс `Phaser.Curves.Line` для создания линейной кривой и, что более важно, как получить набор точек вдоль неё. Этот подход открывает возможности для точного позиционирования объектов, визуальной отладки путей и создания procedural-контента.

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        const graphics = this.add.graphics();

        const curve = new Phaser.Curves.Line(new Phaser.Math.Vector2(100, 100), new Phaser.Math.Vector2(600, 400));

        graphics.lineStyle(1, 0xffffff, 1);

        curve.draw(graphics);

        //  Get 32 points from the curve
        const points = curve.getPoints(32);

        //  Draw the points
        graphics.fillStyle(0xff0000, 1);

        for (let i = 0; i < points.length; i++)
        {
            graphics.fillCircle(points[i].x, points[i].y, 4);
        }
    }
}

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    backgroundColor: '#2d2d2d',
    parent: 'phaser-example',
    scene: Example
};

const game = new Phaser.Game(config);

Создание линейной кривой

Класс Phaser.Curves.Line представляет собой простейшую кривую — прямую линию между двумя точками. Для её создания необходимо указать начальный и конечный вектор (Phaser.Math.Vector2).

const curve = new Phaser.Curves.Line(
    new Phaser.Math.Vector2(100, 100),
    new Phaser.Math.Vector2(600, 400)
);

После создания кривую можно визуализировать с помощью объекта Graphics. Устанавливаем стиль линии и вызываем метод draw.

graphics.lineStyle(1, 0xffffff, 1);
curve.draw(graphics);

Получение точек на кривой

Самая полезная функция для работы с кривыми — getPoints(quantity). Она возвращает массив точек (векторов), равномерно распределённых вдоль всей длины кривой. Количество точек задаётся аргументом.

const points = curve.getPoints(32);

В данном примере мы запрашиваем 32 точки. Эти точки идеально подходят для последующего использования: например, для размещения спрайтов, проверки коллизий или создания эффектов.

Визуализация полученных точек

Чтобы убедиться, что точки получены корректно, их можно отрисовать. Для этого используем тот же объект Graphics, но сменим стиль заливки на красный и пройдёмся по массиву точек в цикле.

graphics.fillStyle(0xff0000, 1);
for (let i = 0; i < points.length; i++)
{
    graphics.fillCircle(points[i].x, points[i].y, 4);
}

Код отрисует красные круги радиусом 4 пикселя в каждой из 32 позиций, наглядно демонстрируя равномерное распределение точек по прямой линии.

Практическое применение: движение объекта

Полученный массив точек можно использовать не только для отрисовки. Например, вы можете заставить спрайт двигаться по этим точкам, создавая плавный патрульный путь.

// Предположим, this.sprite — ваш игровой объект
let currentPointIndex = 0;

// В update-цикле сцены:
if (currentPointIndex < points.length) {
    this.sprite.x = points[currentPointIndex].x;
    this.sprite.y = points[currentPointIndex].y;
    currentPointIndex++;
}

Это базовый пример; в реальном проекте для плавности лучше использовать Phaser.Math.Interpolation или tween-анимацию между точками.

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

Метод getPoints — это мощный инструмент для декомпозиции кривой на управляемые сегменты. Поэкспериментируйте: измените тип кривой на Spline или Quadratic Bezier, варьируйте количество точек и используйте их для генерации уровня, расстановки препятствий или создания сложной траектории снаряда. Это основа для procedural-подходов в вашей игре.