О чем этот пример
В играх часто требуется проверять пересечения или совпадения объектов. Встроенная геометрия Phaser предлагает удобные методы для таких задач. Рассмотрим, как работает метод `Phaser.Geom.Ellipse.Equals` для сравнения двух эллипсов, и как его можно использовать для создания интерактивных визуальных эффектов или триггеров событий в игре. Этот подход эффективнее ручных проверок координат и размеров.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
create ()
{
const graphics = this.add.graphics({ fillStyle: { color: 0x00aaaa } });
const ellipses = [];
for (let x = 0; x < 8; x++)
{
for (let y = 0; y < 6; y++)
{
const width = Phaser.Math.Between(4, 5) * 20;
const height = Phaser.Math.Between(4, 5) * 20;
ellipses.push(new Phaser.Geom.Ellipse(50 + x * 100, 50 + y * 100, width, height));
}
}
const mouseEllipse = new Phaser.Geom.Ellipse(-50, -50, 100, 80);
this.input.on('pointermove', pointer =>
{
// round position to (100 * n + 50) pixels
const x = Math.floor(pointer.x / 100) * 100 + 50;
const y = Math.floor(pointer.y / 100) * 100 + 50;
mouseEllipse.setPosition(x, y);
redraw();
});
redraw();
function redraw ()
{
graphics.clear();
let strokeRed = false;
for (let i = 0; i < ellipses.length; i++)
{
graphics.fillEllipseShape(ellipses[i]);
strokeRed = strokeRed || Phaser.Geom.Ellipse.Equals(mouseEllipse, ellipses[i]);
}
if (strokeRed)
{
graphics.lineStyle(5, 0xaa0000);
}
else
{
graphics.lineStyle(5, 0x0000aa);
}
graphics.strokeEllipseShape(mouseEllipse);
}
}
}
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Суть метода Equals
Метод Phaser.Geom.Ellipse.Equals сравнивает два объекта эллипса. Он возвращает true, если их позиции (свойства `x,y) и размеры (width,height`) идентичны. Это точное сравнение, а не проверка пересечений или приблизительного наложения.
const isEqual = Phaser.Geom.Ellipse.Equals(ellipseA, ellipseB);
В примере этот метод используется для сравнения эллипса, следующего за курсором, с сеткой статических эллипсов.
Подготовка сцены и сетки объектов
В create создается контейнер для рисования graphics и массив ellipses. Два вложенных цикла формируют сетку 8x6 эллипсов со случайными размерами в заданных пределах. Каждый эллипс создается через конструктор Phaser.Geom.Ellipse.
const ellipses = [];
for (let x = 0; x < 8; x++) {
for (let y = 0; y < 6; y++) {
const width = Phaser.Math.Between(4, 5) * 20;
const height = Phaser.Math.Between(4, 5) * 20;
ellipses.push(new Phaser.Geom.Ellipse(50 + x * 100, 50 + y * 100, width, height));
}
}
Также создается отдельный эллипс mouseEllipse, который будет следовать за указателем.
Обработка движения курсора
На событие pointermove подписывается обработчик. Позиция курсора округляется до узлов сетки с шагом 100 пикселей, чтобы mouseEllipse "прилипал" к тем же координатам, что и статические эллипсы. Это обеспечивает возможность точного совпадения.
this.input.on('pointermove', pointer => {
const x = Math.floor(pointer.x / 100) * 100 + 50;
const y = Math.floor(pointer.y / 100) * 100 + 50;
mouseEllipse.setPosition(x, y);
redraw();
});
После обновления позиции вызывается функция redraw для перерисовки кадра.
Визуализация и логика сравнения
Функция redraw сначала очищает холст graphics.clear(). Затем она рисует все эллипсы из массива и, в цикле, проверяет совпадает ли текущий mouseEllipse с любым из них, используя Phaser.Geom.Ellipse.Equals. Результат накапливается в переменной strokeRed.
let strokeRed = false;
for (let i = 0; i < ellipses.length; i++) {
graphics.fillEllipseShape(ellipses[i]);
strokeRed = strokeRed || Phaser.Geom.Ellipse.Equals(mouseEllipse, ellipses[i]);
}
В зависимости от результата (strokeRed), контур двигающегося эллипса рисуется красным (при совпадении) или синим цветом.
Что попробовать дальше
Метод Equals — это простой и надежный способ проверить полное геометрическое совпадение объектов. В игровых сценариях его можно адаптировать для активации триггеров, когда игрок помещает объект в строго определенную зону, или для проверки состояния расстановки предметов. Попробуйте изменить логику: сделайте проверку не на точное совпадение, а на пересечение областей, используя Phaser.Geom.Ellipse.Overlaps, или привяжите к событию клика для фиксации совпадения.
