В библиотеке Phaser для управления положением, размером и вращением объектов активно используются аффинные матрицы 2D-трансформаций. Каждая матрица представляет собой 3×3 структуру, но для оптимизации в Phaser применяются сокращённые 2×3 формы, включающие компоненты scale, rotation, skew и translation. Это позволяет эффективно комбинировать несколько трансформаций в одну, не прибегая к дорогостоящим вычислениям для каждого свойства объекта отдельно.
Стандартная форма матрицы, используемая в Phaser, выглядит как:
| a c tx |
| b d ty |
| 0 0 1 |
где:
a и d — масштаб и вращение по осям X и
Y,b и c — скос (skew) и вращение,tx и ty — смещение (translation).Эта матрица применяется ко всем Game Objects через
внутренний метод setTransformMatrix, обеспечивая
согласованную трансформацию при рендеринге.
1. Смещение (Translation) Смещение задаёт положение
объекта на сцене. Phaser хранит координаты x и
y у каждого объекта, которые в итоге переносятся в матрицу
как tx и ty. Например:
sprite.x = 200;
sprite.y = 150;
В матрице это эквивалентно установке:
tx = 200
ty = 150
2. Масштабирование (Scale) Масштаб влияет на размер
объекта относительно его исходных размеров. Компоненты a и
d определяют масштаб по осям X и Y соответственно:
sprite.setScale(2, 1.5);
Матрица после масштабирования:
| 2 0 tx |
| 0 1.5 ty |
| 0 0 1 |
3. Вращение (Rotation) Вращение задаётся в радианах
и влияет на комбинацию элементов матрицы a, b, c, d.
Формула для преобразования выглядит так:
a = cos(θ) * scaleX
b = sin(θ) * scaleX
c = -sin(θ) * scaleY
d = cos(θ) * scaleY
где θ — угол вращения. В Phaser это удобно применять
через метод:
sprite.rotation = Math.PI / 4; // 45 градусов
4. Скос (Skew) Скос редко используется напрямую, но
его можно контролировать через sprite.setSkew(x, y). Скос
изменяет углы объекта без влияния на его позицию:
c = tan(skewX)
b = tan(skewY)
Phaser позволяет комбинировать несколько трансформаций с сохранением корректной иерархии. Матрицы можно умножать, чтобы объединять смещение, вращение, масштаб и скос в единую матрицу. Умножение матриц выполняется так:
M_result = M_parent * M_child
Это особенно важно для Container, где дочерние объекты наследуют трансформации родителя. Например:
let container = this.add.container(100, 50);
let sprite = this.add.sprite(0, 0, 'character');
container.add(sprite);
В этом случае матрица sprite умножается на матрицу
container, что гарантирует корректное отображение при
перемещении или масштабировании контейнера.
Phaser предоставляет доступ к матрице через свойства
sprite.transformMatrix или методы
getWorldTransformMatrix(). Это позволяет выполнять
кастомные преобразования, минуя стандартные методы
setScale, setRotation и
setPosition. Пример:
let matrix = new Phaser.GameObjects.Components.TransformMatrix();
matrix.applyITRS(100, 50, Math.PI/6, 2, 2);
sprite.setTransformMatrix(matrix);
Здесь applyITRS автоматически рассчитывает компоненты
матрицы на основе Translation, Rotation, Scale.
Использование матриц в Phaser критично для производительности, так как:
Для оптимизации стоит избегать частого обращения к отдельным компонентам матрицы, лучше использовать встроенные методы Phaser, которые автоматически пересчитывают матрицу.
scale, rotation и position
одновременно, что превращает сложные движения в простое обновление
матрицы.Container не нужно обновлять вручную — матрица родителя
автоматически применяется к дочерним элементам.Матрицы трансформации в Phaser — фундаментальный механизм для всех визуальных эффектов, а понимание их структуры и методов управления позволяет создавать сложные динамические сцены с высокой производительностью и точным контролем над каждым объектом.