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

В игровой разработке проверка пересечений объектов — одна из ключевых механик, будь то столкновение пули с врагом или сбор предметов. В этой статье мы разберем пример из официальной документации Phaser, который наглядно демонстрирует, как работает проверка пересечения двух прямоугольников (`Phaser.Geom.Intersects.RectangleToRectangle`). Вы научитесь создавать динамические объекты, отслеживать их перемещение и визуализировать факт столкновения, что станет надежной основой для реализации физики в ваших 2D-играх.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    a = 0;
    pointerRect;
    rect;
    graphics;

    create ()
    {
        this.graphics = this.add.graphics({ fillStyle: { color: 0xaa0000} });

        this.rect = new Phaser.Geom.Rectangle(0, 0, 100, 150);
        this.pointerRect = new Phaser.Geom.Rectangle(450, 350, 150, 100);

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

            Phaser.Geom.Rectangle.CenterOn(this.pointerRect, pointer.x, pointer.y);

        });
    }

    update ()
    {
        this.a += 0.015;

        if (this.a > Math.PI * 4)
        {
            this.a -= Math.PI * 4;
        }

        const x = 400 - Math.cos(this.a / 2) * 400;
        const y = 300 - Math.sin(this.a * 2) * 300;

        Phaser.Geom.Rectangle.CenterOn(this.rect, x, y);

        this.graphics.clear();
        this.graphics.fillRectShape(this.rect);

        if (Phaser.Geom.Intersects.RectangleToRectangle(this.rect, this.pointerRect))
        {
            this.graphics.lineStyle(4, 0xaa0000);
        }
        else
        {
            this.graphics.lineStyle(4, 0x00aa00);
        }

        this.graphics.strokeRectShape(this.pointerRect);
    }
}

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

const game = new Phaser.Game(config);

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

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

Создаем графический объект graphics с красной заливкой. Он будет использоваться для отрисовки нашего первого прямоугольника.

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

Затем создаем два геометрических прямоугольника с помощью Phaser.Geom.Rectangle. Первый, rect, будет двигаться по заданной траектории. Второй, pointerRect, будет следовать за курсором мыши.

this.rect = new Phaser.Geom.Rectangle(0, 0, 100, 150);
this.pointerRect = new Phaser.Geom.Rectangle(450, 350, 150, 100);

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

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

Анимация и обновление состояния

Основная логика движения и отрисовки находится в методе update(), который вызывается каждый кадр.

Сначала мы обновляем угол `a`, который используется для расчета позиции первого прямоугольника. Это создает циклическое движение.

this.a += 0.015;
if (this.a > Math.PI * 4)
{
    this.a -= Math.PI * 4;
}

Затем вычисляются координаты `xиyдля центра первого прямоугольника. Формулы сMath.cosиMath.sin` задают сложную траекторию (фигуру Лиссажу), чтобы сделать визуализацию пересечений более наглядной.

const x = 400 - Math.cos(this.a / 2) * 400;
const y = 300 - Math.sin(this.a * 2) * 300;

После вычислений мы центрируем прямоугольник rect на этих координатах.

Phaser.Geom.Rectangle.CenterOn(this.rect, x, y);

Визуализация и проверка пересечений

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

Сначала очищаем графический объект и заливаем первый прямоугольник (rect) красным цветом.

this.graphics.clear();
this.graphics.fillRectShape(this.rect);

Затем происходит ключевой момент — проверка пересечения двух прямоугольников с помощью Phaser.Geom.Intersects.RectangleToRectangle. Этот метод возвращает true или false.

if (Phaser.Geom.Intersects.RectangleToRectangle(this.rect, this.pointerRect))

В зависимости от результата проверки мы меняем стиль линии для обводки второго прямоугольника (pointerRect). При пересечении линия становится красной (0xaa0000), в противном случае — зеленой (0x00aa00).

{
    this.graphics.lineStyle(4, 0xaa0000);
}
else
{
    this.graphics.lineStyle(4, 0x00aa00);
}

Наконец, рисуем контур второго прямоугольника с выбранным стилем линии.

this.graphics.strokeRectShape(this.pointerRect);

Настройка и запуск игры

Конфигурация игры (config) определяет основные параметры, такие как размер холста, тип рендерера и главную сцену. В данном примере используется автовыбор рендерера (Phaser.AUTO).

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

Затем создается экземпляр игры Phaser.Game, который запускает весь процесс.

const game = new Phaser.Game(config);

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

В этом примере мы реализовали базовую, но мощную систему проверки столкновений прямоугольников. Метод Phaser.Geom.Intersects.RectangleToRectangle — это ваш главный инструмент для детектирования пересечений в 2D-пространстве. Для экспериментов попробуйте изменить размеры или траекторию движения прямоугольников, добавить больше объектов и проверять пересечения между ними или реализовать простую логику реакции на столкновение (например, воспроизведение звука или увеличение счетчика).