I am working on a game feature using sensors, and am having an issue, whereby I can’t seem to use the standard collission detection mechanisms
I’ve re-created the issue in a sandbox here - Phaser 3 - Colissions - CodeSandbox
What happens within this -
- We create a player, and 5 bots within
index.js
- On left click, the player (
player.ts
) will create a “grenade” and throw towards bots (colliding with them), then after 1 second will explode (this is when the grenade body turns from a normal physics body, into a sensor to detect a “kill area”). - grenade.ts
, line 49
The problem is as you see in logs, when the grenade hits the bots before explosion (I.E not a sensor), the collission signature works as expected
grenade.setOnCollide((pair) => {
console.log(`collission between ${pair.bodyA.gameObject.type} and ${pair.bodyB.gameObject.type}`)
});
However once the grenade turns into a sensor, that callback no longer gets called, and I must rely on this unperformant way to check for sensor hits
this.scene.matter.world.on('collisionstart', function (event)
Is there any way I can listen for collissions on the grenade sprite, rather than every player having tio listen to all collission events, and iflter for the correct ones (feels extremelly un-performant)
Hi,
I never used Matter before, but i usually make different classes between weapons and explosions.
Based on your Bot class, i made a Explosion class. And inside Grenade.explode i just create a new explosion. It seems to work, but perhaps not the way you want (with sensor)
Explosion class
export default class Explosion extends Phaser.Physics.Matter.Sprite {
health = 100;
constructor(scene, x, y, key) {
super(scene.matter.world, x, y, key);
// set shape to circle
this.setCircle(50);
// this.setCollisionCategory(collisionGroups.BOT_GROUP);
// this.setCollidesWith([collisionGroups.GRENADE_GROUP]);
this.type = "EXPLOSION";
this.setOnCollide((pair) => {
console.log(
`Explosion collission between ${pair.bodyA.gameObject.type} and ${pair.bodyB.gameObject.type}`
);
});
// destroy the grenade after 0.1 seconds#
this.scene.time.addEvent({
delay: 100,
callback: () => {
this.destroy();
}
});
}
}```
Grenade class
```import Phaser from "phaser";
import Explosion from "./explosion";
export default class Grenade extends Phaser.Physics.Matter.Sprite {
public worldLayer: Phaser.Tilemaps.TilemapLayer;
public associatedEntityId: number;
constructor(
scene: Phaser.Scene,
private startX: number,
private startY: number,
private targetAngle: number,
private speed: number
) {
super(scene.matter.world, startX, startY, "grenade", 0);
this.setVelocity(1, 1);
this.rotation = Phaser.Math.DegToRad(targetAngle) + 1.57079633;
this.setFriction(0, 0);
this.type = "GRENADE_MOVING";
// Detonate after 5 seconds
this.scene.time.addEvent({
delay: 1000,
callback: () => {
this.explode();
}
});
}
explode() {
this.type = "GRENADE_EXPLODING";
const explosion = new Explosion(this.scene,
this.x + 25,
this.y + 25,
'test',
)
// destroy the grenade after 0.1 seconds#
this.scene.time.addEvent({
delay: 100,
callback: () => {
this.destroy();
}
});
}
}```
Makes sense @BlunT76 you could certainly add an extra class for that.
Regarding a cleaner way to detect sensor collission with bodys, I’ve made use of phaser-matter-collision-plugin
The demo now uses it - Phaser 3 - Colissions - CodeSandbox, found the suggestiion in Modular Game Worlds in Phaser 3 (Tilemaps #5) — Matter Physics Platformer | by Michael Hadley | ITNEXT