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

По умолчанию интерактивные объекты в Phaser 3 реагируют на ввод в пределах их ограничивающего прямоугольника (bounding box). Это может быть неудобно для круглых или овальных спрайтов, когда клики в «пустых» углах всё ещё вызывают события. В этой статье мы разберём, как задать точную, геометрически правильную область взаимодействия, используя встроенный класс `Phaser.Geom.Ellipse`. Этот подход делает управление более интуитивным для игрока и является фундаментом для создания сложных нестандартных хитбоксов.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('chick', 'assets/sprites/budbrain_chick.png');
    }

    create ()
    {
        const sprite = this.add.sprite(400, 300, 'chick').setScale(3);

        const shape = new Phaser.Geom.Ellipse(33, 67, 66, 133);

        sprite.setInteractive(shape, Phaser.Geom.Ellipse.Contains);

        //  Input Event listeners

        sprite.on('pointerover', () =>
        {

            sprite.setTint(0x7878ff);

        });

        sprite.on('pointerout', () =>
        {

            sprite.clearTint();

        });
    }
}

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

const game = new Phaser.Game(config);

Проблема стандартного прямоугольного хитбокса

Когда вы создаете спрайт и делаете его интерактивным с помощью setInteractive() без параметров, Phaser использует для проверки ввода прямоугольную область, равную размеру спрайта. Для квадратного или прямоугольного спрайта это идеально. Однако для круглого или овального спрайта (как цыплёнок в примере) это создаёт «мёртвые зоны» — углы, где спрайта визуально нет, но клик всё равно срабатывает.

Это ухудшает пользовательский опыт, особенно в казуальных играх с тапами или сложных интерфейсах. Нам нужен способ проверять, попал ли указатель именно в видимую часть фигуры.

Создание геометрической области: Phaser.Geom.Ellipse

Phaser предоставляет мощный модуль Geometry для работы с фигурами. Класс Phaser.Geom.Ellipse позволяет создать эллипс, задав его центр и радиусы. Эта фигура будет использоваться как точная маска для ввода.

const shape = new Phaser.Geom.Ellipse(33, 67, 66, 133);

В этом коде создаётся эллипс: * 33, 67 — координаты центра эллипса **относительно левого верхнего угла спрайта**. * 66 — ширина (горизонтальный радиус x2). * 133 — высота (верниальный радиус x2).

**Ключевой момент:** координаты и размеры эллипса задаются в системе координат самого спрайта, а не сцены. Это позволяет «привязать» хитбокс к спрайту, где бы он ни находился на экране.

Назначение области и функции проверки

Созданную геометрическую фигуру нужно связать со спрайтом. Для этого используется расширенная форма метода setInteractive(), которая принимает два аргумента: объект области (hit area) и функцию проверки (hit area callback).

sprite.setInteractive(shape, Phaser.Geom.Ellipse.Contains);

* Первый аргумент (shape) — это созданный нами объект Phaser.Geom.Ellipse. * Второй аргумент (Phaser.Geom.Ellipse.Contains) — это готовая функция, которая принимает эллипс и координаты точки, и возвращает true, если точка находится внутри эллипса. Phaser будет вызывать эту функцию для каждой проверки ввода (наведение, клик).

Таким образом, событие pointerover сработает только тогда, когда курсор окажется внутри заданного нами эллипса, а не всего прямоугольника спрайта.

Обработка событий ввода для наглядности

Чтобы визуально подтвердить работу кастомного хитбокса, в примере используются события pointerover и pointerout. Они срабатывают именно при пересечении границ нашей эллиптической области.

sprite.on('pointerover', () => {
    sprite.setTint(0x7878ff); // Подсвечиваем спрайт синим
});

sprite.on('pointerout', () => {
    sprite.clearTint(); // Убираем подсветку
});

Попробуйте водить курсором по спрайту в готовом примере. Вы увидите, что подсветка включается и выключается чётко по границе овала, игнорируя прозрачные углы изображения. Это прямое доказательство работы нашего кастомного хитбокса.

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

Использование Phaser.Geom.Ellipse для определения области взаимодействия — это простой и эффективный способ сделать управление в игре точным и отзывчивым. Этот принцип работает и с другими геометрическими фигурами из модуля Phaser.Geom, такими как Circle, Triangle или Polygon. **Идеи для экспериментов:** 1. Создайте спрайт-звезду и назначьте ей хитбокс в виде многоугольника (Phaser.Geom.Polygon), повторяющего её контур. 2. Скомбинируйте несколько простых фигур (например, прямоугольник и два круга) для создания сложного хитбокса, используя собственную функцию проверки. 3. Динамически меняйте размер или положение геометрической области в зависимости от анимации спрайта (например, для удара мечом).