О чем этот пример
При расстановке объектов на игровом поле важно точно контролировать, относительно какой точки они позиционируются и вращаются. По умолчанию 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('card', 'assets/sprites/mana_card.png');
this.load.atlas('atlas', 'assets/atlas/megaset-1.png', 'assets/atlas/megaset-1.json');
}
create ()
{
// Graphics background with lines on
const graphics = this.add.graphics();
// Change originX to 1 so sprites are right-aligned
this.add.image(200, 200, 'atlas', 'mana_card').setOrigin(1, 0.5);
this.add.image(200, 400, 'card').setOrigin(1, 0.5);
// By default the origin is set to 0.5 (the center of the image)
this.add.image(400, 200, 'atlas', 'mana_card');
this.add.image(400, 400, 'card');
// Change originX to 0 so sprites are left-aligned
this.add.image(600, 200, 'atlas', 'mana_card').setOrigin(0, 0.5);
this.add.image(600, 400, 'card').setOrigin(0, 0.5);
// Draw the alignment lines to our Graphics object
graphics.lineStyle(2, 0x00ff00, 1);
graphics.beginPath();
graphics.moveTo(200, 0);
graphics.lineTo(200, 600);
graphics.moveTo(400, 0);
graphics.lineTo(400, 600);
graphics.moveTo(600, 0);
graphics.lineTo(600, 600);
graphics.strokePath();
graphics.closePath();
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
Что такое точка отсчёта (origin) в Phaser?
Каждый игровой объект в Phaser (спрайт, изображение, текст) имеет точку отсчёта — воображаемую точку внутри своего ограничивающего прямоугольника. Именно эта точка используется для двух ключевых операций:
1. Позиционирования объекта при его добавлении на сцену с помощью координат X и Y. 2. Вращения объекта вокруг этой точки.
По умолчанию для изображений и спрайтов точка отсчёта находится в центре (0.5, 0.5). Это означает, что координаты (x, y), переданные в this.add.image(), будут указывать на центр картинки. Значения origin всегда нормализованы: `0— это левый или верхний край,1— правый или нижний край,0.5` — середина.
// Добавляем картинку с центром в точке (400, 300)
this.add.image(400, 300, 'card');
// Это эквивалентно явному указанию центра:
this.add.image(400, 300, 'card').setOrigin(0.5, 0.5);
Настройка originX для выравнивания по вертикальным линиям
В примере мы видим три вертикальные линии (X = 200, 400, 600). К каждой линии добавлено по два спрайта (один из атласа, второй — отдельное изображение) на двух разных высотах (Y = 200 и Y = 400).
* **Выравнивание по правому краю:** Установив originX в `1`, мы говорим Phaser'у, что точка привязки спрайта находится у его правого края. Поэтому, когда мы задаём X = 200, правый край картинки «прилипает» к линии.
// Правый край спрайта будет на X = 200
this.add.image(200, 200, 'atlas', 'mana_card').setOrigin(1, 0.5);
* **Выравнивание по центру (по умолчанию):** При originX = 0.5 линия X = 400 проходит ровно через центр спрайтов.
// Центр спрайта будет на X = 400
this.add.image(400, 400, 'card');
* **Выравнивание по левому краю:** Установка originX в `0` привязывает левый край спрайта к линии X = 600.
// Левый край спрайта будет на X = 600
this.add.image(600, 400, 'card').setOrigin(0, 0.5);
Обратите внимание, что originY для всех спрайтов остаётся 0.5, поэтому они выровнены по центру относительно своей высоты. Это делает их позиционирование по оси Y предсказуемым.
Создание графических направляющих для наглядности
Чтобы визуализировать линии выравнивания, в примере используется объект Graphics. Это мощный инструмент Phaser для программного рисования примитивов (линий, фигур). Код создаёт зелёные линии, которые помогают сразу увидеть, как меняется положение спрайта в зависимости от origin.
const graphics = this.add.graphics();
graphics.lineStyle(2, 0x00ff00, 1); // Толщина 2px, цвет зелёный
graphics.beginPath();
graphics.moveTo(200, 0); // Начало первой линии
graphics.lineTo(200, 600); // Конец первой линии
// ... рисуются остальные линии
graphics.strokePath(); // Выполняет отрисовку всех заданных путей
graphics.closePath();
Этот приём — создание вспомогательной графики — крайне полезен при отладке расположения, коллайдеров или зон взаимодействия в игре.
Практическое применение: от UI до анимаций
Понимание origin — это не просто теория, а основа для многих игровых механик.
* **Интерфейсы (UI):** Для выравнивания текста по левому краю панели (originX: 0) или прикрепления иконки к правому краю окна (originX: 1).
* **Вращение:** Представьте стрелку компаса или ручку двери. Чтобы она вращалась вокруг своего края, а не центра, нужно изменить origin.
* **Партиклы и эффекты:** Частицы часто «выстреливают» из определённой точки (originX: 0.5, originY: 0 для верхнего центра).
* **Тайловые карты (Tilemaps):** При работе с тайлами корректная установка origin упрощает их размещение в сетке.
// Дверь, вращающаяся вокруг левого края
let door = this.add.image(doorX, doorY, 'door').setOrigin(0, 0.5);
// Анимация открытия двери
this.tweens.add({
targets: door,
angle: 90, // Вращение будет происходить вокруг установленного origin (0, 0.5)
duration: 1000
});
Что попробовать дальше
Метод setOrigin() — это простой, но мощный инструмент для точного контроля над положением и поведением игровых объектов. Поэкспериментируйте: попробуйте менять не только originX, но и originY для выравнивания по горизонтали или создания вращения вокруг угла спрайта. Используйте графические направляющие при отладке сложных сцен. Понимание этой концепции сделает вашу работу с расположением и анимацией объектов в Phaser намного более осознанной и эффективной.
