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

Работа с кривыми — фундаментальный навык для создания динамичных игровых движений и эффектов. В Phaser кривые позволяют описывать траектории объектов, пути перемещения камеры или сложные формы. Часто требуется не просто отрисовать кривую, но и получить набор точек на ней для дальнейших вычислений: например, для размещения объектов вдоль пути с равными интервалами или для расчета позиций в определенные моменты времени. Метод `getSpacedPoints()` класса кривых решает именно эту задачу, предоставляя простой способ получить массив координат, равномерно распределенных по кривой.

Версия 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.getSpacedPoints(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, которые содержат координаты X и Y.

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

После создания кривая может быть отрисована на экране с помощью графического объекта (Graphics). Это помогает визуализировать путь, по которому мы будем распределять точки.

Визуализация кривой с помощью Graphics

Для рисования в Phaser используется объект Graphics. В примере сначала задается стиль линии: толщина, цвет и альфа (прозрачность). Затем кривая рисуется на этом графическом объекте методом draw().

const graphics = this.add.graphics();
graphics.lineStyle(1, 0xffffff, 1);
curve.draw(graphics);

Это создает на экране белый контур нашей линии от точки (100,100) до точки (600,400). Графический объект служит основным инструментом для отображения векторных форм и кривых в реальном времени.

Получение равномерно распределенных точек

Ключевой метод в примере — curve.getSpacedPoints(32). Он возвращает массив из 32 объектов Vector2. Каждый объект представляет координаты точки на кривой. Метод автоматически рассчитывает позиции так, чтобы расстояние между соседними точками вдоль кривой было одинаковым.

const points = curve.getSpacedPoints(32);

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

Отрисовка полученных точек

После получения массива точек мы можем их визуализировать, чтобы убедиться в правильности распределения. В примере меняется стиль заполнения графического объекта на красный цвет и для каждой точки рисуется маленький круг.

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

Цикл проходит по всем элементам массива points и использует их координаты .x и .y для рисования круга радиусом 4 пикселя. Это создает четкую визуализацию равномерного распределения точек вдоль линии.

Практическое применение в играх

Метод getSpacedPoints() полезен не только для линий, но и для любых кривых в Phaser (например, Spline, Quadratic Bezier, Cubic Bezier). Вот несколько практических сценариев использования:

- **Размещение препятствий вдоль пути:** Вы можете создать сложный кривой путь и равномерно разместить на нем препятствия, чтобы игроку приходилось преодолевать их с постоянными интервалами. - **Создание траектории снаряда:** Если снаряд движется по кривой траектории, вы можете получить точки для расчета позиций в разные моменты времени и предсказать его движение. - **Анимация движения объекта:** Перемещение объекта вдоль кривой с постоянной скоростью требует знания позиций на кривой в разные моменты времени. Массив равномерных точек можно использовать для этой задачи.

// Пример: размещение спрайтов вдоль кривой
const spritePath = new Phaser.Curves.Spline([ /* точки сплайна */ ]);
const positions = spritePath.getSpacedPoints(10);
positions.forEach(point => {
    this.add.sprite(point.x, point.y, 'enemy');
});

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

Метод getSpacedPoints() — мощный и простой инструмент для работы с кривыми в Phaser. Он позволяет абстрагироваться от математических расчетов и быстро получить набор координат для реализации игровых механик, связанных с движением и размещением объектов. Для экспериментов попробуйте использовать разные типы кривых (сплайны, кривые Безье) и разное количество точек. Также можно изменить код, чтобы точки не просто отрисовывались, но и становились, например, спрайтами врагов или элементами уровня.