- Extend bonus items spritesheet from 9 to 12 frames (add flour + 2 firework objects)
- Add `flour` type to BONUS_ITEM config with warm off-white/tan color palette and firework variant (2-3x scale, half opacity for dust cloud effect)
- Implement per-type firework variants in BonusItemManager._explode() - particles can now have varied sizes and alpha while maintaining standard physics body size
- Add flour SFX asset (bonus-flour.mp3) and preload it
- Update editor to support placing flour bonus items with appropriate icon, color, and sprite frame
- Update all documentation (README, sprites.md) to reflect the new bonus item type
Additionally:
- Add campaign 2 bus physics customization: grippier tires (higher friction coefficients) and stiffer/less-damped suspension for bouncier ride
- Thread per-campaign wheel friction and suspension parameters through Bus entity from themes.js
- Redesign level11 with shorter course, fewer kids (4 vs 3), tighter time limit (42s vs 119s), and flour bonus items replacing most cash/CTC/guitar
- Introduce `bus_wheel_2` asset and register it in the asset manifest
- Add `BUS.wheelRadius2` config for the larger wheel radius
- Extend themes with a `bus` block to select wheel texture and radius per campaign; campaign02 uses the new bigger wheels while keeping the same axle center
- Make `Bus` accept a bus theme parameter and use provided wheel texture/radius when creating wheels
- Update `PlayScene` to pass the active theme's `bus` settings into the Bus constructor
- Document the new per-campaign bus art/sizing behavior in sprites.md
- Add per-item sound keys to `SmashItemManager` and `BonusItemManager`, playing a dedicated clip on smash/collection (load-tolerant via `cache.audio.exists`)
- Preload new FX clips: `smash-{tv,chair,cone}` and `bonus-{cash,ctc,guitar}`
- Rebuild level07 terrain/layout with updated items, bonus placements, goal, and camera bounds
- Move level01 item positions to match new layout
- Update smash-items sprite sheet (PNG/PSD)
Introduces a new "bonus item" system alongside the existing smashables:
- **Gameplay**: Floating collectible prizes (CTC box, guitar, cash) that the bus passes through with zero physical response. On first contact, the item pops (scale-up + fade) and spawns a radial burst of tinted firework particles that arc down under gravity, settle on terrain, and fade out. Each collected item scores 100 points on the end-of-level tally.
- **Config**: `BONUS_ITEM` in `config.js` holds all tuning knobs (particle count, speed range, spin, lifetime, per-type tint palette, pop scale/duration). `SCORE.perBonusItem` added.
- **Entity**: New `BonusItemManager` class owns static sensor bodies for each bonus item, detects bus collisions, and orchestrates the pop + firework burst animation. Particles are real Matter bodies exempted from bus/kid collision so they can land on terrain without affecting gameplay.
- **Editor**: "Smashables" section renamed to "Placeables" with a kind toggle (Smashables vs Bonus items). Bonus items are float-only with no gravity option. Preview map, click-to-place, item list, and export all support both kinds. `splitPlaceables()` in `levelBuilder.js` splits the unified editor list into the two level arrays (`items` / `bonusItems`).
- **Levels**: Levels 2–6 updated with bonus item placements (and some additional smashable items).
- **Assets**: New `bonus-items.png` spritesheet (9 frames: 3 bonus items × [item + 2 firework objects]) registered in the asset manifest.
- **Score screen**: `_revealBonus()` method in `LevelScoreScene` displays collected bonus count and points, skipped when zero.
- New SmashItemManager entity that spawns items from level data, detects bus contact, swaps to smashed frame, and applies up-and-forward impulse with tumble
- Add `SMASH_ITEM` config block for launch speed/angle/spin, density, friction, restitution, and float height
- Extend asset manifest and spritesheet (6 frames: intact/smashed TV, chair, cone)
- Level editor gains "Smashables" section to place/delete items via click on preview map; exports `items` array in level data
- Level editor can now import bundled or file-based levels, preserving exact terrain while locking section editing; metadata and items remain editable for re-export
- Score scene reveals smashed item count as a bonus line (+50 each) between kids and time tally
- PlayScene wires SmashItemManager lifecycle and passes smashedCount to score scene
- README documents smashables feature, editor workflow, and import behavior
Ejection used to be g-force-triggered, but the suspension isolates the
chassis from shocks so the old threshold was effectively unreachable -
kids were never actually being ejected. Instead the bus now carries an
invisible three-sided box (floor + left/right walls, deliberately no
ceiling) pinned to the chassis with rigid constraints. The fixtures are
standalone bodies in a dedicated kid collision category, not compounded
into the chassis, because Matter only consults the root body's filter
on compounds, so only standalone bodies can be made to collide with kids
while the chassis part stays exempt.
KidManager now checks each kid's rotation-corrected chassis-local
position every physics tick and flips state in both directions: crossing
above the open top marks the kid ejected (light custom gravity,
kid_ejected texture), and drifting back down through it re-marks the kid
aboard. A per-tick hard clamp keeps kids from tunneling through the
floor/walls on a fast hit. Seat constraints and the settle timer are
gone - containment is purely physical collision. GForceMonitor is
demoted to a debug-only readout for landing diagnosis.
Kid art is now 5-frame spritesheets (one distinct kid per seat), with
the frame picked by seat index in Kid.js, and render order is fixed with
explicit depths (kids 1, bus chassis/wheels 2).