О чем этот пример
В игровой разработке проверка пересечений объектов — одна из ключевых механик, будь то столкновение пули с врагом или сбор предметов. В этой статье мы разберем пример из официальной документации 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-пространстве. Для экспериментов попробуйте изменить размеры или траекторию движения прямоугольников, добавить больше объектов и проверять пересечения между ними или реализовать простую логику реакции на столкновение (например, воспроизведение звука или увеличение счетчика).
