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

Управление вводом — основа интерактивности в играх. Понимание того, какие кнопки мыши нажаты, позволяет создавать сложные механики: от контекстных меню по правому клику до зажатия и перетаскивания объектов. В этой статье мы разберем, как использовать API указателя (Pointer) в Phaser для получения точной информации о состоянии кнопок мыши прямо в игровом цикле.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    text;

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('mouse', 'assets/sprites/mouse_jim_sachs.png');
    }

    create ()
    {
        this.add.sprite(0, 600, 'mouse').setOrigin(0, 1);

        this.text = this.add.text(10, 10, '', { fill: '#00ff00' });
    }

    update ()
    {
        const pointer = this.input.activePointer;

        this.text.setText([
            `x: ${pointer.worldX}`,
            `y: ${pointer.worldY}`,
            `isDown: ${pointer.isDown}`,
            `rightButtonDown: ${pointer.rightButtonDown()}`
        ]);
    }
}

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

const game = new Phaser.Game(config);

Настройка сцены и загрузка ресурсов

В методе preload мы загружаем спрайт, который будет служить визуальным фоном. Обратите внимание на использование setBaseURL — это удобный способ указать базовый путь для всех последующих загрузок.

preload ()
{
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.image('mouse', 'assets/sprites/mouse_jim_sachs.png');
}

В методе create мы размещаем спрайт в левом нижнем углу экрана, установив точку привязки (origin) на (0, 1). Также создается текстовый объект для вывода информации. Важный момент: мы сохраняем ссылку на этот текст в свойство класса this.text, чтобы иметь к нему доступ в методе update.

create ()
{
    this.add.sprite(0, 600, 'mouse').setOrigin(0, 1);
    this.text = this.add.text(10, 10, '', { fill: '#00ff00' });
}

Работа с активным указателем (Active Pointer)

Вся магия происходит в методе update, который вызывается на каждом кадре. Ключевой объект — this.input.activePointer. В контексте десктопного браузера это обычно представляет собой основную мышь.

update ()
{
    const pointer = this.input.activePointer;
    // ... дальнейшая работа с pointer
}

Из этого объекта мы можем получать актуальные координаты курсора в игровом мире (worldX, worldY). Это особенно важно, если у вас есть камера, которая перемещает видимую область.

`x: ${pointer.worldX}`,
`y: ${pointer.worldY}`,

Проверка состояния кнопок мыши

Phaser предоставляет простые и понятные свойства и методы для проверки, нажата ли кнопка мыши.

Свойство pointer.isDown возвращает true, если нажата *любая* основная кнопка мыши (обычно левая). Это универсальная проверка для общего клика или удержания.

`isDown: ${pointer.isDown}`

Для более детального контроля, например, для обработки правого клика, используется метод pointer.rightButtonDown(). Он возвращает true только когда нажата именно правая кнопка мыши.

`rightButtonDown: ${pointer.rightButtonDown()}`

Важно помнить разницу: isDown — это свойство, а rightButtonDown() — это метод, который нужно вызвать.

Конфигурация игры и важная настройка

Конфигурационный объект игры содержит ключевую настройку disableContextMenu: true. Она отключает стандартное контекстное меню браузера (которое появляется при правом клике) на canvas-элементе игры. Это необходимо, чтобы правый клик обрабатывался игрой, а не вызывал системное меню.

const config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    disableContextMenu: true, // Запрещаем контекстное меню браузера
    scene: Example
};

Без этой настройки метод pointer.rightButtonDown() будет срабатывать лишь на мгновение, перед тем как браузер откроет своё меню, что сделает механику нерабочей.

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

Используя activePointer, вы можете в реальном времени отслеживать позицию курсора и состояние кнопок мыши, что открывает двери для создания разнообразного геймплея. Для экспериментов попробуйте

  1. Изменить логику, чтобы действие (например, перемещение спрайта) происходило только при зажатой правой кнопке, а не левой
  2. Добавить проверку для средней кнопки мыши через pointer.middleButtonDown()
  3. Реализовать простую систему «перетаскивания», сохраняя начальную позицию объекта при pointer.isDown и обновляя её в update, пока кнопка не будет отпущена