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:
co-authored by
Claude Opus 4.6
parent
728afacc5c
commit
05829e58ae
@@ -586,9 +586,44 @@ export async function createFightScene(config: FightSceneConfig) {
|
||||
k.tween(0.4, 0, duration, (v) => { flash.opacity = v }).then(() => flash.destroy())
|
||||
}
|
||||
|
||||
// Grotesque close-up stubs (disabled — looked bad)
|
||||
function spawnGrotesqueDetails(_fighter: any, _scaleFactor: number) {}
|
||||
function destroyGrotesqueDetails() {}
|
||||
// Grotesque close-up: spawn exaggerated impact details during zoom-ins
|
||||
let grotesqueObjs: any[] = []
|
||||
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
|
||||
function drawArenaDecor() {
|
||||
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() })
|
||||
}
|
||||
|
||||
// Crowd signs stub (disabled — too small to look good)
|
||||
function spawnCrowdSigns(_count: number, _color: string, _text?: string) {}
|
||||
// Crowd signs: pop up from bottom with text, bob, then fade out
|
||||
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 ===
|
||||
// The silly human behind each bot occasionally shows up
|
||||
|
||||
Reference in New Issue
Block a user