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

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

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

Живой запуск

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

Исходный код


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

        const points = [];
        const rect = new Phaser.Geom.Rectangle(0, 0, 200, 150);

        this.input.on('pointerdown', () =>
        {
            Phaser.Geom.Rectangle.Decompose(rect, points);
            redraw();
        });

        this.input.on('pointermove', pointer =>
        {
            Phaser.Geom.Rectangle.CenterOn(rect, pointer.x, pointer.y);
            redraw();
        });

        function redraw ()
        {
            graphics.clear();

            graphics.strokeRectShape(rect);

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

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

const game = new Phaser.Game(config);

Подготовка сцены и данных

В начале метода create() создаются основные объекты: Graphics для отрисовки и массив points для хранения точек. Прямоугольник rect инициализируется с начальными размерами.

const graphics = this.add.graphics({ fillStyle: { color: 0x0000aa }, lineStyle: { color: 0x0000aa } });

const points = [];
const rect = new Phaser.Geom.Rectangle(0, 0, 200, 150);

Обработка ввода: движение и клик

Для интерактивности добавляются два слушателя событий от мыши. При движении указателя прямоугольник центрируется на его координатах с помощью Phaser.Geom.Rectangle.CenterOn. Это изменяет положение rect, не затрагивая его размеры.

this.input.on('pointermove', pointer =>
{
    Phaser.Geom.Rectangle.CenterOn(rect, pointer.x, pointer.y);
    redraw();
});

При клике вызывается ключевой метод Phaser.Geom.Rectangle.Decompose. Он разбирает прямоугольник на его четыре угловые точки и помещает их в массив points. Каждый новый клик добавляет точки в массив заново.

this.input.on('pointerdown', () =>
{
    Phaser.Geom.Rectangle.Decompose(rect, points);
    redraw();
});

Визуализация: отрисовка фигур

Функция redraw() отвечает за графику. Она очищает холст, рисует контур прямоугольника через graphics.strokeRectShape, а затем отображает все точки из массива points как закрашенные круги.

function redraw ()
{
    graphics.clear();

    graphics.strokeRectShape(rect);

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

Конфигурация и запуск игры

Стандартная конфигурация Phaser задаёт размеры окна, тип рендерера и указывает нашу сцену Example. После создания экземпляра Game сцена становится активной.

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

const game = new Phaser.Game(config);

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

Метод Decompose — это мост между прямоугольником как единой фигурой и его вершинами как отдельными объектами. Используйте его для создания систем, где важны углы фигуры: например, для расстановки объектов по периметру, вычисления столкновений в конкретных точках или генерации сетки на основе прямоугольной области. Поэкспериментируйте: измените логику так, чтобы точки не накапливались, а обновлялись при каждом клике, или используйте полученные координаты для построения линий между ними с помощью graphics.strokePoints.