From 48f7ade2410c51752ed7139b16ab70970d202c74 Mon Sep 17 00:00:00 2001 From: Brian Fertig Date: Sat, 16 May 2026 16:14:46 -0600 Subject: [PATCH] refactor blackjack hit animation to use individual card rendering Refactors `animateSingleCard` to accept a specific card object instead of seat/index parameters, simplifying the logic for determining hand position and card index. Updates hit actions for both player and AI to animate the new card individually, revealing its face-up state at the destination upon completion. This replaces the previous bulk `renderSeatCards` call with a more granular visual update. --- public/src/games/blackjack/BlackjackGame.js | 76 +++++++++++++-------- 1 file changed, 48 insertions(+), 28 deletions(-) diff --git a/public/src/games/blackjack/BlackjackGame.js b/public/src/games/blackjack/BlackjackGame.js index 50c428f..438b1fe 100644 --- a/public/src/games/blackjack/BlackjackGame.js +++ b/public/src/games/blackjack/BlackjackGame.js @@ -624,15 +624,17 @@ export default class BlackjackGame extends Phaser.Scene { }); } - animateSingleCard(seat, isDealer, cardIdx, onComplete) { - const pos = isDealer ? { x: DEALER_X, y: DEALER_Y } : SEAT_POS[seat]; - const hand = isDealer ? this.gs.dealer.hand : this.gs.players[seat].hand; + animateSingleCard(seat, card, onComplete) { + const pos = SEAT_POS[seat]; + const p = this.gs.players[seat]; + const isH2 = p.activeHand === 1; + const hand = isH2 ? p.hand2 : p.hand; const total = hand.length; - const tx = isDealer - ? this.cardX(DEALER_X, cardIdx, total) - : this.cardX(pos.x, cardIdx, total); - const ty = isDealer ? DEALER_Y : pos.y; + const cardIdx = total - 1; + const tx = this.cardX(pos.x, cardIdx, total); + const ty = pos.y; + // Flying card-back const flying = this.add.container(CX + 200, 50).setDepth(D.cards + 10); this.addCardBackToContainer(flying); @@ -640,7 +642,13 @@ export default class BlackjackGame extends Phaser.Scene { targets: flying, x: tx, y: ty, duration: 200, ease: 'Power2', onComplete: () => { flying.destroy(); - this.renderSeatCards(seat); + // Reveal the card face-up at the destination + const cardConts = this.cardGraphics[seat] ?? []; + const targetCont = cardConts[cardIdx]; + if (targetCont) { + targetCont.setAlpha(1); + this.drawCard(targetCont, card, true); + } onComplete(); }, }); @@ -918,16 +926,22 @@ export default class BlackjackGame extends Phaser.Scene { this.hideActionButtons(); this.animating = true; this.gs = applyHit(this.gs, this.gs.currentSeat, this.shoe); - this.renderSeatCards(this.gs.currentSeat); - this.time.delayedCall(200, () => { - this.animating = false; - const p = this.gs.players[this.gs.currentSeat]; - if (isBust(p.activeHand === 1 ? p.hand2 : p.hand)) { - this.onPlayerBust(this.gs.currentSeat); - this.time.delayedCall(380, () => this.playerDone(this.gs.currentSeat)); - } else { - this.showActionButtons(); - } + const p = this.gs.players[this.gs.currentSeat]; + const newCard = p.activeHand === 1 + ? p.hand2[p.hand2.length - 1] + : p.hand[p.hand.length - 1]; + + this.animateSingleCard(this.gs.currentSeat, newCard, () => { + this.renderSeatCards(this.gs.currentSeat); + this.time.delayedCall(200, () => { + this.animating = false; + if (isBust(p.activeHand === 1 ? p.hand2 : p.hand)) { + this.onPlayerBust(this.gs.currentSeat); + this.time.delayedCall(380, () => this.playerDone(this.gs.currentSeat)); + } else { + this.showActionButtons(); + } + }); }); } @@ -1012,16 +1026,22 @@ export default class BlackjackGame extends Phaser.Scene { switch (action) { case 'hit': this.gs = applyHit(this.gs, seat, this.shoe); - this.renderSeatCards(seat); - this.time.delayedCall(400, () => { - this.animating = false; - const pp = this.gs.players[seat]; - if (isBust(pp.activeHand === 1 ? pp.hand2 : pp.hand)) { - this.onPlayerBust(seat); - this.time.delayedCall(400, () => this.playerDone(seat)); - } else { - this.time.delayedCall(600, () => this.runAITurn(seat)); - } + const pp = this.gs.players[seat]; + const aiNewCard = pp.activeHand === 1 + ? pp.hand2[pp.hand2.length - 1] + : pp.hand[pp.hand.length - 1]; + this.animateSingleCard(seat, aiNewCard, () => { + this.renderSeatCards(seat); + this.time.delayedCall(400, () => { + this.animating = false; + const pp2 = this.gs.players[seat]; + if (isBust(pp2.activeHand === 1 ? pp2.hand2 : pp2.hand)) { + this.onPlayerBust(seat); + this.time.delayedCall(400, () => this.playerDone(seat)); + } else { + this.time.delayedCall(600, () => this.runAITurn(seat)); + } + }); }); break; case 'double':