-
Hi, For example, I have a collision group "asteroid" for asteroids and a collision group "player" for a player and I want asteroids to be able to collide with themselves and with the player only. How can this be achieved? The example from documentation does not cover this aspect (https://excaliburjs.com/docs/collisiongroups) const asteroidGroup = CollisionGroupManager.create("asteroid");
export class Asteroid extends CosmicBody {
constructor() {
super({
// ...
collisionGroup: asteroidGroup,
});
} And if I combine collision groups then collisions won't work at all export const asteroidGroup = CollisionGroupManager.create("asteroid");
export class Asteroid extends CosmicBody {
constructor() {
const asteroidsCanCollideWith = CollisionGroup.collidesWith([
asteroidGroup,
playerGroup,
]);
super({
// ...
collisionGroup: asteroidsCanCollideWith,
});
}
// ...
} export const playerGroup = CollisionGroupManager.create("player");
export class Player extends CosmicBody {
constructor() {
const playerCanCollideWith = CollisionGroup.collidesWith([
asteroidGroup,
playerGroup,
]);
super({
// ...
collisionGroup: playerCanCollideWith,
});
}
// ...
} If it's important, I use my own collision logic in the precollision event and all objects have a collision type CollisionType.Passive |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
Hi @KostarSf this is a great question! I think the issue here is that both new groups In Excalibur things of the same group do not collide by default, here is an example that you can use to check: const asteroidGroup = ex.CollisionGroupManager.create("asteroid");
const playerGroup = ex.CollisionGroupManager.create("player");
const asteroidsCanCollideWith = ex.CollisionGroup.collidesWith([
asteroidGroup,
playerGroup,
]);
const playerCanCollideWith = ex.CollisionGroup.collidesWith([
asteroidGroup,
playerGroup,
]);
console.log('asteroidsCanCollideWith:', asteroidsCanCollideWith.name); // ~(asteroid+player)
console.log('playerCanCollideWith:', playerCanCollideWith.name); //~(asteroid+player)
console.log('can collide?', asteroidsCanCollideWith.canCollide(playerCanCollideWith)); // false However you can skip the So, the way to thing about this is the "category" is a unique power of 2 in binary, the mask puts a 1 in for each category the group collides with. By default the This is how the public canCollide(other: CollisionGroup): boolean {
return (this.category & other.mask) !== 0 && (other.category & this.mask) !== 0;
} TLDR Possible solutionTo make a group that collides with both players and asteroids, but not "other-group" you could craft a new So here is an example of a custom mask, const asteroidGroup = new ex.CollisionGroup('asteroid', 0b0001, 0b1110);
const playerGroup = new ex.CollisionGroup('player', 0b0010, 0b1101);
const playerAndAsteroid = new ex.CollisionGroup('collided with player & asteroid but not other-group', 0b0100, 0b0111);
const otherGroup = new ex.CollisionGroup('other-group', 0b1000, 0b0111);
console.log('can collide playerAndAsteroid with playerAndAsteroid?', playerAndAsteroid.canCollide(playerAndAsteroid)); // true
console.log('can collide asteroid with player?', asteroidGroup.canCollide(playerGroup)); // true
console.log('can collide asteroid with playerAndAsteroid?', asteroidGroup.canCollide(playerAndAsteroid)); //true
console.log('can collide player with playerAndAsteroid?', playerGroup.canCollide(playerAndAsteroid)); // true
console.log('can collide other-group with playerAndAsteroid?', otherGroup.canCollide(playerAndAsteroid)); // false Here's a table with the possible interactions for this example
|
Beta Was this translation helpful? Give feedback.
Hi @KostarSf this is a great question!
I think the issue here is that both new groups
playerCanCollideWith
andasteroidsCanCollideWith
are technically the same group. This feature in Excalibur is very confusing, each group is a category that won't self collide. There is a special built in groupCollisionGroup.All
that collides with everything.In Excalibur things of the same group do not collide by default, here is an example that you can use to check: