О чем этот пример
При разработке игр часто требуется проверять взаимное расположение геометрических фигур. Например, находится ли игрок (прямоугольник) в безопасной зоне (круг) или вышел ли он за её пределы? Phaser предоставляет удобные методы для таких проверок. В этой статье разберем, как использовать `Phaser.Geom.Circle.ContainsRect()` для определения полного нахождения прямоугольника внутри круга. Этот подход эффективнее ручных расчетов и подходит для проверки зон, триггеров и ограничивающих областей.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
a = 0;
graphics;
rect;
circle;
create ()
{
this.graphics = this.add.graphics({ lineStyle: { width: 2, color: 0x00ff00 }, fillStyle: { color: 0xff0000 }});
this.circle = new Phaser.Geom.Circle(400, 300, 250);
this.rect = new Phaser.Geom.Rectangle(0, 0, 100, 100);
}
update ()
{
this.a += 0.01;
if (this.a > Math.PI * 2)
{
this.a -= Math.PI * 2;
}
this.rect.x = 350 - Math.sin(this.a * 2) * 350;
this.rect.y = 250 - Math.cos(this.a) * 250;
this.graphics.clear();
this.graphics.strokeCircleShape(this.circle);
if (Phaser.Geom.Circle.ContainsRect(this.circle, this.rect))
{
this.graphics.fillStyle(0xff0000);
}
else
{
this.graphics.fillStyle(0x0000ff);
}
this.graphics.fillRectShape(this.rect);
}
}
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Подготовка сцены и создание фигур
В начале работы в методе create() инициализируются объекты для отрисовки и сами геометрические фигуры.
create ()
{
this.graphics = this.add.graphics({ lineStyle: { width: 2, color: 0x00ff00 }, fillStyle: { color: 0xff0000 }});
this.circle = new Phaser.Geom.Circle(400, 300, 250);
this.rect = new Phaser.Geom.Rectangle(0, 0, 100, 100);
}
Объект this.graphics — это инструмент для рисования. Мы задаем ему стиль линии (зеленая, толщиной 2 пикселя) и стиль заливки (красный).
Круг создается с центром в точке (400, 300) и радиусом 250 пикселей. Прямоугольник — с началом в (0, 0), шириной и высотой по 100 пикселей. Его положение будет динамически меняться в update().
Анимация движения прямоугольника
В методе update() реализуется циклическая анимация движения прямоугольника по сложной траектории.
update ()
{
this.a += 0.01;
if (this.a > Math.PI * 2)
{
this.a -= Math.PI * 2;
}
this.rect.x = 350 - Math.sin(this.a * 2) * 350;
this.rect.y = 250 - Math.cos(this.a) * 250;
}
Переменная this.a — это угол, увеличивающийся каждый кадр. Условие сбрасывает его значение после полного оборота (2π), чтобы избежать переполнения.
Координаты прямоугольника вычисляются с помощью тригонометрических функций sin и cos. Умножение угла на разные коэффициенты (this.a * 2 для X и просто this.a для Y) создает интересную траекторию движения — прямоугольник движется по сложной петле, а не по простому кругу.
Отрисовка и ключевая проверка
Перед каждой отрисовкой нужно очистить холст Graphics и проверить текущее положение фигур.
this.graphics.clear();
this.graphics.strokeCircleShape(this.circle);
if (Phaser.Geom.Circle.ContainsRect(this.circle, this.rect))
{
this.graphics.fillStyle(0xff0000);
}
else
{
this.graphics.fillStyle(0x0000ff);
}
this.graphics.fillRectShape(this.rect);
Метод clear() удаляет все, что было нарисовано на this.graphics в предыдущем кадре. Затем контур круга отрисовывается с помощью strokeCircleShape().
Далее происходит главное: вызов Phaser.Geom.Circle.ContainsRect(this.circle, this.rect). Этот статический метод возвращает true, только если прямоугольник **целиком** находится внутри круга, включая его границы. Если хотя бы один угол выходит за пределы круга — вернется false.
В зависимости от результата меняется цвет заливки fillStyle(): красный (0xff0000) для прямоугольника внутри круга и синий (0x0000ff) для вышедшего за его пределы. После установки цвета прямоугольник рисуется методом fillRectShape().
Настройка игры и конфигурация
Запуск игры осуществляется через создание экземпляра Phaser.Game с конфигурационным объектом.
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Объект config определяет основные параметры игры: ширину и высоту холста (800x600), способ рендеринга (Phaser.AUTO выбирает между WebGL и Canvas автоматически), ID HTML-элемента, в который будет встроена игра, и нашу сцену Example.
Создание new Phaser.Game(config) инициализирует игровой цикл, который начинает вызывать методы create() (один раз) и update() (каждый кадр).
Что попробовать дальше
Метод Phaser.Geom.Circle.ContainsRect() — это надежный и производительный способ проверки полного вхождения прямоугольной области в круглую. Он избавляет от необходимости писать собственные геометрические расчеты. Для экспериментов попробуйте изменить размеры или форму фигур, добавить несколько прямоугольников или кругов, либо использовать другую проверку — Phaser.Geom.Circle.Contains() — для определения нахождения точки внутри круга. Это может быть полезно для реализации зон обнаружения для врагов или безопасных зон для восстановления здоровья игрока.
