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

При размещении спрайтов в Phaser вы могли сталкиваться с тем, что они ведут себя не так, как ожидалось: вращаются не вокруг своего центра, а выравниваются странным образом. Всё это контролируется свойством `origin` (точка отсчёта). В этой статье мы разберём, что такое точка отсчёта, как её изменить и как это влияет на позиционирование, вращение и масштабирование объектов. Это фундаментальное понятие, понимание которого сделает вашу работу с игровыми объектами точной и предсказуемой.

Версия 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 originY to 1 so sprites are top-aligned

        this.add.image(100, 100, 'atlas', 'mana_card').setOrigin(0.5, 0);
        this.add.image(200, 100, 'card').setOrigin(0.5, 0);

        //   By default the origin is set to 0.5 (the center of the image)

        this.add.image(350, 300, 'atlas', 'mana_card');
        this.add.image(450, 300, 'card');

        //  Change originX to 0 so sprites are left-aligned

        this.add.image(600, 500, 'atlas', 'mana_card').setOrigin(0.5, 1);
        this.add.image(700, 500, 'card').setOrigin(0.5, 1);

        //  Draw the alignment lines to our Graphics object

        graphics.lineStyle(2, 0x00ff00, 1);

        graphics.beginPath();

        graphics.moveTo(0, 100);
        graphics.lineTo(800, 100);

        graphics.moveTo(0, 300);
        graphics.lineTo(800, 300);

        graphics.moveTo(0, 500);
        graphics.lineTo(800, 500);

        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 у каждого игрового объекта (например, спрайта, изображения, текста) есть точка отсчёта (origin). Это точка внутри самого объекта, относительно которой происходит его позиционирование на сцене, а также вращение и масштабирование.

По умолчанию origin установлен в (0.5, 0.5). Это означает, что точка отсчёта находится ровно в центре объекта. Значения originX и originY задаются в диапазоне от 0 до 1, где 0 — это левый/верхний край, а 1 — правый/нижний край объекта.

Когда вы задаёте координаты (x, y) для объекта с помощью add.image(), именно точка отсчёта объекта помещается в эти координаты на сцене.

Изменение origin через setOrigin

Изменить точку отсчёта после создания объекта можно с помощью метода .setOrigin(). В примере это показано наглядно.

this.add.image(100, 100, 'atlas', 'mana_card').setOrigin(0.5, 0);

Здесь setOrigin(0.5, 0) устанавливает точку отсчёта по X в центре спрайта (0.5), а по Y — в его верхнем крае (`0). Это означает, что координатаy=100` будет указывать на верхний край карты, а не на её центр. Таким образом можно легко выравнивать объекты по верхнему краю относительно некоторой линии.

this.add.image(600, 500, 'atlas', 'mana_card').setOrigin(0.5, 1);

А здесь setOrigin(0.5, 1) устанавливает точку отсчёта по Y в нижнем крае спрайта. Теперь координата y=500 указывает на низ карты, что удобно для выравнивания по нижнему краю.

Визуализация линиями

Чтобы наглядно увидеть, как объекты выравниваются относительно заданных координат, в примере используется объект Graphics для рисования зелёных линий.

Сначала создаётся объект для рисования:

const graphics = this.add.graphics();

Затем настраивается стиль линии и рисуются три горизонтальные линии на уровнях y=100, y=300 и y=500.

graphics.lineStyle(2, 0x00ff00, 1);
graphics.beginPath();
graphics.moveTo(0, 100);
graphics.lineTo(800, 100);
// ... остальные линии
graphics.strokePath();
graphics.closePath();

Благодаря этому мы видим: спрайты с originY=0 (верхнее выравнивание) касаются линии y=100 своим верхом. Спрайты с originY=0.5 (центр по умолчанию) пересекаются линией y=300 ровно посередине. А спрайты с originY=1 (нижнее выравнивание) касаются линии y=500 своим низом. Это отличный способ для отладки позиционирования.

Практическое применение

Понимание и управление origin критически важно в нескольких сценариях:

1. **Точное выравнивание интерфейса (UI):** Когда нужно разместить иконки, кнопки или панели по краям или центру экрана. 2. **Вращение объектов:** Если вы хотите, чтобы спрайт вращался вокруг своего угла, а не центра, установите origin в (0, 0) или (1, 1). 3. **Создание анимаций и эффектов:** Например, «вырастание» объекта из точки можно смоделировать, установив originY=1 и увеличивая scaleY от 0 до 1.

Запомните: изменение origin не меняет визуальный вид спрайта, оно меняет точку, к которой «привязаны» его координаты и трансформации.

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

Точка отсчёта origin — это мощный и гибкий инструмент для контроля над положением и поведением игровых объектов. Поэкспериментируйте: попробуйте анимировать вращение спрайта с разными значениями origin, создайте строку интерфейса, где все элементы выровнены по базовой линии, или реализуйте систему «привязки» объектов друг к другу, манипулируя их точками отсчёта.