**Fix smash items knocking kids out by excluding kidCategory from collision mask**

The previous fix only exempted the bus's `busCategory` from smashed item collisions, leaving items still colliding with and ejecting kids riding at the open top of the compartment. This commit:

- Adds `~this.bus.kidCategory` to the initial collision filter in `_buildItem`, so new smash items are ghost-to-kids from creation
- Updates the post-smash mask update to also clear `kidCategory` (previously only `busCategory` was cleared), preventing a regression where item↔kid collisions would silently re-enable after the smash animation

Items remain solid against terrain and other props, preserving normal landing/physics behavior while ensuring their impact can no longer contribute to ejecting kids.
This commit is contained in:
Brian Fertig 2026-08-22 17:09:53 -06:00
parent cdc26001fd
commit 8e5398e898
1 changed files with 16 additions and 4 deletions

View File

@ -67,6 +67,15 @@ export default class SmashItemManager {
friction: SMASH_ITEM.friction,
frictionAir: SMASH_ITEM.frictionAir,
restitution: SMASH_ITEM.restitution,
// Never collide with the bus's kids. Kids ride at the open top of the
// compartment, so an item slamming into the bus (or a smashed item
// launched up-and-forward) could otherwise knock them out. Clearing the
// dedicated kidCategory (not the default category, which terrain also
// uses) keeps the item solid against the bus (for the smash) and the
// terrain (so it lands) while making it a pure ghost to the kids -
// its impact can no longer contribute to ejecting them. (setStatic/
// setVelocity etc. are untouched; see the rest of this file.)
collisionFilter: { mask: 0xffffffff & ~this.bus.kidCategory },
});
image.setDisplaySize(SMASH_ITEM.displaySize, SMASH_ITEM.displaySize);
image.setDepth(1); // same layer as the kids - over the ground, under the bus
@ -125,10 +134,13 @@ export default class SmashItemManager {
// see the vendored build). Set on the raw matter body directly: that's the
// exact field canCollide reads, and matter-js recomputes pairs every step,
// so this takes effect on the very next physics step. The item keeps its
// mask against everything ELSE (terrain, other items, kids), so it still
// lands and rests where it flies - only the bus is exempted. This is what
// makes the bus "drive through" a smashed prop instead of bumping it.
image.body.collisionFilter.mask = 0xffffffff & ~this.bus.busCategory;
// mask against everything ELSE (terrain, other items) so it still lands
// and rests where it flies - the bus and the kids are exempted. This is
// what makes the bus "drive through" a smashed prop instead of bumping
// it. Keep the kid exemption too (see _buildItem): clearing only
// busCategory here would silently re-enable item<->kid collisions after
// the smash.
image.body.collisionFilter.mask = 0xffffffff & ~this.bus.busCategory & ~this.bus.kidCategory;
// setStatic(false) (Phaser component, same as in _buildItem) restores
// the body's saved real mass/inertia - matter-js stashed them when the