О чем этот пример
При разработке игр часто возникает необходимость работать с геометрическими объектами: рассчитывать траектории, расставлять объекты вдоль пути, создавать эффекты частиц. Библиотека геометрии 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, как позиции для расстановки препятствий или как источник данных для систем частиц.
Попробуйте поэкспериментировать: измените количество точек, чтобы увидеть, как меняется плотность. Используйте полученные координаты для анимации нескольких спрайтов вдоль линии или создайте эффект «построения» линии, последовательно отрисовывая точки с задержкой по времени.
