How to enable physics on extended sprite class

Hi all,

I’m trying to abstract out sprite creation to a custom class but I’m getting an error when adding it to a collision category. Of critical note here is that I’m using Matter, not Arcade. Here’s my class:

class Enemy extends Phaser.GameObjects.Sprite {
	constructor(config){
		super(config.scene,config.x,config.y,config.atlas,config.frame);
		config.scene.add.existing(this);
		this.foo = 'bar';
	}
}

It’s instantiated with:

Enemy = new Enemy({
    scene:this,
    x:Game.config.game.width,
    y:50,
    atlas:'ship-atlas',
    frame:'enemy.png'
});

Later, I set (try to) assign it to a collisionCategory it says the method isn’t defined. I’m guessing this is because physics haven’t been enabled on the sprite. If I were using Arcade, I could just go

config.scene.physics.add.existing(this)

But alas, such a function doesn’t exist in MatterJS.

I believe I can register my custom class so I could go matter.add.enemy as demonstrated in this example.. But that method involves me needing to reproduce what the factory method does, which seems pretty brittle to me.

Does Phaser 3 + Matter have no way to enable physics on a custom class?

See my post: Character class

Your post uses Arcade physics, not Matter. There is no equivalent this.scene.matter.world.enableBody().

this.scene.matter.world.add(this) didn’t throw an error, but it also didn’t result in setCollisionGroup() being injected, nor the pink box being drawn.

The first argument should be scene.matter.world, not scene.

So

super(config.scene,config.x,config.y,config.atlas,config.frame);

should be

super(config.scene.matter.world,config.x,config.y,config.atlas,config.frame);

?

Looking at the docs - yeah, that would seem to be the case. However, that throws an exception: Cannot read property 'queueDepthSort' of undefined on line 2770:

scene.sys.queueDepthSort();

I’m guessing that method doesn’t get injected… or something?

hi, there is the solution

class Sprite_Matter extends Phaser.Physics.Matter.Sprite {
	constructor(scene,x,y,texture) {
		super(scene.matter.world,x,y,texture);
		this.setTexture(texture)
		this.setFrictionAir(0.0005)
		this.setBounce(.1)
		scene.add.existing(this)
	}
	preUpdate(time, delta) {
		super.preUpdate(time, delta)
	}
}
2 Likes

That did it! The problem was I was extending Phaser.GameObjects.Sprite, not Phaser.Physics.Matter.Sprite.

Is this documented somewhere other than the actual code? It’s really confusing how in some places “physics” refers to Arcade, and others it’s just a generic namespace.

class Sprite_normal extends Phaser.GameObjects.Sprite {
    constructor (scene, x, y)
    {
        super(scene, x, y);
        this.setTexture('brain');
        this.setPosition(x, y);
        scene.add.existing(this)
    }
    preUpdate (time, delta)
    {
    }
}

try this, if you want arcade

class Mario extends Phaser.GameObjects.Sprite {
    constructor(scene,x,y,key) {
        super(scene, x, y, key);
        scene.physics.world.enable(this);
        scene.add.existing(this);
        this.body.maxVelocity.x = 200;
        this.body.maxVelocity.y = 500;
    }
    preUpdate(time, delta) {        
		super.preUpdate(time, delta)       
    }  
}