О чем этот пример
При разработке игр на Phaser точность взаимодействия игрока с объектами — ключевой момент. Часто начинающие разработчики сталкиваются с тем, что события мыши срабатывают не там, где визуально находится спрайт. Всё дело в точке привязки объекта — его origin. Эта статья на практическом примере покажет, как свойство `setOrigin` влияет на обработку ввода и почему его понимание критически важно для создания отзывчивого геймплея. Вы научитесь контролировать точку отсчёта для коллизий и визуального позиционирования, избегая распространённых ошибок.
Версия 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.add.sprite(100, 100, 'eye').setInteractive().setOrigin(0);
this.add.sprite(300, 100, 'eye').setInteractive().setOrigin(0.5, 0);
this.add.sprite(600, 100, 'eye').setInteractive().setOrigin(1, 0);
this.add.sprite(200, 400, 'eye').setInteractive().setOrigin(1, 1);
this.add.sprite(400, 400, 'eye').setInteractive().setOrigin(1, 0.2);
this.add.sprite(600, 400, 'eye').setInteractive().setOrigin(0.6, 0.4);
this.input.on('gameobjectover', (pointer, gameObject) =>
{
gameObject.setTint(0xff0000);
});
this.input.on('gameobjectout', (pointer, gameObject) =>
{
gameObject.clearTint();
});
}
}
const config = {
type: Phaser.WEBGL,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
Что такое точка привязки (origin)?
В Phaser у каждого игрового объекта (спрайта, изображения, текста) есть точка привязки — origin. Это точка внутри объекта, относительно которой рассчитываются его позиция на сцене (`x,y`), вращение и масштабирование. По умолчанию origin установлена в центр (0.5, 0.5). Однако для обработки ввода (например, наведения мыши) система проверяет, попал ли курсор в границы объекта, и эти границы также рассчитываются от точки origin.
Если origin смещена, смещается и «горячая зона» для взаимодействия. Это особенно важно для UI-элементов или объектов непрямоугольной формы, где визуальное восприятие должно совпадать с областью клика.
Разбор примера: Разные origin, одно изображение
В исходном коде создаётся шесть спрайтов с одним изображением глаза, но с разными точками привязки. Каждому спрайту назначается интерактивность методом setInteractive(), что позволяет ему реагировать на события мыши.
this.add.sprite(100, 100, 'eye').setInteractive().setOrigin(0);
this.add.sprite(300, 100, 'eye').setInteractive().setOrigin(0.5, 0);
this.add.sprite(600, 100, 'eye').setInteractive().setOrigin(1, 0);
this.add.sprite(200, 400, 'eye').setInteractive().setOrigin(1, 1);
this.add.sprite(400, 400, 'eye').setInteractive().setOrigin(1, 0.2);
this.add.sprite(600, 400, 'eye').setInteractive().setOrigin(0.6, 0.4);
Метод setOrigin принимает два аргумента: смещение по оси X и Y в диапазоне от 0 до 1, где 0 — верхний/левый край, а 1 — нижний/правый край объекта. Например, setOrigin(0) устанавливает точку привязки в левый верхний угол спрайта. Это означает, что координаты (100, 100) на сцене будут указывать именно на этот угол, а не на центр изображения.
Обработка событий ввода: gameobjectover и gameobjectout
Для обработки наведения и увода курсора мыши используются события gameobjectover и gameobjectout объекта this.input. Они срабатывают, когда курсор входит в границы интерактивного объекта или покидает их.
this.input.on('gameobjectover', (pointer, gameObject) => {
gameObject.setTint(0xff0000);
});
this.input.on('gameobjectout', (pointer, gameObject) => {
gameObject.clearTint();
});
Обратите внимание: коллбэк-функции получают ссылку на конкретный gameObject, с которым произошло взаимодействие. В данном примере при наведении объект окрашивается в красный цвет методом setTint, а при уходе курсора окраска снимается clearTint. Важно понимать, что границы для срабатывания этих событий определяются прямоугольником (Hit Area) объекта, который, как и его позиция, зависит от установленного origin.
Практический эффект: Почему это важно?
Запустив пример, вы увидите, что красное окрашивание включается не тогда, когда курсор наводится на центр изображения глаза, а когда он попадает в расчётную область, привязанную к точке origin. Например, у спрайта с origin(1, 1) (правый нижний угол) взаимодействие будет происходить, только если курсор находится в правой нижней части изображения относительно его визуального положения.
Это демонстрирует ключевую мысль: **origin определяет не только место отрисовки, но и «физику» взаимодействия**. Если вы делаете кнопку с иконкой, логично установить origin в (0, 0) — левый верхний угол — чтобы область клика совпадала с видимым прямоугольником кнопки, а не была смещена относительно него.
Работа с кастомизацией Hit Area
Метод setInteractive может принимать более сложные параметры для точного контроля над областью взаимодействия. Это полезно, когда форма объекта сильно отличается от прямоугольника или когда вам нужно полностью отделить логику ввода от точки отрисовки.
// Создание произвольной полигональной области для взаимодействия
let hitArea = new Phaser.Geom.Polygon([0,0, 50,0, 50,50, 0,50]);
this.add.sprite(100, 100, 'eye').setInteractive(hitArea, Phaser.Geom.Polygon.Contains);
В этом случае события gameobjectover и gameobjectout будут срабатывать только при попадании курсора в заданный полигон, независимо от origin и визуальных границ текстуры. Это мощный инструмент для сложных UI или игровых объектов неправильной формы.
Что попробовать дальше
Управление точкой привязки origin — это фундаментальный навык для создания точного и предсказуемого взаимодействия в Phaser. Понимание, как origin влияет на позиционирование и обработку ввода, избавит вас от множества странных багов с коллизиями и кликами. Для экспериментов попробуйте
- Создать интерфейс меню, где все кнопки имеют origin в (0,0) для единообразия
- Сделать вращающийся объект, у которого точка вращения (origin) и точка для клика — разные
- Использовать
setInteractiveс геометрией для объекта сложной формы, например, с звездой
