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

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

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        const graphics = this.add.graphics({ lineStyle: { width: 1, color: 0x00ff00 }, fillStyle: { color: 0xffff00 }});

        const rect = new Phaser.Geom.Rectangle(100, 100, 500, 400);

        graphics.strokeRectShape(rect);

        //  Get 64 points around the rectangle
        // var points = rect.getPoints(64);

        //  Every point will be 50px apart (note the 'false' given for the quantity argument)
        //  If the stepRate doesn't divide equally into the rectangle dimensions then you'll get offset values at the end
        const points = rect.getPoints(false, 50);

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

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

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

const game = new Phaser.Game(config);

Создаем прямоугольник и графику

В примере мы работаем внутри метода create сцены. Сначала создаем объект graphics для отрисовки линий и фигур. Затем создаем прямоугольник с координатами (100, 100), шириной 500 и высотой 400 пикселей.

const graphics = this.add.graphics({ lineStyle: { width: 1, color: 0x00ff00 }, fillStyle: { color: 0xffff00 }});

const rect = new Phaser.Geom.Rectangle(100, 100, 500, 400);

Зеленой линией (strokeRectShape) рисуем контур прямоугольника, чтобы видеть его границы.

Метод getPoints: два режима работы

Ключевой метод rect.getPoints может работать в двух режимах. Первый аргумент определяет режим: - Если передано число (например, 64), метод вернет указанное количество точек, равномерно распределенных по периметру. - Если передано false, активируется второй режим: второй аргумент (stepRate) задает расстояние между точками в пикселях.

В примере используется второй режим с шагом 50 пикселей.

const points = rect.getPoints(false, 50);

Метод проходит по периметру прямоугольника, начиная с левого верхнего угла, и возвращает массив точек (Phaser.Geom.Point). Если шаг не делит стороны ровно, последние точки на каждой стороне могут сместиться.

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

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

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

Цикл проходит по всем точкам. Для каждой точки `p` рисуется квадрат размером 8x8 пикселя, центрированный на координатах точки (смещение на -4 по осям).

Практическое применение: патрульные пути и границы

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

// Предположим, у нас есть спрайт охранника
const guard = this.add.sprite(points[0].x, points[0].y, 'guard');
this.tweens.add({
    targets: guard,
    props: {
        x: { value: points.map(p => p.x), duration: 10000 },
        y: { value: points.map(p => p.y), duration: 10000 }
    },
    repeat: -1
});

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

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

Метод getPoints класса Phaser.Geom.Rectangle — мощный инструмент для работы с границами областей. Он избавляет от ручных расчетов и позволяет легко получать координаты для размещения объектов или задания движения. Поэкспериментируйте: попробуйте разные значения stepRate, создайте несколько прямоугольников с разными точками, используйте точки для генерации частиц вдоль границ или для создания динамических барьеров, которые меняют форму во время игры.