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

При разработке игры с большим количеством ресурсов легко столкнуться с конфликтом имён: два изображения в разных папках могут иметь одинаковый ключ `player`, что приведёт к ошибкам загрузки. Phaser предоставляет элегантное решение — префиксы для загрузчика. Эта статья покажет, как использовать префиксы, особенно в связке с файловыми паками (`pack`), чтобы изолировать ресурсы разных модулей игры и сделать код чище и безопаснее. Мы разберём конкретный пример из бага-трекера Phaser, где префикс применяется к атласу и изображению, загруженным через один конфигурационный объект. Вы научитесь управлять ключами текстуры на глобальном уровне, не меняя исходные имена файлов.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene {
    FilePackObject = {
        test1: {
            prefix: "superCoolPrefix-",
            files: [
                {
                    type: "image",
                    key: "taikodrummaster",
                    url: "assets/pics/taikodrummaster.jpg",
                },
                {
                    type: "multiatlas",
                    key: "megaset",
                    url: "assets/atlas/tp3-multi-atlas.json",
                    path: "assets/atlas",
                },
            ],
        },
    };

    preload() {
        
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
// this.load.setPrefix("superCoolPrefix-");
        // this.load.image("taikodrummaster", 'assets/pics/taikodrummaster.jpg');
        // this.load.multiatlas("megaset", 'assets/atlas/tp3-multi-atlas.json', 'assets/atlas');
        // this.load.atlas("megaset", 'assets/atlas/megaset-0.png', 'assets/atlas/megaset-0.json');
        this.load.pack("pack1", this.FilePackObject);
    }

    create() {
        console.log(this.textures.list);

        this.add.image(400, 300, "superCoolPrefix-taikodrummaster");

        this.add.image(0, 0, "superCoolPrefix-megaset", "contra1").setOrigin(0);

        // this.add.image(0, 0, "megaset", "contra1").setOrigin(0);
    }
}

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    scene: Example,
    parent: "phaser-example",
};

const game = new Phaser.Game(config);

Что такое префикс и зачем он нужен?

Метод this.load.setPrefix(prefix) глобально добавляет указанную строку ко всем последующим ключам загружаемых ресурсов. Если установить префикс 'menu-' и загрузить изображение с ключом 'background', то в кэш текстуры оно попадёт как 'menu-background'. Это позволяет создавать логические пространства имён.

Особенно полезно это при использовании сторонних модулей или ассет-паков, где вы не контролируете исходные ключи. Префикс предотвращает их перезапись вашими собственными ресурсами. В нашем примере префикс задаётся не через прямой вызов метода, а через конфигурацию пака.

Структура файлового пака (File Pack)

Phaser позволяет описывать несколько ресурсов в одном объекте — файловом паке. Это удобно для организации. В примере объект FilePackObject содержит один пак test1.

Важнейшее поле здесь — prefix. Оно указывает префикс, который будет автоматически применён ко всем файлам внутри этого конкретного пака. Обратите внимание, что сам ключ пака ('pack1') не получает префикс — префикс применяется к ключам самих ресурсов (например, 'taikodrummaster').

FilePackObject = {
    test1: {
        prefix: "superCoolPrefix-",
        files: [
            // ... массив файлов
        ]
    }
};

Загрузка ресурсов через пак и применение префикса

В методе preload() вместо нескольких вызовов (load.image, load.multiatlas) используется один — load.pack. Он принимает ключ пака и наш конфигурационный объект. Загрузчик Phaser разбирает объект, применяет префикс 'superCoolPrefix-' к ключам ресурсов и загружает файлы по указанным URL.

preload() {
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.pack("pack1", this.FilePackObject);
}

В результате в кэш текстуры (this.textures.list) изображение и атлас попадут не с ключами 'taikodrummaster' и 'megaset', а с ключами 'superCoolPrefix-taikodrummaster' и 'superCoolPrefix-megaset'. Проверить это можно через console.log, как это сделано в create().

Использование ресурсов с префиксом в сцене

После загрузки все обращения к текстурам должны использовать полный ключ с префиксом. В примере это хорошо видно при создании изображений.

Первый спрайт создаётся из обычного изображения. Обратите внимание, что в this.add.image используется полный ключ с префиксом.

this.add.image(400, 300, "superCoolPrefix-taikodrummaster");

Второй спрайт создаётся из мультиатласа. Первый аргумент — всё тот же полный ключ текстуры атласа, второй аргумент — ключ конкретного фрейма внутри этого атласа. Префикс не влияет на внутренние имена фреймов в JSON-описании атласа.

this.add.image(0, 0, "superCoolPrefix-megaset", "contra1").setOrigin(0);

Попытка использовать ключ без префикса ("megaset") приведёт к ошибке, так как текстура с таким ключом не была загружена.

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

Использование префиксов через файловые паки — это мощный паттерн для структурирования ресурсов в Phaser. Он позволяет безопасно комбинировать ассеты из разных источников, избегая коллизий имён. Для экспериментов попробуйте: создать несколько паков с разными префиксами; динамически менять префикс в зависимости от локализации игры; или написать вспомогательную функцию, которая будет автоматически генерировать префиксы на основе имени модуля игры.