О чем этот пример

Определение, находится ли точка внутри эллипса — частая задача в разработке игр. Она пригодится для создания нестандартных зон взаимодействия, хитбоксов для овальных объектов или триггеров сложной формы. Встроенный метод `contains` объекта `Phaser.Geom.Ellipse` решает эту задачу эффективно и без лишних вычислений. В этой статье мы разберем готовый пример, который визуализирует проверку в реальном времени, и покажем, как интегрировать эту логику в вашу игру для создания отзывчивых и интерактивных областей.

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        const graphics = this.add.graphics({ lineStyle: { width: 2, color: 0x00aaaa } });

        const ellipse = new Phaser.Geom.Ellipse(400, 300, 400, 250);

        graphics.strokeEllipseShape(ellipse);

        this.input.on('pointermove', pointer =>
        {

            graphics.clear();

            if (ellipse.contains(pointer.x, pointer.y))
            {
                graphics.lineStyle(2, 0xaa0000);
            }
            else
            {
                graphics.lineStyle(2, 0x00aaaa);
            }

            graphics.strokeEllipseShape(ellipse);

        });
    }
}

const config = {
    width: 800,
    height: 600,
    type: Phaser.AUTO,
    parent: 'phaser-example',
    scene: Example
};

const game = new Phaser.Game(config);

Создание и отрисовка эллипса

В начале метода create сцены мы инициализируем графический объект Graphics для рисования. Затем создаем геометрический объект Ellipse, определяя его центр, ширину и высоту.

const graphics = this.add.graphics({ lineStyle: { width: 2, color: 0x00aaaa } });
const ellipse = new Phaser.Geom.Ellipse(400, 300, 400, 250);
graphics.strokeEllipseShape(ellipse);

Объект ellipse хранит только математическое представление фигуры. Для его отображения на экране используется метод strokeEllipseShape графического контекста graphics. Исходный цвет контура — бирюзовый (0x00aaaa).

Обработка движения курсора

Ключевая логика привязана к событию pointermove. Каждый раз при движении мыши или касании событие срабатывает, и функция-обработчик получает объект pointer с координатами.

this.input.on('pointermove', pointer => {
    graphics.clear();
    // ... логика проверки и перерисовки
});

Первым делом мы очищаем холст graphics с помощью метода clear(). Это важно, потому что иначе старые кадры наложатся на новые. После очистки нужно нарисовать эллипс заново с актуальным цветом.

Магия метода contains

Вот сердце примера — проверка, находится ли точка с координатами курсора внутри эллипса. Для этого у объекта ellipse вызывается метод contains.

if (ellipse.contains(pointer.x, pointer.y))
{
    graphics.lineStyle(2, 0xaa0000);
}
else
{
    graphics.lineStyle(2, 0x00aaaa);
}

Метод contains принимает координаты X и Y точки и возвращает true или false. Если точка внутри эллипса, мы устанавливаем новый стиль линии для graphics — красный цвет (0xaa0000). Если снаружи — возвращаем исходный бирюзовый. После установки стиля эллипс рисуется заново.

Этот метод использует математическую формулу эллипса, что делает проверку очень быстрой.

Интеграция в игровую логику

Как применить это на практике? Представьте овальное озеро, при наведении на которое курсор меняется. Или врага с овальным щитом, который нужно атаковать только в определенной зоне.

// Пример: проверка при клике
this.input.on('pointerdown', (pointer) => {
    if (ovalHitArea.contains(pointer.x, pointer.y)) {
        this.damageBoss(); // Наносим урон боссу
    }
});

Вместо постоянной перерисовки, как в демо, вы можете вызывать contains только в нужные моменты: при клике (pointerdown), в цикле обновления (update) для проверки столкновения с игроком или при отпускании объекта.

Что попробовать дальше

Метод Phaser.Geom.Ellipse.contains — это простой и мощный инструмент для работы с нестандартными областями в играх. Он избавляет от необходимости писать собственную математику для проверки точек в эллипсе. Поэкспериментируйте: создайте несколько эллипсов разного размера и проверяйте попадание в каждый из них, реализуйте перетаскивание объекта только внутри овальной зоны или скомбинируйте эллипс с другими геометрическими фигурами из модуля Phaser.Geom для создания сложных составных хитбоксов.