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

Правильная обработка кликов и наведения — основа отзывчивого геймплея. Но что делать, когда объект реагирует не там, где нужно? Встроенный инструмент отладки зоны клика (`enableDebug`) в Phaser 3 позволяет визуализировать хитбоксы и быстро находить ошибки в логике взаимодействия. Эта статья покажет, как использовать `setInteractive` с кастомными геометрическими областями и функцией-коллбэком, а также как отлаживать их с помощью `this.input.enableDebug()`. Вы научитесь создавать сложные зоны взаимодействия для спрайтов любого масштаба и формы.

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

Живой запуск

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

Исходный код


var game = new Phaser.Game({
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    parent: 'phaser-example',
    scene: {
        preload: preload,
        create: create
    }
});

function preload ()
{
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.image('test', 'assets/sprites/p2.jpg');
    this.load.image('image', 'assets/sprites/32x32.png');
}

function create ()
{
    var image = new Phaser.GameObjects.Sprite(this, 400, 300, 'image');

    image.setInteractive({
      draggable: true,
      hitArea: new Phaser.Geom.Rectangle(10,10,20,20),
      hitAreaCallback: Phaser.Geom.Rectangle.Contains
    });

    this.add.existing(image);
    image.setScale(8, 8);
    // image.setOrigin(0,0);

    this.input.enableDebug(image, 0xffff00);

    // var actualHitArea = this.add.rectangle(image.x + 30, image.y + 30, 60, 60);
    // actualHitArea.setOrigin(0,0);
    // actualHitArea.setStrokeStyle(2, 0x00ff00);

    image.on('drag', function (pointer, dragX, dragY) {
        image.x = dragX;
        image.y = dragY;
    });
    image.on('pointerover', function () {
        this.setTint(0x00ff00);
    });
    image.on('pointerout', function () {
        this.clearTint();
    });

    const image2 = this.add.image(150, 150, 'test') // test image has 200x200 size for example
    image2.setScale(1.7);
    image2.setInteractive(new Phaser.Geom.Circle(160, 120, 80), Phaser.Geom.Circle.Contains);
    this.input.enableDebug(image2);
    image2.on('pointerover', function () {
        this.setTint(0x00ff00);
    });
    image2.on('pointerout', function () {
        this.clearTint();
    });

}

Визуализация хитбокса: включение отладки

Phaser предоставляет метод enableDebug() у объекта this.input. Он рисует поверх игрового объекта контур его текущей зоны взаимодействия (hit area). Цвет контура можно задать вторым параметром в формате HEX.

Без этого инструмента определить, где именно можно кликнуть на увеличенном или трансформированном спрайте, практически невозможно.

// Включаем отладку для объекта image с желтым контуром
this.input.enableDebug(image, 0xffff00);

Кастомизация зоны взаимодействия: прямоугольник

По умолчанию зона взаимодействия совпадает с границами спрайта. Но вы можете задать свою область с помощью объекта hitArea и функции hitAreaCallback. Это полезно для создания крупных кнопок из маленьких спрайтов или нестандартных областей.

В примере для спрайта размером 32x32 пикселя создается прямоугольная зона (Phaser.Geom.Rectangle) с отступом 10 пикселей от левого верхнего угла и размером 20x20. Коллбэк Phaser.Geom.Rectangle.Contains проверяет, попал ли указатель в этот прямоугольник.

image.setInteractive({
  draggable: true,
  hitArea: new Phaser.Geom.Rectangle(10, 10, 20, 20),
  hitAreaCallback: Phaser.Geom.Rectangle.Contains
});

После масштабирования спрайта в 8 раз (setScale(8,8)) эта небольшая область также увеличивается, и отладка позволяет это четко увидеть.

Взаимодействие с объектом: события drag, pointerover, pointerout

После настройки setInteractive можно назначать обработчики событий. В примере объект стал перетаскиваемым (draggable: true) и реагирует на наведение.

Обратите внимание: координаты в событии drag уже подготовлены для перемещения объекта.

image.on('drag', function (pointer, dragX, dragY) {
    image.x = dragX;
    image.y = dragY;
});

image.on('pointerover', function () {
    this.setTint(0x00ff00); // Подсветка зеленым при наведении
});

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

Другой пример: круглая зона взаимодействия

Кроме прямоугольников, можно использовать любую геометрию Phaser. Второй спрайт в примере использует круглую зону (Phaser.Geom.Circle).

Метод setInteractive также можно вызывать с теми же параметрами, но без объекта-конфигурации. Первый аргумент — геометрия, второй — функция проверки.

// Создаем круглую зону с центром (160,120) и радиусом 80
image2.setInteractive(new Phaser.Geom.Circle(160, 120, 80), Phaser.Geom.Circle.Contains);

// Включаем отладку с цветом по умолчанию
this.input.enableDebug(image2);

Здесь координаты круга задаются относительно собственной системы координат спрайта (с учетом его точки начала origin).

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

Инструмент enableDebug — это ваш лучший помощник при работе с интерактивными объектами в Phaser. Он мгновенно показывает расхождения между визуальным представлением и областью клика. Для экспериментов попробуйте: 1. Использовать Phaser.Geom.Ellipse или Phaser.Geom.Polygon для сложных форм хитбоксов. 2. Написать свою функцию hitAreaCallback для составных или асимметричных областей. 3. Динамически менять hitArea в зависимости от состояния анимации персонажа.