Преобразование координат между сценой и экраном

В Phaser координаты объектов могут быть представлены в разных системах: координаты сцены (world coordinates) и координаты экрана (screen coordinates). Понимание различий и способов их преобразования критично для реализации точного позиционирования, взаимодействия с пользователем и визуальных эффектов.


Координаты сцены (World Coordinates)

Координаты сцены описывают положение объектов относительно глобальной системы сцены. Эта система фиксирована и не зависит от камеры, масштаба или сдвигов.

  • x и y объектов сцены отражают их положение в пределах сцены.
  • Любое перемещение камеры не меняет координаты сцены, но влияет на то, как они отображаются на экране.

Пример:

let sprite = this.add.sprite(100, 200, 'player');
console.log(sprite.x, sprite.y); // 100, 200

Даже если камера сдвигается, sprite.x и sprite.y остаются прежними.


Координаты экрана (Screen Coordinates)

Координаты экрана описывают положение объектов относительно видимой области на экране. Они зависят от камеры, масштабирования и сдвига сцены.

  • Для конвертации координат сцены в координаты экрана используется камера.
  • Эти координаты необходимы для обработки событий ввода, например, кликов мышью или касаний.

Пример получения экранных координат объекта:

let camera = this.cameras.main;
let screenX = camera.worldView.x + sprite.x;
let screenY = camera.worldView.y + sprite.y;

Однако в Phaser есть более удобные методы.


Методы преобразования в Phaser

Phaser предоставляет встроенные функции для работы с преобразованием координат:

camera.worldView и camera.worldViewToCamera

  • camera.worldView — прямоугольник (Phaser.Geom.Rectangle), который описывает видимую область сцены.
  • camera.worldView.x и camera.worldView.y позволяют вычислять смещение для перевода координат сцены в экранные координаты.

Camera.worldToScreen

Phaser 3 не содержит прямого метода worldToScreen в API, но можно использовать Camera.getWorldPoint(x, y) и Camera.getWorldPoint(pointer.x, pointer.y) для обратного преобразования:

  • camera.getWorldPoint(screenX, screenY) — конвертирует координаты экрана в координаты сцены.
  • Применяется для обработки кликов мышью или касаний.

Пример:

this.input.on('pointerdown', function (pointer) {
    let worldPoint = this.cameras.main.getWorldPoint(pointer.x, pointer.y);
    console.log(worldPoint.x, worldPoint.y);
}, this);

Таким образом, координаты нажатия переводятся в глобальную систему сцены.


Учет масштабирования и zoom

Камера Phaser поддерживает zoom, что также влияет на преобразование координат.

  • Координаты сцены остаются неизменными.
  • Экранные координаты изменяются пропорционально camera.zoom.

Пример преобразования с учетом zoom:

let camera = this.cameras.main;
let screenX = (sprite.x - camera.scrollX) * camera.zoom;
let screenY = (sprite.y - camera.scrollY) * camera.zoom;
  • camera.scrollX и camera.scrollY — положение верхнего левого угла камеры в координатах сцены.
  • camera.zoom — коэффициент масштабирования.

Использование матриц преобразования

Для сложных случаев, например, при вращении камеры, можно использовать матрицы преобразования (Matrix4 или TransformMatrix в Phaser).

  • Создается матрица для преобразования мировых координат в экранные с учетом масштаба, поворота и смещения камеры.
  • camera.getWorldTransformMatrix() возвращает матрицу, которая может быть применена к любой точке.

Пример:

let matrix = camera.getWorldTransformMatrix();
let point = new Phaser.Math.Vector2(sprite.x, sprite.y);
matrix.transformPoint(point.x, point.y, point);
console.log(point.x, point.y); // экранные координаты

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

  1. Обработка ввода мыши и касаний: Преобразование экранных координат указателя в координаты сцены позволяет точно определить объект под курсором.

  2. Слежение за объектами: Для UI-элементов, которые должны следовать за объектами сцены, требуется конвертация координат сцены в экранные.

  3. Эффекты камеры и параллакс: Элементы, не относящиеся к сцене (HUD, меню), остаются в экранной системе координат, тогда как спрайты сцены смещаются камерой.


Ключевые моменты

  • Координаты сцены неизменны относительно сцены, координаты экрана зависят от камеры и зума.
  • camera.getWorldPoint(x, y) — экран → сцена.
  • (sprite.x - camera.scrollX) * camera.zoom — сцена → экран.
  • Для сложных трансформаций использовать camera.getWorldTransformMatrix().
  • Всегда учитывать scrollX/scrollY и zoom при конвертации координат.

Эффективное управление координатами между сценой и экраном обеспечивает точное взаимодействие объектов, стабильное позиционирование элементов интерфейса и правильное отображение визуальных эффектов.