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

Интерактивность — ключевой элемент вовлечения игрока. Часто необходимо реагировать не просто на клик, а на сам факт перемещения курсора мыши над элементами игры. В Phaser для этого существует событие `gameobjectmove`. Эта статья покажет, как его эффективно использовать, в том числе для обработки нескольких объектов одновременно, что идеально подходит для создания эффектов наведения, подсветки интерактивных зон или динамической смены состояний спрайтов.

Версия 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('eye', 'assets/pics/lance-overdose-loader-eye.png');
    }

    create ()
    {
        const sprite1 = this.add.sprite(400, 300, 'eye').setInteractive();
        const sprite2 = this.add.sprite(450, 350, 'eye').setInteractive();
        const sprite3 = this.add.sprite(500, 400, 'eye').setInteractive();

        //  If you disable topOnly it will fire events for all objects the pointer is over, regardless of place on the display list
        this.input.topOnly = false;

        //  Events

        this.input.on('gameobjectmove', (pointer, gameObject) =>
        {

            gameObject.setTint(Math.random() * 16000000);

        });
    }
}

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

const game = new Phaser.Game(config);

Создание интерактивных спрайтов

Первым шагом является подготовка игровых объектов, которые должны реагировать на указатель мыши. В Phaser для этого используется метод setInteractive(). Он сообщает системе ввода, что объект теперь может получать события.

const sprite1 = this.add.sprite(400, 300, 'eye').setInteractive();
const sprite2 = this.add.sprite(450, 350, 'eye').setInteractive();
const sprite3 = this.add.sprite(500, 400, 'eye').setInteractive();

Здесь мы создаем три спрайта с одним изображением и сразу делаем их интерактивными. Без вызова setInteractive() событие gameobjectmove на них не сработает.

Ключевая настройка: input.topOnly

По умолчанию Phaser оптимизирует обработку событий. Свойство this.input.topOnly управляет тем, как события мыши распределяются между объектами, если они перекрываются.

this.input.topOnly = false;

Когда topOnly установлено в true (значение по умолчанию), событие получит только самый верхний объект в порядке отрисовки (display list). Установив значение в false, мы разрешаем событию срабатывать для всех объектов, над которыми в данный момент находится указатель, независимо от их глубины. Это необходимо, если вы хотите, чтобы несколько перекрывающихся спрайтов одновременно реагировали на движение мыши.

Обработка события gameobjectmove

Основная логика реакции на движение мыши по объекту реализуется через слушатель события 'gameobjectmove'.

this.input.on('gameobjectmove', (pointer, gameObject) => {
    gameObject.setTint(Math.random() * 16000000);
});

Метод this.input.on добавляет обработчик. Коллбэк-функция получает два аргумента: pointer (объект, содержащий информацию о положении и состоянии указателя) и gameObject (именно тот интерактивный объект, над которым в данный момент движется мышь). В данном примере при каждом движении мыши над объектом его цвет (tint) случайным образом меняется. Math.random() * 16000000 генерирует случайное шестнадцатеричное значение для окрашивания.

Конфигурация и запуск игры

Как и в любом проекте Phaser, необходимо определить конфигурационный объект и создать экземпляр игры.

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

const game = new Phaser.Game(config);

Эта конфигурация создает игровое поле размером 800x600 пикселей, использует рендерер WEBGL и указывает, что стартовой сценой должен быть наш класс Example.

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

Событие gameobjectmove — это мощный инструмент для создания плавной и отзывчивой интерактивности. Поэкспериментируйте: вместо смены цвета можно изменять масштаб спрайта, запускать частицы, проигрывать звук наведения или показывать всплывающую подсказку. Попробуйте комбинировать его с другими событиями, например gameobjectover и gameobjectout, для создания сложного поведения при наведении и уходе курсора.