О чем этот пример
Определение пересечений геометрических фигур — фундаментальная задача при разработке игр. От проверки попадания снаряда до триггеров скрытых зон — всё строится на эффективных геометрических проверках. В этой статье мы разберем пример из официальной документации Phaser, который наглядно демонстрирует использование метода `Phaser.Geom.Ellipse.ContainsRect`. Вы научитесь проверять, полностью ли прямоугольная область находится внутри эллипса, и визуализировать результат в реальном времени, что пригодится для создания сложных условий столкновений и игровых механик.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
create ()
{
const graphics = this.add.graphics({ fillStyle: { color: 0x0000aa } });
const ellipse = new Phaser.Geom.Ellipse(400, 300, 400, 250);
const rect = new Phaser.Geom.Rectangle(400, 300, 150, 100);
this.input.on('pointermove', pointer =>
{
Phaser.Geom.Rectangle.CenterOn(rect, pointer.x, pointer.y);
redraw();
});
redraw();
function redraw ()
{
graphics.clear();
graphics.fillRectShape(rect);
if (Phaser.Geom.Ellipse.ContainsRect(ellipse, rect))
{
graphics.lineStyle(2, 0xaa0000);
}
else
{
graphics.lineStyle(2, 0x00aaaa);
}
graphics.strokeEllipseShape(ellipse, 64);
}
}
}
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Разбор сцены и начальной настройки
Вся логика примера содержится в методе create класса сцены Example. Первым делом создается графический объект graphics для рисования фигур.
const graphics = this.add.graphics({ fillStyle: { color: 0x0000aa } });
Затем определяются две геометрические фигуры: эллипс и прямоугольник. Эллипс фиксирован и расположен в центре сцены, а прямоугольник изначально также создан в центре, но его позиция будет меняться.
const ellipse = new Phaser.Geom.Ellipse(400, 300, 400, 250);
const rect = new Phaser.Geom.Rectangle(400, 300, 150, 100);
Параметры конструктора Ellipse — это координаты центра (x, y) и два радиуса (width, height). Для Rectangle задаются координаты левого верхнего угла, ширина и высота.
Обработка движения указателя и логика перерисовки
Ключевая интерактивность достигается за счет слушателя события pointermove. При каждом движении мыши или касании прямоугольник rect центрируется на текущих координатах указателя с помощью статического метода Phaser.Geom.Rectangle.CenterOn.
this.input.on('pointermove', pointer => {
Phaser.Geom.Rectangle.CenterOn(rect, pointer.x, pointer.y);
redraw();
});
После обновления позиции вызывается функция redraw(), которая отвечает за визуализацию. Изначальный вызов redraw() после настройки событий отрисовывает сцену в исходном состоянии.
Визуализация и проверка условия ContainsRect
Функция redraw — сердце этого примера. Сначала она очищает предыдущий кадр.
graphics.clear();
graphics.fillRectShape(rect);
Затем происходит самая важная проверка с помощью метода Phaser.Geom.Ellipse.ContainsRect. Этот метод принимает два аргумента: эллипс и прямоугольник. Он возвращает true, только если ВСЕ углы прямоугольника находятся внутри границ эллипса. Это строгая проверка на полное содержание, а не просто пересечение.
if (Phaser.Geom.Ellipse.ContainsRect(ellipse, rect)) {
graphics.lineStyle(2, 0xaa0000);
} else {
graphics.lineStyle(2, 0x00aaaa);
}
В зависимости от результата, цвет контура эллипса меняется: красный (0xaa0000) означает, что прямоугольник внутри, бирюзовый (0x00aaaa) — что снаружи или пересекает границу. В конце функция рисует контур эллипса.
graphics.strokeEllipseShape(ellipse, 64);
Параметр 64 определяет количество сегментов, из которых состоит сглаженный контур эллипса. Чем больше сегментов, тем более гладкой будет кривая, но выше нагрузка на отрисовку. Для статичной сцены это не критично.
Конфигурация игры и запуск
Код завершается стандартной для Phaser 3 конфигурацией игры. В объекте config задаются размеры канваса, указывается тип рендерера (Phaser.AUTO позволяет движку выбрать WebGL или Canvas) и определяется родительский контейнер в HTML, а также основная сцена.
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
После создания экземпляра Game движок автоматически инициализирует рендерер, системы ввода и запустит жизненный цикл сцены Example.
Что попробовать дальше
Метод Phaser.Geom.Ellipse.ContainsRect предоставляет простой и эффективный способ для точной геометрической проверки. Это мощный инструмент для игровой логики, выходящий за рамки простых прямоугольных хитбоксов. Для экспериментов попробуйте: изменить размеры фигур прямо во время выполнения; использовать проверку ContainsRect для активации игровых событий (например, открытия двери, когда игрок находится в определенной зоне); или комбинировать её с другими методами из классов Phaser.Geom, например, для проверки попадания точки (Ellipse.Contains) или пересечения прямоугольников.
