feat: implement spawnGrotesqueDetails and spawnCrowdSigns stubs

- spawnGrotesqueDetails: radial impact lines + dots during zoom close-ups
- spawnCrowdSigns: signs rise from bottom with text labels, bob, fade out

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-08 00:00:16 +00:00
co-authored by Claude Opus 4.6
parent 728afacc5c
commit 05829e58ae
+88 -5
View File
@@ -586,9 +586,44 @@ export async function createFightScene(config: FightSceneConfig) {
k.tween(0.4, 0, duration, (v) => { flash.opacity = v }).then(() => flash.destroy()) k.tween(0.4, 0, duration, (v) => { flash.opacity = v }).then(() => flash.destroy())
} }
// Grotesque close-up stubs (disabled — looked bad) // Grotesque close-up: spawn exaggerated impact details during zoom-ins
function spawnGrotesqueDetails(_fighter: any, _scaleFactor: number) {} let grotesqueObjs: any[] = []
function destroyGrotesqueDetails() {} function spawnGrotesqueDetails(fighter: any, scaleFactor: number) {
destroyGrotesqueDetails()
if (!fighter?.exists()) return
const fx = fighter.pos.x, fy = fighter.pos.y
const s = Math.max(1, scaleFactor)
// Impact lines radiating from fighter
for (let i = 0; i < 6; i++) {
const angle = (i / 6) * Math.PI * 2 + Math.random() * 0.3
const len = 30 + Math.random() * 40
const line = k.add([
k.rect(3 * s, len * s),
k.pos(fx + Math.cos(angle) * 20, fy - 30 + Math.sin(angle) * 20),
k.color(safeColor(k, i % 2 === 0 ? '#ffffff' : '#ff2d2d')),
k.opacity(0.7),
k.z(25),
k.rotate(angle * (180 / Math.PI) + 90),
k.anchor('center'),
])
grotesqueObjs.push(line)
}
// Speed/impact dots
for (let i = 0; i < 4; i++) {
const dot = k.add([
k.circle(4 + Math.random() * 6),
k.pos(fx + (Math.random() - 0.5) * 60, fy - 30 + (Math.random() - 0.5) * 50),
k.color(safeColor(k, '#ffe14d')),
k.opacity(0.8),
k.z(25),
])
grotesqueObjs.push(dot)
}
}
function destroyGrotesqueDetails() {
for (const o of grotesqueObjs) { if (o.exists()) o.destroy() }
grotesqueObjs = []
}
// Arena-specific background decoration // Arena-specific background decoration
function drawArenaDecor() { function drawArenaDecor() {
const a = arena const a = arena
@@ -6278,8 +6313,56 @@ export async function createFightScene(config: FightSceneConfig) {
k.tween(0.8, 0, 1.5, (v) => { heart.opacity = v }).then(() => { if (heart.exists()) heart.destroy() }) k.tween(0.8, 0, 1.5, (v) => { heart.opacity = v }).then(() => { if (heart.exists()) heart.destroy() })
} }
// Crowd signs stub (disabled — too small to look good) // Crowd signs: pop up from bottom with text, bob, then fade out
function spawnCrowdSigns(_count: number, _color: string, _text?: string) {} function spawnCrowdSigns(count: number, color: string, text?: string) {
const labels = text ? [text] : ['GO!', 'WOW', 'KO!', 'LOL', 'GG', 'OMG']
for (let i = 0; i < count; i++) {
const x = W * 0.15 + Math.random() * W * 0.7
const startY = H + 20
const endY = GROUND_Y + 10 + Math.random() * 20
const label = labels[Math.floor(Math.random() * labels.length)]
// Sign stick
const stick = k.add([
k.rect(3, 25),
k.pos(x, startY),
k.color(safeColor(k, '#886644')),
k.opacity(0.8),
k.z(8),
k.anchor('bot'),
])
// Sign face
const sign = k.add([
k.rect(Math.max(30, label.length * 10), 18),
k.pos(x, startY - 25),
k.color(safeColor(k, color)),
k.opacity(0.85),
k.z(8),
k.anchor('center'),
])
// Sign text
const txt = k.add([
k.text(label, { size: 10 }),
k.pos(x, startY - 25),
k.color(safeColor(k, '#ffffff')),
k.opacity(0.9),
k.z(9),
k.anchor('center'),
])
const delay = i * 0.08
// Rise up
k.wait(delay, () => {
k.tween(startY, endY, 0.3, (v) => { stick.pos.y = v; sign.pos.y = v - 25; txt.pos.y = v - 25 }, k.easings.easeOutBack)
})
// Bob + fade out after 1.5s
k.wait(delay + 1.5, () => {
k.tween(0.85, 0, 0.5, (v) => { stick.opacity = v; sign.opacity = v; txt.opacity = v }).then(() => {
if (stick.exists()) stick.destroy()
if (sign.exists()) sign.destroy()
if (txt.exists()) txt.destroy()
})
})
}
}
// === HUMAN OWNER APPEARANCES === // === HUMAN OWNER APPEARANCES ===
// The silly human behind each bot occasionally shows up // The silly human behind each bot occasionally shows up