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

При разработке игр часто возникает необходимость работать с геометрическими объектами: рассчитывать траектории, расставлять объекты вдоль пути, создавать эффекты частиц. Библиотека геометрии Phaser предоставляет для этого мощные и простые в использовании инструменты. В этой статье мы разберем, как с помощью класса `Phaser.Geom.Line` и метода `getPoints()` получить равномерно распределенный набор точек вдоль отрезка. Этот прием полезен для создания путей следования врагов, визуализации траекторий снарядов или равномерного размещения декораций.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        const graphics = this.add.graphics({ fillStyle: { color: 0xff0000 }});

        const line = new Phaser.Geom.Line(100, 100, 600, 500);

        const points = line.getPoints(32);

        for (let i = 0; i < points.length; i++)
        {
            const p = points[i];

            graphics.fillRect(p.x - 2, p.y - 2, 4, 4);
        }
    }
}

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

const game = new Phaser.Game(config);

Создание линии

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

Создадим отрезок от точки (100, 100) до точки (600, 500). Координаты задаются в пикселях относительно левого верхнего угла игрового холста.

const line = new Phaser.Geom.Line(100, 100, 600, 500);

Получение массива точек

Ключевой метод для нашей задачи — getPoints(quantity). Он принимает один аргумент — количество точек, которое нужно получить, и возвращает массив объектов. Каждый объект в массиве имеет свойства `xиy`.

Важно понимать, что точки распределяются равномерно по всей длине линии, включая ее начало и конец. Если запросить 2 точки, вы получите начало и конец отрезка. Если 32 — 32 точки, равномерно разбросанные от начала до конца.

const points = line.getPoints(32);

Визуализация результата

Чтобы увидеть полученные точки, необходимо их нарисовать. В Phaser за отрисовку примитивов (линий, фигур, точек) отвечает объект Graphics. Мы создаем его, задаем стиль заливки красным цветом, а затем в цикле проходим по всем точкам из массива.

Для каждой точки мы рисуем небольшой квадрат (прямоугольник с заливкой) методом fillRect(). Его аргументы — координаты левого верхнего угла, ширина и высота. Чтобы точка оказалась в центре квадрата, мы смещаем координаты угла на половину размера квадрата (в нашем случае на -2 пикселя).

const graphics = this.add.graphics({ fillStyle: { color: 0xff0000 }});

for (let i = 0; i < points.length; i++)
{
    const p = points[i];
    graphics.fillRect(p.x - 2, p.y - 2, 4, 4);
}

Сцена и конфигурация игры

Весь рабочий код, как обычно в Phaser, размещается внутри методов сцены. В данном примере мы используем только метод create(), который выполняется один раз при создании сцены.

Конфигурационный объект config задает базовые параметры игры: размеры холста, тип рендерера (Phaser.AUTO позволяет движку выбрать WebGL или Canvas) и корневую сцену. Инициализация игры происходит через создание экземпляра класса Phaser.Game.

class Example extends Phaser.Scene
{
    create ()
    {
        // ... весь код из примеров выше
    }
}

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

const game = new Phaser.Game(config);

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

Метод getPoints() класса Phaser.Geom.Line — это простой и эффективный способ дискретизировать отрезок. Полученный массив точек можно использовать не только для отрисовки, но и как готовый путь для движения спрайта через Phaser.Math.Interpolation, как позиции для расстановки препятствий или как источник данных для систем частиц. Попробуйте поэкспериментировать: измените количество точек, чтобы увидеть, как меняется плотность. Используйте полученные координаты для анимации нескольких спрайтов вдоль линии или создайте эффект «построения» линии, последовательно отрисовывая точки с задержкой по времени.