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

В Phaser 3 работа с 3D-эффектами и сложной геометрией объектов открывает новые возможности для визуализации. В этой статье на примере кода мы разберем, как создавать сетки (Mesh) и управлять их вершинами для формирования сетчатых поверхностей. Это полезно для создания динамических фонов, деформации спрайтов или простых 3D-преобразований в 2D-пространстве игры.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    constructor ()
    {
        super();
    }

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('ayu', 'assets/pics/ayu.png');
    }

    create ()
    {
        var cnt = 10;

        for(var i = 0; i < cnt; i++) {
            for(var j = 0; j < cnt; j++) {        
                const mesh = this.add.mesh(50 + i * 100, 50 + j  * 100, 'ayu');
                Phaser.Geom.Mesh.GenerateGridVerts({
                    mesh,
                    widthSegments: 10
                });
                mesh.hideCCW = false;
                mesh.panZ(20);
            }
        }
    }
}

const config = {
    type: Phaser.AUTO,
    width: 1000,
    height: 800,
    backgroundColor: '#0a440a',
    parent: 'phaser-example',
    scene: Example,
    batchSize: 512,
};

let game = new Phaser.Game(config);

Подготовка сцены и загрузка ассетов

Первым делом в методе preload() мы загружаем изображение, которое будет использоваться как текстура для сетки. Важно правильно указать базовый URL для загрузки ресурсов.

preload ()
{
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.image('ayu', 'assets/pics/ayu.png');
}

Создание массива сеток в цикле

В методе create() мы используем двойной цикл для генерации массива сеток. Каждая сетка создается с помощью this.add.mesh(), где задаются координаты позиции и ключ текстуры. Таким образом, мы размещаем сетки в виде сетки (grid) на сцене.

for(var i = 0; i < cnt; i++) {
    for(var j = 0; j < cnt; j++) {        
        const mesh = this.add.mesh(50 + i * 100, 50 + j  * 100, 'ayu');
        // Дальнейшая обработка mesh
    }
}

Генерация вершин для сетки

После создания объекта mesh мы вызываем Phaser.Geom.Mesh.GenerateGridVerts() для генерации вершин сетки. Параметр widthSegments определяет количество сегментов по ширине, что влияет на детализацию геометрии. Это преобразует плоский спрайт в сетчатую структуру, с которой можно работать как с 3D-объектом.

Phaser.Geom.Mesh.GenerateGridVerts({
    mesh,
    widthSegments: 10
});

Настройка отображения и трансформации

Мы устанавливаем свойство hideCCW в false, чтобы отображать все грани сетки, включая те, которые обычно скрыты из-за порядка обхода вершин (против часовой стрелки). Затем применяем mesh.panZ(20) для смещения сетки по оси Z, создавая эффект глубины и перспективы в 2D-пространстве.

mesh.hideCCW = false;
mesh.panZ(20);

Конфигурация игры и производительность

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

const config = {
    type: Phaser.AUTO,
    width: 1000,
    height: 800,
    backgroundColor: '#0a440a',
    parent: 'phaser-example',
    scene: Example,
    batchSize: 512,
};

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

Использование сеток в Phaser 3 позволяет выйти за рамки стандартных спрайтов, добавляя в игры элементы 3D-геометрии и сложные визуальные эффекты. Экспериментируйте с параметрами widthSegments, трансформациями вроде panZ() или rotateX(), а также попробуйте динамически изменять вершины сетки для создания анимированных поверхностей, таких как вода или рельеф.