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

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

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.scenePlugin({
            key: 'BannerTextPlugin',
            url: 'assets/loader-tests/BannerTextPlugin.js',
            sceneKey: 'banner'
        });

        this.load.text('3x5', 'assets/loader-tests/3x5.flf');
        this.load.spritesheet('balls', 'assets/sprites/balls.png', { frameWidth: 17, frameHeight: 17 });
        this.load.spritesheet('tiles', 'assets/tilemaps/tiles/drawtiles.png', { frameWidth: 32, frameHeight: 32 });
        this.load.image('chunk', 'assets/sprites/chunk.png');
    }

    create ()
    {
        this.banner.config('3x5');

        this.banner.createText('Phaser 3', 0, 32, 'balls', 1);

        this.banner.createText('Brings you a new Banner Text Plugin', 0, 140, 'chunk');

        this.banner.createText('PHASER', 0, 300, 'tiles', 5);
    }
}

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

const game = new Phaser.Game(config);

Что такое сценовый плагин и зачем он нужен

Сценовый плагин (Scene Plugin) в Phaser 3 — это специальный модуль, который добавляет новые методы и свойства непосредственно в экземпляр сцены (this внутри методов сцены). Это отличный способ расширить стандартные возможности движка без необходимости модифицировать его ядро или создавать глобальные хелперы.

В предоставленном примере плагин BannerTextPlugin отвечает за создание текстовых баннеров с использованием пользовательских шрифтов и спрайтов. Подключая его, разработчик получает доступ к новому API через свойство this.banner в своей сцене.

Регистрация плагина в методе `preload`

Ключевой этап — объявление и загрузка плагина. Это делается с помощью метода this.load.scenePlugin() внутри preload. Этот метод асинхронно загружает JS-файл плагина и привязывает его к сцене.

this.load.scenePlugin({
    key: 'BannerTextPlugin',
    url: 'assets/loader-tests/BannerTextPlugin.js',
    sceneKey: 'banner'
});

Разберем параметры конфигурационного объекта: - key: Внутренний ключ, под которым плагин регистрируется в загрузчике. - url: Путь к JavaScript-файлу, содержащему код плагина. - sceneKey: Самое важное. Это имя свойства, которое будет добавлено к сцене (this). В нашем случае — banner. Именно через this.banner мы получим доступ ко всем методам плагина после его загрузки.

Параллельно загружаются необходимые для работы плагина ресурсы: текстовый файл с описанием шрифта (3x5), таблицы спрайтов и изображения.

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

После того как все ресурсы загружены, в методе create сцена может использовать новый функционал. Первым делом плагин нужно сконфигурировать, передав ему загруженный ранее файл шрифта.

this.banner.config('3x5');

Вызов config — это метод, предоставляемый самим плагином BannerTextPlugin. Ему передается ключ ассета '3x5', который соответствует загруженному текстовому файлу шрифта.

Теперь плагин готов к созданию текста. Для этого используется метод createText.

this.banner.createText('Phaser 3', 0, 32, 'balls', 1);

Аргументы метода, судя по вызовам: 1. Строка текста для отображения. 2. Координата X. 3. Координата Y. 4. Ключ графического ассета (спрайтшита или изображения), который будет использован для визуализации символов текста. 5. Необязательный кадр (frame) из спрайтшита. В первом вызове используется кадр `1из'balls', а в последнем — кадр5из'tiles'. Если ассет — одиночное изображение (как'chunk'`), этот параметр, видимо, не требуется.

Сборка конфигурации игры и запуск

Сцена с подключенным плагином регистрируется в основном конфиге игры стандартным образом. Никакой дополнительной конфигурации на уровне игры не требуется — вся магия происходит внутри сцены.

const config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    scene: Example // Наша сцена с плагином
};

const game = new Phaser.Game(config);

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

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

Использование this.load.scenePlugin() — это чистый и эффективный способ модуляризации кода в Phaser 3. Вы можете создавать собственные плагины для любых задач: управления UI, реализации сложных анимаций, работы с API. Для экспериментов попробуйте

  1. Написать простой плагин, добавляющий сцене метод this.debug.log() для вывода styled-сообщений в консоль
  2. Подключить один и тот же плагин к нескольким сценам и посмотреть, как они работают независимо друг от друга