Matter.js - How to overlap tile layer and sprite

Hi, I’m trying to add overlap feature to my game between sprite and a map layer (from tiled). I tried implement it with @espace answer in Matter.js how do you do a system of overlap? , but It didn’t work. Can somebody give me an example how to achieve that overlaping collision?

Just to clarify, are you asking about detecting and handling a collision between a game object and a tile, but you don’t want the game object to separate from the tile (they are allowed to overlap)? Are you also using Matter physics, or are you using Arcade?

I’m using Matter physics. The problem is that I want to detect collision between tiles, and my sprite when overlaping, So I need example how to achieve this. I don’t have any idea how to handle this. Actually my tiles collides with my sprite by setting property:

setCollisionByProperty({collidesLadder: true})

but I don’t want to collide them, I just want to detect when they overlaping.

Okay, after a bit of digging, here’s what I’ve found. What you’re looking for is the “isSensor” property on the matterjs physics body. I was fiddling around with this example - here’s an excerpt where the tiles are given physics bodies

// Set colliding tiles before converting the layer to Matter bodies!
layer.setCollisionByProperty({ collides: true });
// Convert the layer. Any colliding tiles will be given a Matter body. If a tile has collision // shapes from Tiled, these will be loaded. If not, a default rectangle body will be used. The
// body will be accessible via tile.physics.matterBody.
this.matter.world.convertTilemapLayer(layer);

The example is setting collisions on tiles that have the property {collides: true}, but you’re limiting yours to the collidesLadder property, all good so far. At this point all your ladder tiles will have physics bodies and all of them will collide.

As far as I can tell, convertTilemapLayer doesn’t allow for any options to set all the bodies it creates as sensors, so we’ll have to iterate through all the created bodies and SET their isSensor properties. NOTE: If you have other tiles in that layer that do NOT have the ladderCollide property, you may need to throw in an if statement that checks if the tile has a body before attempting to set the body’s isSensor property.

layer.forEachTile(function (tile) {
  // If your ladder tiles have a complex body made up of different parts, you'll need to iterate through
  // each part. If it's a simple rectangle, it will only have 1 part which is a reference to itself
  tile.physics.matterBody.body.parts.forEach((part) => {
    part.isSensor = true;
  });
});

Now collisions will be detected with your ladder tiles, but your sprite can overlap them and won’t separate from them.

If someone has a more elegant way to handle this, I’d love to hear it. But this should hopefully get you going for the time being.

I don’t know why byt my tiles physics property is an empty object. Can ou send me your example?

Better yet, can you send a relevant section of your code? In the meantime I’ll make up a CodePen.

This console.log returns empty object in physics property:

/* MAP */
    var map = this.make.tilemap({ key: "map" });
    var tileset = map.addTilesetImage("la-roche-tiles", "la-roche-tiles");
    this.backgroundLayer = map.createLayer("Background", tileset);
    var layer = map.createLayer("Ground", tileset);

    let ladderLayer = map.createLayer("Ladders", tileset);
    map.setCollisionByProperty({ collides: true }, true, true, "Ground");
    map.setCollisionByProperty({ collideLadder: true }, true, true, "Ladders");

    ladderLayer.forEachTile(function (tile) {
      // tile.physics.matterBody.body.parts.forEach((part) => {
      //   part.isSensor = true;
      // });
       console.log(tile.physics); // This returns me empty object, so I can't set it to sensor;
    });

There are only 7 lines of code in my previous post and you skipped one! It even has a commented description!

this.matter.world.convertTilemapLayer(layer) is what actual GIVES your tiles physics bodies. setCollisionByProperty only creates a filter for which tiles will receive bodies from convertTilemapLayer.

Here are their descriptions in the docs: setCollisionByProperty, convertTilemapLayer

Make sure you check out examples for Matter physics since it seems to work quite differently from Arcade. Here’s the example I posted earlier, and here’s a CodePen modifying that example to fit your situation:

Again, for anyone reading this in the future, if you have a more elegant or efficient way to set tile bodies as sensors, I’d love to hear it!