Trying to detect if 2 specific bodies are colliding with matter.js in phaser 3

Viewed 148

I'm trying to add enemies to my platformer game using the matter physics engine however using the this.matter.world.on collisionactive function only checks collision between the floor and enemy after the player jumps once. I'm currently using labels to check for collision. I have tried adding extra conditions but have only been able to allow the player to infinitely jump. i.e- it is checking the labels of what is colliding.

Collision checking code:

    this.matter.world.on("collisionactive", (e,o1,o2) => {
        if(o1.label == 'floor' && o2.label == 'player')
        {
            this.touchingGround = true;
            console.log('touching')
        }
    });

Enemy creation function: Right now the enemies are cubes that are created at the cursor when the player presses f

function createEnemy(scene,x,y)
{
    enemy = scene.matter.add.image(x,y,'enemy').setScale(1.5)
    enemy.body.label = 'enemy'
}
1 Answers

I don't completely understand the problem, but if you have an issue with checking/finding all current collisions, you can use the pairs property of the event-object-argument (link to the documentation), which is passed to the physics-callback function. This property should contain, the other collisions.

"...The event.pairs array may contain more colliding bodies. ..."

Here a short demo:

document.body.style = 'margin:0;';
var config = {
    type: Phaser.AUTO,
    width: 11 * 16, 
    height: 6 * 16,
    zoom: 2,
    pixelArt: true,
    scene: {
        preload: preload,
        create: create
    },
    physics: {
        default: 'matter',
        matter: {
            gravity: {
                y:.3
            },
            debug:true
        }
    },
    banner: false
};

function preload (){
    this.load.image('mario-tiles', 'https://labs.phaser.io/assets/tilemaps/tiles/super-mario.png');
}

function create (){
    var level = [
      '0'.repeat(11).split(''),
      '0'.repeat(11).split(''),
      '0'.repeat(11).split(''),
      '0'.repeat(11).split(''),
      '0'.repeat(11).split(''),
      '0'.repeat(11).split('').map( _ => 14),
    ];        
   
    var map = this.make.tilemap({ data: level, tileWidth: 16, tileHeight: 16 });
    var tiles = map.addTilesetImage('mario-tiles');
    var layer = map.createLayer(0, tiles, 0, 0);

    this.add.text(4, 4, 'click to jump', {color:'#9EE6FF', fontSize:10})
        .setOrigin(0);
    var info = this.add.text(4, 14, 'waiting ...', {color:'#ffffff', fontSize:10})
        .setOrigin(0);

    let enemy1 = this.add.rectangle(60.25, 5, 8, 8, 0xfff000)
        .setOrigin(0.5);
    let player = this.add.rectangle(60, 20, 8, 8, 0xffffff);
    
    layer.setCollision([14]);
    
    this.matter.add.gameObject(enemy1);
   
    this.matter.add.gameObject(player);
    this.matter.world.convertTilemapLayer(layer, {label:'floor'});
    
    player.body.label = 'player';
    enemy1.body.label = 'enemy';
    
    this.input.on('pointerup', _=> player.setVelocityY(-3))
    
    player.setVelocityY(-1)

    this.matter.world.on("collisionactive", (e, o1, o2) => {

        let text = 'p: ';
        
        if( e.pairs.some (pair => pair.bodyA.label == 'player' && pair.bodyB.label =='floor' )) {
            text += 'touch floor ';
        }
        
        if( e.pairs.some (pair => pair.bodyA.label == 'enemy' && pair.bodyB.label =='player' )) {
            text += 'touch enemy ';
        }
        
        if( e.pairs.some (pair => pair.bodyA.label == 'enemy' && pair.bodyB.label =='floor' )) {
            text += '\ne: touch floor';
        }
        info.setText(text);            
    });
}

new Phaser.Game(config);
<script src="//cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>

Related