How do you create subclasses derived from Phaser.Physics.Matter.Sprite and register them to instantiate them like
this.matter.add.myMatterSprite(...)
I know how to register Sprite subclasses but no clue on how to do it matter physics sprites.
How do you create subclasses derived from Phaser.Physics.Matter.Sprite and register them to instantiate them like
this.matter.add.myMatterSprite(...)
I know how to register Sprite subclasses but no clue on how to do it matter physics sprites.
Ok, I think I see the problem: there is no register
function on the Matter.Factory class.
I did found a workaround though:
Lander.js
import Phaser from "phaser";
class Lander extends Phaser.Physics.Matter.Sprite {
update(time, delta) {
super.update(time, delta);
/* gameobject update logic */
}
}
Phaser.GameObjects.GameObjectFactory.register('lander', function (x, y, key, frame, matterOptions) {
var lander = new Lander(this.scene.matter.world, x, y, key, frame, matterOptions);
this.displayList.add(lander);
this.updateList.add(lander);
return lander;
}
);
export default Lander;
So that now I can do on my scene:
import Phaser from "phaser";
import Lander from "/gameobjects/space/Lander";
class SpaceScene extends Phaser.Scene {
//...
create() {
//...
var lander = this.add.lander(
this.scale.width/2,
this.scale.height*.9,
'space', 'lander.png',
{
shape: matterShapes['lander']
}
);
//...
}
}
Being a maniac as I am I don’t find very elegant to invoke a matter physics factory function directly from the scene, but I guess there is nothig I can do about it without modifying the phaser source code, right?
Ok, being stubborn in addition to a maniac and reading how the register function is injected in the GameObjectFactory prototype I found a better(*) solution.
Import this file after phaser, but before your scene classes on your index.js (or whatever js file you use as entry point)
MatterFactoryRegister.js
Phaser.Physics.Matter.Factory.register = function (factoryType, factoryFunction) {
if (!Phaser.Physics.Matter.Factory.prototype.hasOwnProperty(factoryType))
{
Phaser.Physics.Matter.Factory.prototype[factoryType] = factoryFunction;
}
}
Lets you register the Matter.Sprite subclass into the Matter factory this way:
Lander.js
import Phaser from "phaser";
class Lander extends Phaser.Physics.Matter.Sprite {
update(time, delta) {
super.update(time, delta);
/* gameobject update logic */
}
}
Phaser.Physics.Matter.Factory.register('lander',
function (x, y, key, frame, matterOptions) {
var lander = new Lander(this.scene.matter.world, x, y, key, frame, matterOptions);
this.sys.displayList.add(lander);
this.sys.updateList.add(lander);
return lander;
}
);
export default Lander;
And so you can do this in your scene:
SpaceScene.js
import Phaser from "phaser";
import Lander from "/gameobjects/space/Lander";
class SpaceScene extends Phaser.Scene {
//...
create() {
//...
var lander = this.matter.add.lander(
this.scale.width/2,
this.scale.height*.9,
'space', 'lander.png',
{
shape: matterShapes['lander']
}
);
//...
}
}
Which is what I originally was looking for.
EDIT:
(*) Actually it’s not a very good idea to modify native or library prototypes on the fly because in a later version of phaser we could be overwriting library functionality, so it’s better to do something like this (kinda polyfill):
MatterFactoryRegister.js
if (!Phaser.Physics.Matter.Factory.register) {
Phaser.Physics.Matter.Factory.register = function (factoryType, factoryFunction) {
if (!Phaser.Physics.Matter.Factory.prototype.hasOwnProperty(factoryType))
{
Phaser.Physics.Matter.Factory.prototype[factoryType] = factoryFunction;
}
}
}
You can actually just extend the Matter.Sprite class and add it to your scene. Makes for an easier solution (in TypeScript):
export default class SpriteCharacter extends Phaser.Physics.Matter.Sprite {
constructor(scene: Scene, spriteTexture: string, x: number, y: number) {
super(scene.matter.world, x, y, spriteTexture, 0)
scene.add.existing(this)
}
}