О чем этот пример
В играх постоянно требуется проверять пересечение объектов — для определения столкновений, зон видимости или триггеров событий. Phaser предоставляет для этого удобные инструменты геометрического модуля. В этой статье мы разберем, как находить область пересечения двух прямоугольников и визуализировать её в реальном времени, что станет основой для ваших систем коллизий и взаимодействий.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
create ()
{
const graphics = this.add.graphics({ lineStyle: { width: 2, color: 0x0000aa } });
const rect = new Phaser.Geom.Rectangle(250, 200, 300, 200);
const pointerRect = new Phaser.Geom.Rectangle(450, 350, 150, 100);
this.input.on('pointermove', pointer =>
{
Phaser.Geom.Rectangle.CenterOn(pointerRect, pointer.x, pointer.y);
redraw();
});
redraw();
function redraw ()
{
graphics.clear();
graphics.strokeRectShape(rect);
graphics.strokeRectShape(pointerRect);
const intersection = Phaser.Geom.Intersects.GetRectangleIntersection(rect, pointerRect);
graphics.lineStyle(2, 0xaa0000);
graphics.strokeRectShape(intersection);
}
}
}
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Создание геометрии и графики
В методе create() сцены мы сначала создаем объект Graphics для отрисовки фигур. Затем определяем два прямоугольника: статичный (rect) и подвижный (pointerRect), который будет следовать за курсором.
const graphics = this.add.graphics({ lineStyle: { width: 2, color: 0x0000aa } });
const rect = new Phaser.Geom.Rectangle(250, 200, 300, 200);
const pointerRect = new Phaser.Geom.Rectangle(450, 350, 150, 100);
Объекту graphics задается стиль синей линии толщиной 2 пикселя. Прямоугольники создаются с указанием координат X, Y, ширины и высоты. Пока это лишь математические объекты в памяти, не отрисованные на экране.
Обработка движения указателя
Мы подписываемся на событие pointermove от ввода (this.input). При каждом движении мыши или касании центр подвижного прямоугольника (pointerRect) перемещается в координаты курсора с помощью статического метода Phaser.Geom.Rectangle.CenterOn(). После обновления позиции вызывается функция redraw() для перерисовки кадра.
this.input.on('pointermove', pointer => {
Phaser.Geom.Rectangle.CenterOn(pointerRect, pointer.x, pointer.y);
redraw();
});
Это обеспечивает интерактивность: прямоугольник следует за указателем. Метод CenterOn() изменяет координаты переданного прямоугольника так, чтобы его центр совпадал с заданными точками pointer.x и pointer.y.
Функция перерисовки и визуализация
Функция redraw() сначала очищает холст graphics от предыдущего кадра. Затем она отрисовывает контуры обоих исходных прямоугольников с помощью strokeRectShape(), используя заданный ранее синий стиль линии.
function redraw() {
graphics.clear();
graphics.strokeRectShape(rect);
graphics.strokeRectShape(pointerRect);
После этого происходит самое важное — вычисление пересечения. Мы вызываем Phaser.Geom.Intersects.GetRectangleIntersection(), передавая два прямоугольника. Этот метод возвращает новый объект Phaser.Geom.Rectangle, который представляет собой область пересечения исходных фигур. Если прямоугольники не пересекаются, метод вернет null.
const intersection = Phaser.Geom.Intersects.GetRectangleIntersection(rect, pointerRect);
Визуализация области пересечения
После вычисления пересечения мы меняем стиль линии на красный (0xaa0000) и отрисовываем полученный прямоугольник intersection. Если пересечения нет (intersection равен null), метод strokeRectShape() ничего не нарисует, и красный прямоугольник не появится.
graphics.lineStyle(2, 0xaa0000);
graphics.strokeRectShape(intersection);
Таким образом, красным цветом выделяется только та область, где два синих прямоугольника накладываются друг на друга. Это наглядно демонстрирует работу геометрического вычисления в реальном времени.
Сборка конфигурации игры
Код завершается стандартной для Phaser конфигурацией игры. Мы указываем размеры холста, тип рендерера (Phaser.AUTO), ID родительского элемента и класс нашей сцены Example.
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Эта конфигурация запускает игровой цикл. Важно, что метод create() сцены вызывается автоматически после инициализации игры, и все наши логика создания объектов и подписки на события выполняется один раз в начале.
Что попробовать дальше
Метод GetRectangleIntersection() — мощный и простой способ получить точную область пересечения двух прямоугольников. Вы можете использовать его не только для визуализации, но и в игровой логике: например, для расчета урона в определенной зоне, активации ловушек или определения видимости для NPC. Попробуйте поэкспериментировать: измените код так, чтобы при пересечении менялся цвет фона сцены, или добавьте третий прямоугольник для поиска пересечения трех областей сразу.
