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

Стандартный курсор мыши — это функционально, но скучно. В игровых проектах визуальная стилизация интерфейса, включая указатель, играет ключевую роль в создании атмосферы и улучшении пользовательского опыта. Кастомизация курсора в Phaser — это простой и эффективный способ усилить immersion, подчеркнуть тематику игры или визуально выделить интерактивные объекты. В этой статье мы разберем, как заменить системный курсор на собственное изображение для всей сцены или для отдельных игровых объектов. Вы научитесь управлять курсором с помощью API Phaser Input, что позволит вам создавать более уникальные и запоминающиеся игровые интерфейсы.

Версия 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 ()
    {
        this.input.setDefaultCursor('url(assets/input/cursors/blue.cur), pointer');

        const sprite = this.add.sprite(400, 300, 'eye').setInteractive({ cursor: 'url(assets/input/cursors/pen.cur), pointer' });

        sprite.on('pointerover', function (event)
        {

            this.setTint(0xff0000);

        });

        sprite.on('pointerout', function (event)
        {

            this.clearTint();

        });
    }
}

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

const game = new Phaser.Game(config);

Настройка курсора по умолчанию для всей сцены

Phaser позволяет установить кастомный курсор, который будет отображаться по умолчанию во всей сцене. Это делается с помощью метода setDefaultCursor() объекта this.input. В качестве аргумента метод принимает строку в формате CSS-свойства cursor.

this.input.setDefaultCursor('url(assets/input/cursors/blue.cur), pointer');

Здесь url(assets/input/cursors/blue.cur) — это путь к файлу с изображением курсора. Строка , pointer после URL — это запасной вариант (fallback). Если браузер по какой-то причине не сможет загрузить или использовать указанный файл .cur, он отобразит стандартный системный курсор типа pointer (рука с указательным пальцем). Этот fallback — хорошая практика для обеспечения отказоустойчивости.

Интерактивные объекты и их собственные курсоры

Часто требуется, чтобы курсор менялся только при наведении на определенные, интерактивные объекты. В Phaser для этого нужно сделать объект интерактивным с помощью метода setInteractive(). Курсор для этого объекта задается прямо в его конфигурации.

const sprite = this.add.sprite(400, 300, 'eye').setInteractive({ cursor: 'url(assets/input/cursors/pen.cur), pointer' });

В этом коде создается спрайт и сразу же делается интерактивным. В опциях setInteractive() передается объект с полем cursor. Значение поля — такая же CSS-строка, как и для setDefaultCursor. Теперь при наведении мыши на этот спрайт курсор сменится на кастомное изображение пера, а при уходе с него — вернется к курсору по умолчанию для сцены (синему).

Визуальная обратная связь: события pointerover и pointerout

Смена курсора — это уже хорошая обратная связь для игрока. Но её можно усилить, добавив визуальное изменение самого объекта при наведении. Для этого используются события pointerover (курсор наведен на объект) и pointerout (курсор ушел с объекта).

sprite.on('pointerover', function (event) {
    this.setTint(0xff0000);
});

sprite.on('pointerout', function (event) {
    this.clearTint();
});

В обработчике pointerover вызывается метод setTint(0xff0000), который окрашивает спрайт в красный цвет. Ключевое слово this внутри функции-обработчика ссылается на сам спрайт (sprite), потому что мы использовали обычное функциональное выражение. При уходе курсора (pointerout) вызывается clearTint(), который убирает окрашивание. Таким образом, объект подсвечивается красным, пока на него наведен курсор, что делает взаимодействие более очевидным.

Практические советы по работе с курсорами

1. **Поддерживаемые форматы:** Phaser полагается на браузер. Основные форматы — .cur (Windows Cursor) и .png. Формат .cur часто лучше поддерживает "горячую точку" (hotspot) — точку, которая соответствует реальному положению указателя. Для .png может потребоваться дополнительная настройка смещения через CSS.

2. **Размеры изображения:** Обычно размер курсора не должен превышать 32x32 или 64x64 пикселя. Слишком большой курсор будет выглядеть громоздко и может закрывать важные элементы интерфейса.

3. **Fallback — это важно:** Всегда указывайте запасной системный курсор (например, pointer, default, crosshair). Это гарантирует, что взаимодействие останется возможным, даже если с кастомным изображением возникнут проблемы.

// Хорошо: с fallback
setInteractive({ cursor: 'url(assets/cursor.cur), pointer' });

// Плохо: без fallback (риск получить невидимый курсор)
setInteractive({ cursor: 'url(assets/cursor.cur)' });

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

Кастомизация курсора в Phaser — это мощный, но простой инструмент для улучшения игрового опыта. Вы можете задать общий стиль для всей сцены и точечно менять его для отдельных интерактивных элементов, комбинируя с другими эффектами вроде tint. **Идеи для экспериментов:** 1. Создайте анимированный курсор, подгрузив спрайтшит и переключая кадры в обработчике pointermove. 2. Реализуйте "умный" курсор, который меняет вид в зависимости от типа объекта под ним (меч для врагов, ключ для замков). 3. Добавьте звуковые эффекты с помощью this.sound.play() при событиях pointerover и pointerout для полного сенсорного погружения.