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

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

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        const graphics = this.add.graphics();

        const rectangles = [];

        for (let x = 0; x < 16; x++)
        {
            for (let y = 0; y < 12; y++)
            {
                const size = Phaser.Math.Between(1, 5) * 10;

                rectangles.push(new Phaser.Geom.Rectangle(x * 50, y * 50, size, size));
            }
        }

        const pointerRect = new Phaser.Geom.Rectangle(0, 0, 50, 50);

        this.input.on('pointermove', pointer =>
        {

            // round position to 25 pixels
            const x = Math.round(pointer.x / 25) * 25;
            const y = Math.round(pointer.y / 25) * 25;

            pointerRect.setPosition(x, y);

            redraw();
        });

        redraw();

        function redraw ()
        {
            graphics.clear();
            graphics.lineStyle(2, 0x0000aa);

            let strokeRed = false;

            for (let i = 0; i < rectangles.length; i++)
            {
                graphics.strokeRectShape(rectangles[i]);
                strokeRed = strokeRed || Phaser.Geom.Rectangle.Equals(pointerRect, rectangles[i]);
            }

            if (strokeRed)
            {
                graphics.lineStyle(5, 0xaa0000);
            }
            else
            {
                graphics.lineStyle(5, 0x0000aa);
            }

            graphics.strokeRectShape(pointerRect);
        }
    }
}

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

const game = new Phaser.Game(config);

Что делает метод Rectangle.Equals?

Метод Phaser.Geom.Rectangle.Equals — это статическая функция, которая сравнивает два прямоугольника на полное равенство. Она возвращает true только если все свойства прямоугольников (координаты `x,y, ширинаwidthи высотаheight`) идентичны. Это строгое сравнение, полезное для проверки точного позиционирования.

В примере этот метод используется для сравнения прямоугольника, следующего за указателем, с массивом статических прямоугольников на сцене. Если найдено полное совпадение, цвет контура основного прямоугольника меняется.

Структура примера: создание сетки

Код создает сцену с сеткой из 192 прямоугольников случайного размера. Каждый прямоугольник представлен объектом Phaser.Geom.Rectangle.

const rectangles = [];

for (let x = 0; x < 16; x++)
{
    for (let y = 0; y < 12; y++)
    {
        const size = Phaser.Math.Between(1, 5) * 10;
        rectangles.push(new Phaser.Geom.Rectangle(x * 50, y * 50, size, size));
    }
}

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

Обработка движения указателя

Для плавного и привязанного к сетке движения используется событие pointermove. Позиция курсора округляется до шага в 25 пикселей, чтобы прямоугольник перемещался по фиксированной сетке, что упрощает визуальное сравнение и наложение.

this.input.on('pointermove', pointer =>
{
    const x = Math.round(pointer.x / 25) * 25;
    const y = Math.round(pointer.y / 25) * 25;
    pointerRect.setPosition(x, y);
    redraw();
});

После обновления позиции вызывается функция redraw() для перерисовки сцены.

Логика сравнения и отрисовки

Функция redraw() — это сердце примера. Она очищает холст, рисует все прямоугольники сетки и затем проверяет, совпадает ли pointerRect с любым из них.

function redraw ()
{
    graphics.clear();
    graphics.lineStyle(2, 0x0000aa);

    let strokeRed = false;

    for (let i = 0; i < rectangles.length; i++)
    {
        graphics.strokeRectShape(rectangles[i]);
        strokeRed = strokeRed || Phaser.Geom.Rectangle.Equals(pointerRect, rectangles[i]);
    }

    if (strokeRed)
    {
        graphics.lineStyle(5, 0xaa0000);
    }
    else
    {
        graphics.lineStyle(5, 0x0000aa);
    }

    graphics.strokeRectShape(pointerRect);
}

Ключевая строка — вызов Phaser.Geom.Rectangle.Equals(pointerRect, rectangles[i]). Флаг strokeRed становится true, если хотя бы одно сравнение вернуло true. В зависимости от этого флага меняется стиль линии для контура pointerRect.

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

Сцена добавляется в конфигурацию игры Phaser, которая инициализирует холст заданного размера.

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

const game = new Phaser.Game(config);

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

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

Метод Phaser.Geom.Rectangle.Equals — это простой, но точный инструмент для сравнения прямоугольников. В рассмотренном примере он используется для визуальной индикации совпадения, но в реальном проекте его можно применять для логики игровых механик, например, проверки, находится ли юнит точно в определенной клетке поля или активирована ли конкретная зона. Для экспериментов попробуйте изменить условие сравнения: проверяйте не полное равенство, а пересечение прямоугольников с помощью Phaser.Geom.Rectangle.Overlaps. Также можно добавить реакцию не только на совпадение, но и на близость фигур.