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

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

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        this.add.text(10, 10, 'Click to reverse the array matrix columns', { 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.ReverseColumns(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);

Что делает `Phaser.Utils.Array.Matrix.ReverseColumns`?

Метод ReverseColumns принимает на вход двумерный массив (матрицу) и возвращает её новую копию, в которой порядок столбцов изменен на обратный. Проще говоря, первый столбец становится последним, второй — предпоследним и так далее. Это похоже на вертикальное "зеркальное" отражение матрицы.

Важно отметить, что исходный массив не модифицируется. Метод создает и возвращает новый массив с измененным порядком столбцов. Это поведение (иммутабельность) помогает избежать случайных сайд-эффектов в коде.

Разбор примера кода

В предложенном примере создается простая сцена Phaser. В ней инициализируется матрица 6x6, заполненная числами, и выводится на экран с помощью Phaser.Utils.Array.Matrix.MatrixToString. По клику мыши столбцы матрицы переворачиваются.

Давайте посмотрим на ключевые моменты:

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));

Утилита MatrixToString форматирует матрицу в читаемую строку, где строки разделены символом \n, а элементы в строке — пробелом. Это очень удобно для быстрого вывода отладочной информации.

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

Обработчик клика. При каждом клике мыши матрица matrix заменяется на результат работы ReverseColumns, и текстовый объект обновляется.

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

Зачем может понадобиться переворачивать столбцы матрицы в реальном проекте?

* **Генерация симметричных уровней:** Вы можете создать половину уровня, а затем зеркально отразить её, чтобы получить полную, симметричную карту. Это экономит время и ресурсы. * **Эффекты отражения:** Например, для создания эффекта "отражения в воде" или симметричного поведения врагов. * **Манипуляции с данными спрайтшита или тайлмапа:** Если ваша карта уровня или данные анимации хранятся в виде матрицы, этот метод поможет быстро создать её зеркальный вариант.

Представьте, что ваша матрица — это тайловая карта:

let tilemapMatrix = [
    [1, 1, 1, 2],
    [0, 5, 5, 0],
    [0, 5, 5, 0],
    [3, 3, 3, 4]
];
// После ReverseColumns получим:
// [
//    [2, 1, 1, 1],
//    [0, 5, 5, 0],
//    [0, 5, 5, 0],
//    [4, 3, 3, 3]
// ]

Крайние колонки поменялись местами, а центральная часть (где у нас, условно, платформа из тайлов `5`) осталась симметричной относительно вертикальной оси.

Другие полезные методы Phaser.Utils.Array.Matrix

Модуль Phaser.Utils.Array.Matrix содержит не только ReverseColumns. Вот некоторые из его полезных функций:

* ReverseRows(matrix) — переворачивает строки матрицы (горизонтальное отражение). * RotateLeft(matrix) / RotateRight(matrix) — поворачивает матрицу на 90 градусов против или по часовой стрелке. * TransposeMatrix(matrix) — транспонирует матрицу (меняет строки и столбцы местами). * Rotate180(matrix) — поворачивает матрицу на 180 градусов.

Использование этих методов может кардинально упростить код, который вручную потребовал бы вложенных циклов for. Все они работают по тому же принципу: не изменяют исходный массив, а возвращают новый.

// Пример поворота матрицы влево
let rotatedMatrix = Phaser.Utils.Array.Matrix.RotateLeft(originalMatrix);

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

Использование встроенных утилит Phaser, таких как методы модуля Array.Matrix, — это признак чистого и эффективного кода. Они помогают избежать "велосипедов" и сосредоточиться на игровой логике. **Идеи для экспериментов:** 1. Создайте простой редактор уровней на канвасе, где по клику добавляется тайл. Добавьте кнопки "Отразить по вертикали/горизонтали" и "Повернуть", используя изученные методы. 2. Скомбинируйте ReverseColumns и ReverseRows. Что получится? Проверьте, совпадает ли результат с Rotate180. 3. Попробуйте применить эти методы не к числовым данным, а к массивам, содержащим ссылки на игровые объекты или конфигурационные данные. Убедитесь, что копируются именно ссылки, а не создаются новые объекты.