Wire audio/ghost/title into game, race:respawn event, launcher x-centering

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
type-two 2026-07-18 11:51:38 +10:00
parent 4494924c8c
commit 43d2b0049a

View File

@ -12,6 +12,9 @@ import { createBlobFeel } from './blob/feel'
import { createFollowCamera } from './blob/camera'
import { PaintSkin, PaintCannon, BuffSystem, PaintHUD, installPaint } from './paint/index'
import { createPressurePlate, createSpringBoot, createBucketDump, createBubbleArch, createConveyorBelt } from './machine/index'
import { installAudio } from './audio/index'
import { installGhost } from './ghost/index'
import { installTitle } from './ui/title'
export function installGame(world: World) {
const course = buildGreybox(world)
@ -133,7 +136,8 @@ export function installGame(world: World) {
// into the shelf face, so go UP hard and pull toward the slot center;
// forward drift only wins after the arc clears the shelf top.
const vz = Math.max(-3, Math.min(3, (0.5 - t.z) * 1.5))
blob.body.setLinvel({ x: v.x * 0.4, y: 14, z: vz }, true)
const vx = Math.max(-3, Math.min(3, (0 - t.x) * 1.5)) // center x too — cannon impacts drift racers sideways
blob.body.setLinvel({ x: vx, y: 14, z: vz }, true)
bounceCooldown = 0.6
world.events.emit('blob:jumped', {}) // reuse the stretch feel
}
@ -213,6 +217,7 @@ export function installGame(world: World) {
raceState = 'idle'
raceT = 0
banner.style.display = 'none'
world.events.emit('race:respawn', {})
}
world.onFrame(() => {
if (blob.body.translation().y < -25) respawn()
@ -248,6 +253,11 @@ export function installGame(world: World) {
setTimeout(() => toast.remove(), 3200)
})
// ---- wave 2: audio, ghost, title ----
installAudio(world)
installGhost(world, blob, { radius: blob.radius })
installTitle(world)
// debug handle (dev builds are the only builds right now)
;(window as unknown as { BLOBBO: unknown }).BLOBBO = { world, blob, skin, course }