From 1753f43f2e7f70aded60fdfcfd12c37745aae740 Mon Sep 17 00:00:00 2001 From: Brian Fertig Date: Tue, 7 Jul 2026 19:07:26 -0600 Subject: [PATCH] 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 --- src/games/dungeonboss/DungeonBossGame.js | 46 +++++++++++++++++++++--- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/src/games/dungeonboss/DungeonBossGame.js b/src/games/dungeonboss/DungeonBossGame.js index 662ae5a..b07583e 100644 --- a/src/games/dungeonboss/DungeonBossGame.js +++ b/src/games/dungeonboss/DungeonBossGame.js @@ -3450,8 +3450,11 @@ export default class DungeonBossGame extends Phaser.Scene { onUpdate: () => heroRec.cont.hpText.setText(`${Math.round(hpObj.v)}`), }); } - if (step.heroDies) this.time.delayedCall(480, () => this.removeHeroCard(uid, onDone)); - else this.time.delayedCall(480, onDone); + if (step.heroDies) { + 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); 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); const idx = ab.heroOrder.indexOf(uid); if (idx >= 0) ab.heroOrder.splice(idx, 1); - if (step.eliminated) this.showAdventureEliminatedBanner(this.seatName(ab.seat), onDone); - else onDone(); + this.showAdventureImpactText(`${this.seatName(ab.seat)} was wounded`, '#ff3b3b', () => { + 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(); }, + }); }, }); },