О чем этот пример
Управление вводом — основа интерактивности в играх. Понимание того, какие кнопки мыши нажаты, позволяет создавать сложные механики: от контекстных меню по правому клику до зажатия и перетаскивания объектов. В этой статье мы разберем, как использовать 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, вы можете в реальном времени отслеживать позицию курсора и состояние кнопок мыши, что открывает двери для создания разнообразного геймплея. Для экспериментов попробуйте
- Изменить логику, чтобы действие (например, перемещение спрайта) происходило только при зажатой правой кнопке, а не левой
- Добавить проверку для средней кнопки мыши через
pointer.middleButtonDown() - Реализовать простую систему «перетаскивания», сохраняя начальную позицию объекта при
pointer.isDownи обновляя её вupdate, пока кнопка не будет отпущена
