refactor: eliminate more any types in FightScene, FightViewer, FightPage

Replace any[] with GameObj[], fighter: any with Fighter in speech
bubbles, talking anims, showboat system, bow/fistbump/helpup, and
dizzy stars. Fix customization as any casts with ?? undefined.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-09 06:29:09 +00:00
co-authored by Claude Opus 4.6
parent a86d39b982
commit 38d7236be3
3 changed files with 15 additions and 15 deletions
+2 -2
View File
@@ -201,8 +201,8 @@ async function initScene() {
try {
const scenePromise = createFightScene({
canvas: newCanvas,
botA: { name: props.fight.botA.name, seed: props.fight.botA.avatarSeed || props.fight.botA.name, tier: props.fight.botA.tier, archetype: props.fight.botA.archetype, customization: props.fight.botA.customization as any, wins: props.fight.botA.wins, losses: props.fight.botA.losses },
botB: { name: props.fight.botB.name, seed: props.fight.botB.avatarSeed || props.fight.botB.name, tier: props.fight.botB.tier, archetype: props.fight.botB.archetype, customization: props.fight.botB.customization as any, wins: props.fight.botB.wins, losses: props.fight.botB.losses },
botA: { name: props.fight.botA.name, seed: props.fight.botA.avatarSeed || props.fight.botA.name, tier: props.fight.botA.tier, archetype: props.fight.botA.archetype, customization: props.fight.botA.customization ?? undefined, wins: props.fight.botA.wins, losses: props.fight.botA.losses },
botB: { name: props.fight.botB.name, seed: props.fight.botB.avatarSeed || props.fight.botB.name, tier: props.fight.botB.tier, archetype: props.fight.botB.archetype, customization: props.fight.botB.customization ?? undefined, wins: props.fight.botB.wins, losses: props.fight.botB.losses },
arena: props.fight.arena,
})
const timeout = new Promise<null>((resolve) => setTimeout(() => resolve(null), 10_000))
+12 -12
View File
@@ -1934,10 +1934,10 @@ export async function createFightScene(config: FightSceneConfig) {
// Speech bubble above a fighter — colourful with tail
// Active speech bubbles — destroy previous before showing new
let activeBubbleA: any[] = []
let activeBubbleB: any[] = []
let activeBubbleA: GameObj[] = []
let activeBubbleB: GameObj[] = []
function destroyBubble(els: any[]) {
function destroyBubble(els: GameObj[]) {
els.forEach(el => { if (el.exists()) el.destroy() })
els.length = 0
}
@@ -1950,7 +1950,7 @@ export async function createFightScene(config: FightSceneConfig) {
if (side === 'a') destroyBubble(activeBubbleA)
else destroyBubble(activeBubbleB)
const allEls: any[] = []
const allEls: GameObj[] = []
// Sanitize and truncate
const clean = safeText(text)
@@ -2092,7 +2092,7 @@ export async function createFightScene(config: FightSceneConfig) {
}
// Talking mouth animation — a small rectangle that opens/closes near the fighter's face
const talkingAnims: Record<string, { objs: any[]; timer: ReturnType<typeof setInterval> }> = {}
const talkingAnims: Record<string, { objs: GameObj[]; timer: ReturnType<typeof setInterval> }> = {}
function startTalking(side: 'a' | 'b') {
stopTalking(side) // cleanup any existing
@@ -2333,7 +2333,7 @@ export async function createFightScene(config: FightSceneConfig) {
}
// Respectful bow animation
async function playBow(fighter: any) {
async function playBow(fighter: Fighter) {
const origScaleY = fighter.scale.y
await k.tween(fighter.scale.y, origScaleY * 0.85, 0.2, (v) => { fighter.scale.y = v }, k.easings.easeOutQuad)
await k.wait(0.3)
@@ -2341,7 +2341,7 @@ export async function createFightScene(config: FightSceneConfig) {
}
// Fist bump between two fighters
async function playFistBump(fighterA: any, fighterB: any) {
async function playFistBump(fighterA: Fighter, fighterB: Fighter) {
const midX = (fighterA.pos.x + fighterB.pos.x) / 2
const origAX = fighterA.pos.x
const origBX = fighterB.pos.x
@@ -2361,7 +2361,7 @@ export async function createFightScene(config: FightSceneConfig) {
}
// Winner helps loser back up
async function playHelpUp(winner: any, loser: any, winningSide: 'a' | 'b') {
async function playHelpUp(winner: Fighter, loser: Fighter, winningSide: 'a' | 'b') {
const dir = winningSide === 'a' ? 1 : -1
const origWX = winner.pos.x
await k.tween(winner.pos.x, loser.pos.x - dir * 30, 0.4, (v) => { winner.pos.x = v }, k.easings.easeInOutQuad)
@@ -2503,7 +2503,7 @@ export async function createFightScene(config: FightSceneConfig) {
// Fighters perform these during question/answer phases instead of boring idle bobbing
const _showboatActive: Record<string, boolean> = { a: false, b: false }
type ShowboatFn = (fighter: any, homeX: number, homeY: number, sx: number, sy: number, dir: number) => Promise<void>
type ShowboatFn = (fighter: Fighter, homeX: number, homeY: number, sx: number, sy: number, dir: number) => Promise<void>
// dir: 1 = facing right (bot A), -1 = facing left (bot B)
const showboats: ShowboatFn[] = [
@@ -3039,7 +3039,7 @@ export async function createFightScene(config: FightSceneConfig) {
k.tween(f.pos.y, hy - 60, 0.2, (v) => { f.pos.y = v }, k.easings.easeOutQuad),
])
// Spawn orbiting ₿
const orbs: any[] = []
const orbs: GameObj[] = []
for (let i = 0; i < 8; i++) {
const orb = k.add([k.text('₿', { size: 8 + Math.random() * 6 }), k.pos(center, f.pos.y), k.color(safeColor(k, i % 2 === 0 ? '#ffd700' : '#ff8c00')), k.opacity(0.8), k.z(15), k.anchor('center')])
orbs.push(orb)
@@ -3347,7 +3347,7 @@ export async function createFightScene(config: FightSceneConfig) {
// Creator uses magical showboats 60% of the time, normal 40%
const pool = isCreator ? [...showboats, ...creatorShowboats, ...creatorShowboats] : showboats
while (_showboatActive[side]) {
const f = k.get(tag)[0]
const f = k.get(tag)[0] as Fighter | undefined
if (!f) break
const sx = f.scale.x
const sy = f.scale.y
@@ -3416,7 +3416,7 @@ export async function createFightScene(config: FightSceneConfig) {
},
// Physical contact delegates
_spawnDizzyStars(fighter: any, duration: number) { return roundSystem._spawnDizzyStars(fighter, duration) },
_spawnDizzyStars(fighter: Fighter, duration: number) { return roundSystem._spawnDizzyStars(fighter, duration) },
_resetPositions() { return roundSystem._resetPositions() },
_brawlRapid(winningSide: 'a' | 'b' | null, intensity: number) { return roundSystem._brawlRapid(winningSide, intensity) },
_brawlKnockdown(winningSide: 'a' | 'b' | null, intensity: number) { return roundSystem._brawlKnockdown(winningSide, intensity) },
+1 -1
View File
@@ -566,7 +566,7 @@ async function watchAnotherFight() {
const res = await fetch('/api/fights')
if (res.ok) {
const fights = await res.json()
const finished = fights.filter((f: any) => f.status === 'finished' && f.id !== fightId.value)
const finished = fights.filter((f: { status: string; id: string }) => f.status === 'finished' && f.id !== fightId.value)
if (finished.length > 0) {
const pick = finished[Math.floor(Math.random() * finished.length)]
router.push(`/arena/${pick.id}`)