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

Работа с двумерными массивами (матрицами) — частая задача при разработке игр: от уровней на тайлах и карт проходимости до сложных игровых состояний. Phaser предоставляет мощные утилиты для их обработки, упрощая разработку. В этой статье разберем метод `Phaser.Utils.Array.Matrix.TransposeMatrix`, который выполняет операцию транспонирования. Это не просто академическое упражнение — транспонирование матриц может быть ключом к реализации поворота игрового поля, преобразования данных уровня или оптимизации расчетов.

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        this.add.text(10, 10, 'Click to rotate the array matrix right', { font: '16px Courier', fill: '#ffffff' });

        const text = this.add.text(200, 200, '', { font: '32px Courier', fill: '#00ff00' });

        let matrix = [
            [ 1, 1, 1, 1, 1, 1 ],
            [ 2, 0, 0, 0, 0, 4 ],
            [ 2, 0, 1, 2, 0, 4 ],
            [ 2, 0, 3, 4, 0, 4 ],
            [ 2, 0, 0, 0, 0, 4 ],
            [ 3, 3, 3, 3, 3, 3 ]
        ];

        text.setText(Phaser.Utils.Array.Matrix.MatrixToString(matrix));

        this.input.on('pointerup', () =>
        {

            matrix = Phaser.Utils.Array.Matrix.TransposeMatrix(matrix);

            text.setText(Phaser.Utils.Array.Matrix.MatrixToString(matrix));

        });
    }
}

const config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    scene: Example
};

const game = new Phaser.Game(config);

Что такое транспонирование матрицы?

Транспонирование — это операция, при которой строки матрицы становятся её столбцами, а столбцы — строками. Если представить матрицу как таблицу, то мы как бы «переворачиваем» её относительно главной диагонали.

Для игрового разработчика это может означать: * Поворот данных уровня на 90 градусов (с последующим отражением). * Конвертацию данных, удобных для хранения, в данные, удобные для обработки системой коллизий или рендеринга. * Подготовку данных для математических операций.

Визуально это выглядит так:

// Было:
[ [1, 2],
  [3, 4] ]

// Стало после TransposeMatrix:
[ [1, 3],
  [2, 4] ]

Разбираем пример: отображение и интерактивность

В предложенном примере создается простая сцена. Сначала на экран выводится текст-инструкция для пользователя.

Затем определяется исходная матрица 6x6, заполненная числами. Она хранит состояние «уровня» или «паттерна». Для её красивого отображения на экране используется утилита Phaser.Utils.Array.Matrix.MatrixToString. Она преобразует вложенный массив в аккуратную текстовую строку с переносами, которую можно вывести в text объект.

let matrix = [
    [ 1, 1, 1, 1, 1, 1 ],
    [ 2, 0, 0, 0, 0, 4 ],
    [ 2, 0, 1, 2, 0, 4 ],
    [ 2, 0, 3, 4, 0, 4 ],
    [ 2, 0, 0, 0, 0, 4 ],
    [ 3, 3, 3, 3, 3, 3 ]
];
text.setText(Phaser.Utils.Array.Matrix.MatrixToString(matrix));

Далее на событие клика (pointerup) вешается обработчик. По каждому клику матрица будет меняться.

Сердце примера: вызов TransposeMatrix

Вся магия происходит внутри обработчика клика. Всего одна строка кода кардинально меняет структуру данных.

Метод Phaser.Utils.Array.Matrix.TransposeMatrix принимает один аргумент — исходную матрицу (двумерный массив), и возвращает её транспонированную копию. Исходный массив не модифицируется.

this.input.on('pointerup', () => {
    matrix = Phaser.Utils.Array.Matrix.TransposeMatrix(matrix);
    text.setText(Phaser.Utils.Array.Matrix.MatrixToString(matrix));
});

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

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

Где это может пригодиться в реальном проекте?

1. **Генерация уровней:** У вас есть набор комнат, описанных матрицами. Транспонирование позволяет получить вариации одной комнаты без создания новых ассетов. 2. **Игровая логика:** Если ваша игра, например, «тетрисоподобная» или головоломка с блоками, транспонирование может быть частью алгоритма поворота фигуры. В сочетании с обращением строк или столбцов можно получить поворот на 90 градусов. 3. **Обработка данных тайловой карты:** Иногда данные карты из редактора удобнее обрабатывать в другом «развороте». TransposeMatrix поможет быстро их преобразовать.

Важный нюанс: метод ожидает **правильную** матрицу, где все вложенные массивы имеют одинаковую длину. В противном случае результат может быть неожиданным.

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

Phaser.Utils.Array.Matrix.TransposeMatrix — это небольшой, но мощный инструмент для работы с двумерными данными. Он избавляет от необходимости писать вложенные циклы для таких операций, делая код чище и понятнее. **Идеи для экспериментов:** 1. Создайте простой редактор уровней на канвасе, где клик транспонирует карту. 2. Скомбинируйте TransposeMatrix с ReverseMatrixRows (также доступен в Phaser.Utils.Array.Matrix), чтобы реализовать полный поворот спрайта или игрового поля на 90 градусов. 3. Используйте транспонирование для симуляции смены дня и ночи, где каждый столбец матрицы — это состояние объектов в определенный час.