О чем этот пример
При разработке игр часто возникает необходимость динамически изменять игровые области, зоны коллизий или интерфейсы в ответ на действия игрока. Метод `Phaser.Geom.Rectangle.MergeXY` предоставляет элегантное решение для этой задачи, позволяя расширить прямоугольник так, чтобы он включил в себя новую точку. Это полезно для создания резиновых выделений, адаптивных зон интереса или плавного изменения границ объектов при взаимодействии.
Версия 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(350, 250, 100, 100);
this.input.on('pointerdown', pointer =>
{
Phaser.Geom.Rectangle.MergeXY(rect, pointer.x, pointer.y);
redraw();
});
redraw();
function redraw ()
{
graphics.clear();
graphics.strokeRectShape(rect);
}
}
}
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что делает MergeXY?
Статический метод Phaser.Geom.Rectangle.MergeXY изменяет переданный ему прямоугольник таким образом, что новая точка с координатами (x, y) оказывается внутри него. Если точка уже находится внутри прямоугольника, его размеры и положение остаются прежними. Если точка лежит снаружи, прямоугольник расширяется ровно настолько, чтобы вместить эту точку, сохраняя свою прямоугольную форму.
Этот метод модифицирует исходный объект прямоугольника, а не создаёт новый. Его логика похожа на операцию объединения (merge) прямоугольника с бесконечно малым прямоугольником-точкой.
Разбор примера кода
В данном примере создаётся сцена с одним прямоугольником и обработчиком событий мыши. При каждом клике прямоугольник расширяется, чтобы включить точку клика.
Сначала создаётся графический объект graphics для отрисовки и определяется исходный прямоугольник rect.
const graphics = this.add.graphics({ lineStyle: { width: 2, color: 0x0000aa } });
const rect = new Phaser.Geom.Rectangle(350, 250, 100, 100);
Затем вешается обработчик события pointerdown на пользовательский ввод. Внутри него и происходит магия.
this.input.on('pointerdown', pointer => {
Phaser.Geom.Rectangle.MergeXY(rect, pointer.x, pointer.y);
redraw();
});
Вызов MergeXY принимает два аргумента: объект прямоугольника для изменения и координаты точки (x, y), взятые из положения указателя (pointer). После изменения прямоугольника вызывается функция redraw() для обновления его отображения на экране.
Как работает перерисовка
Функция redraw отвечает за визуализацию текущего состояния прямоугольника. Важно очищать графический слой перед каждой отрисовкой, иначе старые кадры будут накладываться на новые.
function redraw ()
{
graphics.clear();
graphics.strokeRectShape(rect);
}
Сначала graphics.clear() удаляет всё, что было нарисовано этим графическим объектом. Затем graphics.strokeRectShape(rect) рисует контур текущего прямоугольника. Исходный вызов redraw() в create отображает прямоугольник в его начальном состоянии.
Практическое применение в играх
1. **Резиновое выделение (Box Selection):** Классический интерфейс для выделения нескольких юнитов в стратегиях. При зажатой кнопке мыши прямоугольник расширяется от начальной точки до текущего положения курсора, используя MergeXY для каждой новой позиции.
2. **Динамические камеры или зоны видимости:** Можно плавно корректировать область, которую должна охватывать камера, чтобы в кадр попадали все важные объекты (например, все игроки в кооперативной игре).
3. **Расчёт общего bounding box:** Для группы разбросанных спрайтов можно начать с прямоугольника вокруг первого спрайта и последовательно применять MergeXY к координатам остальных, чтобы получить общую ограничивающую рамку.
Что попробовать дальше
Метод Phaser.Geom.Rectangle.MergeXY — это мощный и простой инструмент для управления прямоугольными областями в реальном времени. Он идеально подходит для сценариев, где границы объекта должны реагировать на внешние точки. Для экспериментов попробуйте изменить пример: обрабатывать не клики, а движение мыши с зажатой кнопкой, чтобы создать интерактивное выделение. Или примените этот метод к Phaser.Geom.Rectangle, который служит телом для физического спрайта, чтобы динамически менять его хитбокс.
