Phaser 3 + Matter.js laser pointer example

Hi Phaser coders!

I’d like to create a simple laser pointer test with Matter.js and Phaser 3 although I’d like for the laser beam to interact with the Matter.js tilemap as well.

Essentially the laser beam starts in the center of the room and is pointed toward the mouse.

To do this I used the Phaser 3 line game object and it all worked well until I introduced the Matter.js tilemap.

When the laser hits the tilemap it just goes straight through instead of stopping at the tile :frowning:

I don’t really know where to start on this, I looked into raycasting but I didn’t understand it very well.

Any help is much appreciated :slight_smile:

It’s been a few days and I still haven’t gotten an answer.

If creating a laser pointer that interacts with a tilemap isn’t possible then please let me know instead of leaving me guessing.

You can!

Adding a line game object will not by default have a matter body, you will have to make a matter body for it and then assign that body to the line. You can then use matter collision callbacks to check if the line should only be drawn to a tile.

You can also use a raycast, you will not have to add a body to the line to use this. To raycast in the matter world, you use Phaser.Physics.Matter.Matter.Query.ray(allTheTileBodies, centerOfTheRoom, mousePosition, widthOfRayInPixels); This gives you an array of bodies that you can iterate and find the closest body, use that to stop drawing the laserpointer line. “allTheTileBodies” are part of the bodies in the current scene can be found in matter.world.localWorld.bodies.

Sorry for not giving code examples, can’t do it right now. Check https://labs.phaser.io/ there might be some matter/tile examples that can be useful.

Hi there @smjn thank you so much for your reply!

I think I know how I can achieve this effect now, so I’ll reply to this thread in a few days showing what worked for me.

Hi @smjn!

I’ve had a go at raycasting and this is what I’ve come up with:

var startPointObj          = {'x': 100, 'y': 100};
var angleRad               = Phaser.Math.Angle.BetweenPoints(
    startPointObj,
    {'x': mouseX, 'y': mouseY},
);
var endPointObj            = {'x': Math.cos(angleRad) * 10000, 'y': Math.sin(angleRad) * 10000};
var collisionsArr          = Phaser.Physics.Matter.Matter.Query.ray(this.matter.world.localWorld.bodies, startPointObj, endPointObj);
var collidedSpriteObj      = null;
var collidedPenetrationObj = {};

if (collisionsArr[0]) {
    collidedSpriteObj      = collisionsArr[0].bodyB;
    collidedPenetrationObj = collisionsArr[0].penetration;
}
this.add.line(
    0,
    0,
    startPointObj.x,
    startPointObj.y,
    (collidedSpriteObj) ? collidedSpriteObj.position.x + collidedPenetrationObj.x : endPointObj.x,
    (collidedSpriteObj) ? collidedSpriteObj.position.y + collidedPenetrationObj.y : endPointObj.y,
    0xff0000
).setOrigin(0, 0);

What this is supposed to do is draw a line at 100, 100 that is angled in the mouse’s direction, then stop the line when it hit’s something.

But it doesn’t work properly :frowning:

This is what it does:

It seems to be doing this weird clumping as it hits each tile:

image

Do any of you know why this is happening?