add animated impact text for hero wounds and deaths in dungeon boss

Introduce showAdventureImpactText() to display centered, animated text
when heroes are wounded or killed during adventure battles. Text pops in
with scale, shakes/pulses, then fades out before continuing.

- Show "Soul Captured" message when hero dies
- Show "was wounded" message on hero defeat
- Chain onDone after full animation completes for proper beat sequencing
This commit is contained in:
Brian Fertig 2026-07-07 19:07:26 -06:00
parent 3e9ee8e47b
commit 1753f43f2e
1 changed files with 41 additions and 5 deletions

View File

@ -3450,8 +3450,11 @@ export default class DungeonBossGame extends Phaser.Scene {
onUpdate: () => heroRec.cont.hpText.setText(`${Math.round(hpObj.v)}`), onUpdate: () => heroRec.cont.hpText.setText(`${Math.round(hpObj.v)}`),
}); });
} }
if (step.heroDies) this.time.delayedCall(480, () => this.removeHeroCard(uid, onDone)); if (step.heroDies) {
else this.time.delayedCall(480, onDone); this.time.delayedCall(480, () => this.removeHeroCard(uid, () => {
this.showAdventureImpactText(`${this.advHeroName(uid)}'s Soul Captured`, '#39ff6a', onDone);
}));
} else this.time.delayedCall(480, onDone);
}); });
}); });
} }
@ -3475,7 +3478,9 @@ export default class DungeonBossGame extends Phaser.Scene {
ab.stage.add(flash); ab.stage.add(flash);
this.tweens.add({ targets: flash, alpha: 0, duration: 260, onComplete: () => flash.destroy() }); this.tweens.add({ targets: flash, alpha: 0, duration: 260, onComplete: () => flash.destroy() });
} }
this.time.delayedCall(300, () => this.removeHeroCard(uid, onDone)); this.time.delayedCall(300, () => this.removeHeroCard(uid, () => {
this.showAdventureImpactText(`${this.advHeroName(uid)}'s Soul Captured`, '#39ff6a', onDone);
}));
}); });
} }
@ -3501,8 +3506,39 @@ export default class DungeonBossGame extends Phaser.Scene {
ab.heroCards.delete(uid); ab.heroCards.delete(uid);
const idx = ab.heroOrder.indexOf(uid); const idx = ab.heroOrder.indexOf(uid);
if (idx >= 0) ab.heroOrder.splice(idx, 1); if (idx >= 0) ab.heroOrder.splice(idx, 1);
if (step.eliminated) this.showAdventureEliminatedBanner(this.seatName(ab.seat), onDone); this.showAdventureImpactText(`${this.seatName(ab.seat)} was wounded`, '#ff3b3b', () => {
else onDone(); if (step.eliminated) this.showAdventureEliminatedBanner(this.seatName(ab.seat), onDone);
else onDone();
});
},
});
},
});
}
// Big punchy center-screen text for a boss wound or a hero's death — pops
// in, shakes/pulses for about a second, then shrinks away to nothing.
// onDone only fires once the whole sequence completes, so callers can
// chain it as a blocking beat before the walk proceeds.
showAdventureImpactText(text, color, onDone) {
const ab = this._advBattle;
const cx = GAME_WIDTH / 2, cy = GAME_HEIGHT / 2;
const t = this.add.text(cx, cy, text, {
fontFamily: 'Righteous', fontSize: '60px', color, align: 'center',
stroke: '#120e16', strokeThickness: 8,
}).setOrigin(0.5).setScale(0);
ab.root.add(t);
this.tweens.add({
targets: t, scale: 1, duration: 220, ease: 'Back.easeOut',
onComplete: () => {
this.tweens.add({ targets: t, x: cx - 5, duration: 55, ease: 'Sine.easeInOut', yoyo: true, repeat: 9 });
this.tweens.add({
targets: t, scale: 1.08, duration: 150, ease: 'Sine.easeInOut', yoyo: true, repeat: 2,
onComplete: () => {
this.tweens.add({
targets: t, scale: 0, alpha: 0, duration: 260, ease: 'Cubic.easeIn',
onComplete: () => { t.destroy(); onDone(); },
});
}, },
}); });
}, },