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

Разработка игр на Phaser часто подразумевает работу в команде или поддержку кода на разных языках. Встроенная система инъекции карт (Scene Injection Map) позволяет переопределять ключевые методы сцены, такие как `add` или `load`, на пользовательские алиасы. Это особенно полезно для локализации API на родной язык команды, адаптации под конкретные соглашения о кодировании или просто для повышения читабельности кода. В статье разберем, как это работает на практическом примере, и покажем, как настроить сцену под свои нужды.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    constructor() {
        super({
            key: 'Example',
            map: {
                add: '加',
                load: '加载'
            }
        });
    }

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

    create ()
    {
        this.加.image(400, 300, 'face');
        console.log(this);
    }
}

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

const game = new Phaser.Game(config);

Что такое Scene Injection Map?

При создании сцены в Phaser через super() в конструкторе можно передать объект конфигурации. Одно из его свойств — map. Это объект, где ключами являются стандартные имена систем сцены (например, 'add', 'load', 'physics'), а значениями — строки, на которые вы хотите заменить эти имена в контексте данной сцены.

Это не создает новые методы, а лишь назначает псевдонимы для уже существующих. Таким образом, вы можете обращаться к системе this.add через новое имя, например, this.加 (что означает 'добавить' на китайском).

Анализ примера: Конструктор сцены

В предоставленном примере в конструкторе класса Example определяется карта переименования. Ключ 'add' сопоставляется со строкой '加', а ключ 'load' — со строкой '加载'.

constructor() {
    super({
        key: 'Example',
        map: {
            add: '加',
            load: '加载'
        }
    });
}

После этого в методах preload и create этой сцены мы обязаны использовать новые имена. Попытка вызвать this.load или this.add приведет к ошибке, так как оригинальные свойства будут перезаписаны.

Использование кастомных алиасов

В методе preload для загрузки изображения используется не стандартный this.load.image, а его новый алиас this.加载.image. Обратите внимание: меняется только корневое свойство (load на 加载), сам метод image и его аргументы остаются без изменений.

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

Аналогично, в методе create для создания спрайта используется this.加.image вместо this.add.image.

create ()
{
    this.加.image(400, 300, 'face');
    console.log(this);
}

Вывод console.log(this) в консоли наглядно покажет, что у объекта сцены теперь присутствуют свойства `加и加载, а оригинальныеaddиload` отсутствуют.

Конфигурация игры и важные ограничения

Конфигурация самой игры (config) и ее запуск остаются стандартными. Система инъекции карт — это внутренняя настройка конкретной сцены.

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    parent: 'phaser-example',
    scene: Example // Указываем наш класс сцены с кастомной картой
};

const game = new Phaser.Game(config);

Важное ограничение: карта применяется только к системам, перечисленным в документации Phaser (например, add, load, physics, input). Вы не можете произвольно переименовать любые методы или свойства сцены. Также это изменение действует только в пределах экземпляра этой конкретной сцены.

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

Scene Injection Map в Phaser — это мощный инструмент для тонкой настройки API сцены под требования проекта. Он позволяет сделать код более идиоматичным для вашей команды, особенно при работе с неанглоязычными разработчиками. Для экспериментов попробуйте создать карту для других систем, например, переименовать this.physics в this.физ или this.input в this.ввод. Также можно изучить, как это работает в наследуемых сценах, или создать утилиту для автоматической генерации таких карт на основе словаря локализации.