О чем этот пример
Встроенные игровые объекты Phaser — мощный инструмент, но иногда вам нужен уникальный объект с предустановленными свойствами, например, спрайт с фиксированным масштабом или особым поведением. Создание собственного типа игрового объекта через плагин позволяет инкапсулировать эту логику и добавлять новые экземпляры одной строкой, используя знакомый синтаксис `this.add`. Это повышает переиспользование кода и делает его чище. В этой статье мы разберём практический пример создания плагина, который регистрирует новый тип объекта 'clown' — увеличенный спрайт клоуна. Вы научитесь расширять `Phaser.GameObjects.Image`, создавать плагин для его регистрации и интегрировать его в конфигурацию игры.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class ClownGameObject extends Phaser.GameObjects.Image {
constructor (scene, x, y)
{
super(scene, x, y, 'clown');
this.setScale(4);
}
}
class ClownPlugin extends Phaser.Plugins.BasePlugin {
constructor (pluginManager)
{
super(pluginManager);
// Register our new Game Object type
pluginManager.registerGameObject('clown', this.createClown);
}
createClown (x, y)
{
return this.displayList.add(new ClownGameObject(this.scene, x, y));
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
pixelArt: true,
plugins: {
global: [
{ key: 'ClownPlugin', plugin: ClownPlugin, start: true }
]
},
scene: {
preload: preload,
create: create
}
};
let game = new Phaser.Game(config);
function preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('clown', 'assets/sprites/clown.png');
}
function create ()
{
this.add.clown(400, 200);
this.add.clown(300, 300);
this.add.clown(500, 300);
}
Наследуемся от стандартного игрового объекта
Первым шагом создаём класс кастомного игрового объекта. Мы наследуемся от Phaser.GameObjects.Image, что даёт нам все базовые свойства и методы спрайта.
В конструкторе вызываем super, передавая сцену, координаты и ключ текстуры. После этого мы можем сразу задать специфичные для нашего объекта свойства. В примере это фиксированный масштаб.
class ClownGameObject extends Phaser.GameObjects.Image {
constructor (scene, x, y) {
super(scene, x, y, 'clown');
this.setScale(4);
}
}
Таким образом, каждый созданный объект ClownGameObject будет спрайтом с текстурами 'clown', автоматически увеличенным в 4 раза. Вся эта настройка скрыта внутри класса.
Создаём и регистрируем плагин
Чтобы Phaser узнал о нашем новом типе объекта и позволил создавать его через this.add, нужен плагин. Класс плагина наследуется от Phaser.Plugins.BasePlugin.
Ключевой момент — регистрация в методе конструктора. Мы обращаемся к pluginManager и вызываем метод registerGameObject. Первый аргумент — строка, которая станет именем метода фабрики (в нашем случае 'clown'), второй — функция, которая будет этот объект создавать и возвращать.
class ClownPlugin extends Phaser.Plugins.BasePlugin {
constructor (pluginManager) {
super(pluginManager);
pluginManager.registerGameObject('clown', this.createClown);
}
createClown (x, y) {
return this.displayList.add(new ClownGameObject(this.scene, x, y));
}
}
Функция createClown создаёт экземпляр нашего ClownGameObject и добавляет его в displayList текущей сцены, что делает объект видимым. Обратите внимание на контекст: this внутри createClown будет ссылаться на экземпляр GameObjectFactory сцены, поэтому у нас есть доступ к this.scene и this.displayList.
Интеграция плагина в конфиг игры
Плагин нужно добавить в глобальные плагины игры, чтобы он был доступен во всех сценах. Это делается в основном конфигурационном объекте.
В поле plugins.global передаём массив объектов. Каждый объект должен содержать ключ key (уникальное строковое имя), plugin (ссылку на класс плагина) и start: true для автоматического запуска.
const config = {
// ... другие настройки (тип, размеры)
plugins: {
global: [
{ key: 'ClownPlugin', plugin: ClownPlugin, start: true }
]
},
scene: {
preload: preload,
create: create
}
};
После такой настройки плагин зарегистрирует метод clown в фабрике игровых объектов (this.add) для каждой сцены.
Использование кастомного объекта в сцене
Теперь в коде сцены мы можем создавать наших клоунов так же просто, как и любые стандартные объекты. Phaser автоматически добавит метод clown в объект this.add.
В функции preload загружаем необходимую текстуру.
function preload () {
this.load.image('clown', 'assets/sprites/clown.png');
}
В функции create вызываем новый метод. Каждый вызов создаёт новый экземпляр ClownGameObject с заданными координатами и предустановленным масштабом.
function create () {
this.add.clown(400, 200);
this.add.clown(300, 300);
this.add.clown(500, 300);
}
Код сцены становится очень чистым и декларативным: мы просто говорим «добавь клоуна в точку (X, Y)».
Что попробовать дальше
Создание кастомных игровых объектов через плагины — отличный способ структурировать код в больших проектах. Вы инкапсулируете логику создания и настройки объектов, делая её переиспользуемой и скрытой от основного кода сцены. Для экспериментов попробуйте: добавить в класс ClownGameObject физическое тело через this.scene.physics.add.existing(this); реализовать в классе анимацию или кастомный метод update; создать плагин для более сложного составного объекта, используя Phaser.GameObjects.Container в качестве базового класса.
