О чем этот пример
Встроенные возможности Phaser обширны, но рано или поздно каждый разработчик сталкивается с необходимостью добавить свою, уникальную логику. Плагины — идеальный способ инкапсулировать и переиспользовать такой код. В этой статье мы разберем практический пример создания плагина-генератора случайных имен для персонажей игр. Вы научитесь регистрировать плагин, обращаться к его методам из сцены и структурировать код для максимальной гибкости.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class RandomNamePlugin extends Phaser.Plugins.BasePlugin {
constructor (pluginManager)
{
super(pluginManager);
this.syllables1 = [ 'fro', 'tir', 'nag', 'bli', 'mon', 'zip' ];
this.syllables2 = [ 'fay', 'shi', 'zag', 'blarg', 'rash', 'izen' ];
this.current = this.syllables1;
}
changeSet ()
{
this.current = this.syllables2;
}
getNames (qty = 10)
{
let names = [];
for (let i = 0; i < qty; i++)
{
let name = '';
for (let i = 0; i < Phaser.Math.Between(2, 4); i++)
{
name = name.concat(Phaser.Utils.Array.GetRandom(this.current));
}
names.push(Phaser.Utils.String.UppercaseFirst(name));
}
return names;
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: {
preload: preload,
create: create
}
};
let game = new Phaser.Game(config);
function preload ()
{
// this.load.setBaseURL('https://cdn.phaserfiles.com/v385');
this.load.plugin('RandomNamePlugin', RandomNamePlugin, true);
}
function create ()
{
let plugin = this.plugins.get('RandomNamePlugin');
let names = plugin.getNames(10);
this.add.text(10, 10, names, { font: '16px Courier', fill: '#00ff00' });
}
Анатомия плагина: класс-наследник
В Phaser все пользовательские плагины должны наследоваться от базового класса Phaser.Plugins.BasePlugin. Это гарантирует, что плагин будет правильно интегрирован в жизненный цикл игры и получит доступ к менеджеру плагинов.
Конструктор класса — отличное место для инициализации внутреннего состояния. В нашем примере здесь определяются два набора слогов для генерации имен и выбирается активный набор.
class RandomNamePlugin extends Phaser.Plugins.BasePlugin {
constructor (pluginManager) {
super(pluginManager);
this.syllables1 = [ 'fro', 'tir', 'nag', 'bli', 'mon', 'zip' ];
this.syllables2 = [ 'fay', 'shi', 'zag', 'blarg', 'rash', 'izen' ];
this.current = this.syllables1;
}
}
Публичные методы плагина
Любая полезная логика плагина выносится в его публичные методы. В нашем случае это метод changeSet() для переключения между наборами слогов и основной метод getNames(qty).
Метод getNames использует встроенные утилиты Phaser для своей работы:
1. Phaser.Math.Between(2, 4) определяет, из скольких слогов будет состоять каждое имя.
2. Phaser.Utils.Array.GetRandom(this.current) случайным образом выбирает слог из активного набора.
3. Phaser.Utils.String.UppercaseFirst(name) делает первую букву имени заглавной.
changeSet () {
this.current = this.syllables2;
}
getNames (qty = 10) {
let names = [];
for (let i = 0; i < qty; i++) {
let name = '';
for (let i = 0; i < Phaser.Math.Between(2, 4); i++) {
name = name.concat(Phaser.Utils.Array.GetRandom(this.current));
}
names.push(Phaser.Utils.String.UppercaseFirst(name));
}
return names;
}
Загрузка и регистрация плагина
Чтобы плагин стал доступен в игре, его необходимо зарегистрировать через Loader Plugin в методе preload() сцены. Ключевой метод здесь — this.load.plugin().
Его параметры:
1. Ключ плагина ('RandomNamePlugin'), по которому мы будем получать его экземпляр.
2. Ссылка на класс плагина (RandomNamePlugin).
3. Флаг запуска (true), который указывает, что плагин должен быть запущен (вызван его метод start()) сразу после загрузки.
function preload () {
this.load.plugin('RandomNamePlugin', RandomNamePlugin, true);
}
Использование плагина в сцене
После загрузки экземпляр плагина доступен через this.plugins.get(), куда передается тот самый ключ, который использовался при регистрации. Получив экземпляр, можно вызывать любые его публичные методы.
В примере мы генерируем 10 имен и отображаем их на экране, передавая массив строк прямо в метод this.add.text(). Phaser автоматически соединит элементы массива через запятую.
function create () {
let plugin = this.plugins.get('RandomNamePlugin');
let names = plugin.getNames(10);
this.add.text(10, 10, names, { font: '16px Courier', fill: '#00ff00' });
}
Что попробовать дальше
Создание плагинов в Phaser — это мощный паттерн для структурирования кода. Он позволяет выносить специализированную логику (генерацию контента, управление аудио, работу с API) в отдельные, легко тестируемые и переиспользуемые модули. Для экспериментов попробуйте: расширить плагин, добавив возможность загрузки наборов слогов из JSON-файла; создать плагин-сервис для управления игровыми достижениями; или реализовать плагин, который добавляет в сцену новые фабричные методы для создания сложных игровых объектов.
