feat: overhaul player turn order and add action callouts
- Replace left-to-right seat processing with clockwise PLAY_ORDER starting top-right - Animate deal sequence to follow the new play order - Add pulsing highlight ring for active player's portrait - Show large animated action callouts (Hit/Stand/Double/Split) between player and cards - Position action buttons dynamically relative to the active player's portrait - Update result reveal order to match clockwise play order - Move betting UI panel and adjust button depths for proper layering - Remove unused `nextActiveSeat` import in favor of `nextPlaySeat` method
This commit is contained in:
parent
349d2736c9
commit
02d10faa2d
|
|
@ -10,7 +10,7 @@ import {
|
||||||
buildShoe, handValue, isBlackjack, isBust, canDouble, canSplit,
|
buildShoe, handValue, isBlackjack, isBust, canDouble, canSplit,
|
||||||
createInitialState, prepareRound, applyBet, dealAllCards,
|
createInitialState, prepareRound, applyBet, dealAllCards,
|
||||||
applyInsurance, resolveInsurance, applyHit, applyStand, applyDouble, applySplit,
|
applyInsurance, resolveInsurance, applyHit, applyStand, applyDouble, applySplit,
|
||||||
runDealerTurn, resolveRound, nextActiveSeat, isPlayerDone,
|
runDealerTurn, resolveRound, isPlayerDone,
|
||||||
} from './BlackjackLogic.js';
|
} from './BlackjackLogic.js';
|
||||||
import { chooseBet, chooseAction, chooseInsurance } from './BlackjackAI.js';
|
import { chooseBet, chooseAction, chooseInsurance } from './BlackjackAI.js';
|
||||||
|
|
||||||
|
|
@ -28,15 +28,22 @@ const DEALER_Y = 420; // ~1/3 down the table ellipse (top ≈190, bottom ≈890)
|
||||||
// 6 opponents fanned 3-per-side (filled outward-alternating so the table stays
|
// 6 opponents fanned 3-per-side (filled outward-alternating so the table stays
|
||||||
// balanced when fewer than 6 opponents are chosen).
|
// balanced when fewer than 6 opponents are chosen).
|
||||||
const SEAT_POS = [
|
const SEAT_POS = [
|
||||||
{ x: CX, y: 860, portraitR: 72, portraitX: CX - 230, portraitY: 860, betX: 1110, betY: 770 }, // 0 Human (bottom centre)
|
{ x: CX, y: 782, portraitR: 72, portraitX: CX - 230, portraitY: 860, betX: 1110, betY: 770 }, // 0 Human (bottom centre)
|
||||||
{ x: 1490, y: 745, portraitR: 58, portraitX: 1600, portraitY: 800 }, // 1 right-bottom
|
{ x: 1380, y: 710, portraitR: 58, portraitX: 1600, portraitY: 800 }, // 1 right-bottom
|
||||||
{ x: 430, y: 745, portraitR: 58, portraitX: 320, portraitY: 800 }, // 2 left-bottom
|
{ x: 540, y: 710, portraitR: 58, portraitX: 320, portraitY: 800 }, // 2 left-bottom
|
||||||
{ x: 1670, y: 595, portraitR: 58, portraitX: 1805, portraitY: 610 }, // 3 right-mid
|
{ x: 1560, y: 588, portraitR: 58, portraitX: 1805, portraitY: 610 }, // 3 right-mid
|
||||||
{ x: 250, y: 595, portraitR: 58, portraitX: 115, portraitY: 610 }, // 4 left-mid
|
{ x: 360, y: 588, portraitR: 58, portraitX: 115, portraitY: 610 }, // 4 left-mid
|
||||||
{ x: 1585, y: 375, portraitR: 58, portraitX: 1705, portraitY: 335, labelDX: 10 }, // 5 right-top
|
{ x: 1470, y: 410, portraitR: 58, portraitX: 1705, portraitY: 335, labelDX: 10 }, // 5 right-top
|
||||||
{ x: 335, y: 375, portraitR: 58, portraitX: 215, portraitY: 335, labelDX: -10 }, // 6 left-top
|
{ x: 450, y: 410, portraitR: 58, portraitX: 215, portraitY: 335, labelDX: -10 }, // 6 left-top
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Turn order: start at the top-right seat and proceed clockwise around the table.
|
||||||
|
const PLAY_ORDER = [5, 3, 1, 0, 2, 4, 6];
|
||||||
|
|
||||||
|
// Large per-action callout shown between a player and their cards.
|
||||||
|
const ACTION_LABELS = { hit: 'Hit', stand: 'Stand', double: 'Double', split: 'Split' };
|
||||||
|
const ACTION_COLORS = { hit: '#3cc6c0', stand: '#f5d020', double: '#ff8c00', split: '#b07cd6' };
|
||||||
|
|
||||||
const CHIP_COLORS = { 5: 0xe05c5c, 25: 0x5cb85c, 50: 0x4a90d9, 100: 0x2c2c2c };
|
const CHIP_COLORS = { 5: 0xe05c5c, 25: 0x5cb85c, 50: 0x4a90d9, 100: 0x2c2c2c };
|
||||||
const CHIP_TEXT_COLORS = { 5: '#ffffff', 25: '#ffffff', 50: '#ffffff', 100: '#ffffff' };
|
const CHIP_TEXT_COLORS = { 5: '#ffffff', 25: '#ffffff', 50: '#ffffff', 100: '#ffffff' };
|
||||||
const CHIP_AMOUNTS = [5, 25, 50, 100];
|
const CHIP_AMOUNTS = [5, 25, 50, 100];
|
||||||
|
|
@ -253,6 +260,14 @@ export default class BlackjackGame extends Phaser.Scene {
|
||||||
const y = GAME_HEIGHT - 80;
|
const y = GAME_HEIGHT - 80;
|
||||||
const cx = CX + 60; // shift right slightly to avoid portrait
|
const cx = CX + 60; // shift right slightly to avoid portrait
|
||||||
|
|
||||||
|
// Solid window behind all the betting controls (shown between rounds)
|
||||||
|
const panel = this.add.graphics().setDepth(D.ui);
|
||||||
|
panel.fillStyle(0x000000, 1);
|
||||||
|
panel.fillRoundedRect(cx - 174, y - 69, 726, 116, 18);
|
||||||
|
panel.lineStyle(3, COLORS.accent, 1);
|
||||||
|
panel.strokeRoundedRect(cx - 174, y - 69, 726, 116, 18);
|
||||||
|
this.bettingUIGroup.push(panel);
|
||||||
|
|
||||||
// Chip buttons
|
// Chip buttons
|
||||||
CHIP_AMOUNTS.forEach((amt, i) => {
|
CHIP_AMOUNTS.forEach((amt, i) => {
|
||||||
const bx = cx - 120 + i * 80;
|
const bx = cx - 120 + i * 80;
|
||||||
|
|
@ -292,6 +307,9 @@ export default class BlackjackGame extends Phaser.Scene {
|
||||||
width: 110, height: 50, fontSize: 20,
|
width: 110, height: 50, fontSize: 20,
|
||||||
});
|
});
|
||||||
this.dealBtn.setEnabled(false);
|
this.dealBtn.setEnabled(false);
|
||||||
|
// Keep the buttons above the betting window panel
|
||||||
|
clearBtn.setDepth(D.ui + 1);
|
||||||
|
this.dealBtn.setDepth(D.ui + 1);
|
||||||
|
|
||||||
this.bettingUIGroup.push(this.betDisplayText, this.balanceText, clearBtn, this.dealBtn);
|
this.bettingUIGroup.push(this.betDisplayText, this.balanceText, clearBtn, this.dealBtn);
|
||||||
this.hideBettingUI();
|
this.hideBettingUI();
|
||||||
|
|
@ -451,6 +469,7 @@ export default class BlackjackGame extends Phaser.Scene {
|
||||||
this.bustedSeats = new Set();
|
this.bustedSeats = new Set();
|
||||||
this.gs = prepareRound(this.gs);
|
this.gs = prepareRound(this.gs);
|
||||||
this.clearCardGraphics();
|
this.clearCardGraphics();
|
||||||
|
this.clearActiveHighlight();
|
||||||
this.renderAll();
|
this.renderAll();
|
||||||
this.showBettingUI();
|
this.showBettingUI();
|
||||||
this.updateBetDisplay();
|
this.updateBetDisplay();
|
||||||
|
|
@ -735,12 +754,13 @@ export default class BlackjackGame extends Phaser.Scene {
|
||||||
}
|
}
|
||||||
|
|
||||||
animateDeal(onComplete) {
|
animateDeal(onComplete) {
|
||||||
// Build deal order: player0-c1, p1-c1, ..., dealer-upcard, p0-c2, p1-c2, ..., dealer-hole
|
// Deal in play order (top-right, clockwise): each player card 1, dealer upcard,
|
||||||
const activePlayers = this.gs.players.filter(p => p.active);
|
// each player card 2, dealer hole.
|
||||||
|
const seats = PLAY_ORDER.filter(seat => this.gs.players[seat]?.active);
|
||||||
const dealSeq = [];
|
const dealSeq = [];
|
||||||
for (const p of activePlayers) dealSeq.push({ type: 'player', seat: p.seat, cardIdx: 0 });
|
for (const seat of seats) dealSeq.push({ type: 'player', seat, cardIdx: 0 });
|
||||||
dealSeq.push({ type: 'dealer', cardIdx: 0 }); // upcard
|
dealSeq.push({ type: 'dealer', cardIdx: 0 }); // upcard
|
||||||
for (const p of activePlayers) dealSeq.push({ type: 'player', seat: p.seat, cardIdx: 1 });
|
for (const seat of seats) dealSeq.push({ type: 'player', seat, cardIdx: 1 });
|
||||||
dealSeq.push({ type: 'dealer', cardIdx: 1 }); // hole card
|
dealSeq.push({ type: 'dealer', cardIdx: 1 }); // hole card
|
||||||
|
|
||||||
// Hide all cards initially
|
// Hide all cards initially
|
||||||
|
|
@ -829,8 +849,8 @@ export default class BlackjackGame extends Phaser.Scene {
|
||||||
const tx = this.cardX(pos.x, cardIdx, total);
|
const tx = this.cardX(pos.x, cardIdx, total);
|
||||||
const ty = pos.y;
|
const ty = pos.y;
|
||||||
|
|
||||||
// Flying card-back
|
// Flying card-back dealt from the dealer's area
|
||||||
const flying = this.add.container(CX + 200, 50).setDepth(D.cards + 10);
|
const flying = this.add.container(DEALER_X, DEALER_Y).setDepth(D.cards + 10);
|
||||||
this.addCardBackToContainer(flying);
|
this.addCardBackToContainer(flying);
|
||||||
|
|
||||||
this.tweens.add({
|
this.tweens.add({
|
||||||
|
|
@ -850,6 +870,67 @@ export default class BlackjackGame extends Phaser.Scene {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Per-turn action callout ──────────────────────────────────────────────
|
||||||
|
// Large colored word (Hit/Stand/Double/Split) shown between the player and
|
||||||
|
// their cards; lingers >= 1s before fading. Fire-and-forget (no flow gating).
|
||||||
|
animateActionText(seat, action) {
|
||||||
|
const label = ACTION_LABELS[action];
|
||||||
|
if (!label) return;
|
||||||
|
const pos = SEAT_POS[seat];
|
||||||
|
const px = pos.portraitX ?? pos.x;
|
||||||
|
const py = pos.portraitY ?? pos.y;
|
||||||
|
const tx = (px + pos.x) / 2;
|
||||||
|
const ty = (py + pos.y) / 2;
|
||||||
|
|
||||||
|
const txt = this.add.text(tx, ty, label, {
|
||||||
|
fontFamily: '"Julius Sans One"',
|
||||||
|
fontSize: '44px',
|
||||||
|
color: ACTION_COLORS[action] ?? '#ffffff',
|
||||||
|
fontStyle: 'bold',
|
||||||
|
stroke: '#000000', strokeThickness: 5,
|
||||||
|
}).setOrigin(0.5).setAlpha(0).setScale(1.4).setDepth(D.modal);
|
||||||
|
|
||||||
|
this.tweens.add({
|
||||||
|
targets: txt, alpha: 1, scaleX: 1, scaleY: 1,
|
||||||
|
duration: 180, ease: 'Back.Out',
|
||||||
|
});
|
||||||
|
this.time.delayedCall(1000, () => {
|
||||||
|
this.tweens.add({
|
||||||
|
targets: txt, alpha: 0, y: ty - 26,
|
||||||
|
duration: 350, ease: 'Power2',
|
||||||
|
onComplete: () => txt.destroy(),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Active-player turn highlight (pulsing ring around the portrait) ────────
|
||||||
|
highlightActiveSeat(seat) {
|
||||||
|
const pos = SEAT_POS[seat];
|
||||||
|
const px = pos.portraitX ?? pos.x;
|
||||||
|
const py = pos.portraitY ?? pos.y;
|
||||||
|
|
||||||
|
if (!this.activeRing) {
|
||||||
|
this.activeRing = this.add.graphics().setDepth(D.ui - 1);
|
||||||
|
}
|
||||||
|
this.activeRing.clear();
|
||||||
|
this.activeRing.lineStyle(5, COLORS.accent, 0.9);
|
||||||
|
this.activeRing.strokeCircle(0, 0, pos.portraitR + 8);
|
||||||
|
this.activeRing.setPosition(px, py).setVisible(true).setScale(1).setAlpha(1);
|
||||||
|
|
||||||
|
this.activeRingTween?.stop();
|
||||||
|
this.activeRingTween = this.tweens.add({
|
||||||
|
targets: this.activeRing,
|
||||||
|
scaleX: 1.12, scaleY: 1.12, alpha: 0.45,
|
||||||
|
duration: 650, ease: 'Sine.easeInOut', yoyo: true, repeat: -1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
clearActiveHighlight() {
|
||||||
|
this.activeRingTween?.stop();
|
||||||
|
this.activeRingTween = null;
|
||||||
|
if (this.activeRing) this.activeRing.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
// ── Per-seat result animation (text + chips + fireworks) ─────────────────
|
// ── Per-seat result animation (text + chips + fireworks) ─────────────────
|
||||||
animateSeatResult(seat, onComplete) {
|
animateSeatResult(seat, onComplete) {
|
||||||
const p = this.gs.players[seat];
|
const p = this.gs.players[seat];
|
||||||
|
|
@ -1054,14 +1135,29 @@ export default class BlackjackGame extends Phaser.Scene {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Player turns ──────────────────────────────────────────────────────────
|
// ── Player turns ──────────────────────────────────────────────────────────
|
||||||
|
// First seat to act, walking PLAY_ORDER (clockwise from top-right).
|
||||||
|
firstPlaySeat() {
|
||||||
|
for (const seat of PLAY_ORDER) {
|
||||||
|
if (this.gs.players[seat]?.active) return seat;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next seat in PLAY_ORDER after the current one that still needs to act.
|
||||||
|
nextPlaySeat() {
|
||||||
|
const start = PLAY_ORDER.indexOf(this.gs.currentSeat);
|
||||||
|
for (let i = start + 1; i < PLAY_ORDER.length; i++) {
|
||||||
|
const p = this.gs.players[PLAY_ORDER[i]];
|
||||||
|
if (p?.active && (p.status === 'playing' || p.status === 'waiting')) return PLAY_ORDER[i];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
startPlayerTurns() {
|
startPlayerTurns() {
|
||||||
this.gs = { ...this.gs, phase: 'player_turn' };
|
this.gs = { ...this.gs, phase: 'player_turn' };
|
||||||
// Mark first active player as 'playing'
|
const seat = this.firstPlaySeat();
|
||||||
const p = this.gs.players.find(pl => pl.active);
|
this.gs = { ...this.gs, currentSeat: seat };
|
||||||
if (p) {
|
this.advanceToPlayer(seat);
|
||||||
this.gs = { ...this.gs, currentSeat: p.seat };
|
|
||||||
}
|
|
||||||
this.advanceToPlayer(p?.seat ?? 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
advanceToPlayer(seat) {
|
advanceToPlayer(seat) {
|
||||||
|
|
@ -1071,13 +1167,14 @@ export default class BlackjackGame extends Phaser.Scene {
|
||||||
|
|
||||||
// Skip if already determined (blackjack on deal)
|
// Skip if already determined (blackjack on deal)
|
||||||
if (isPlayerDone(p)) {
|
if (isPlayerDone(p)) {
|
||||||
const next = nextActiveSeat(this.gs);
|
const next = this.nextPlaySeat();
|
||||||
if (next === null) { this.startDealerTurn(); return; }
|
if (next === null) { this.startDealerTurn(); return; }
|
||||||
this.gs = { ...this.gs, currentSeat: next };
|
this.gs = { ...this.gs, currentSeat: next };
|
||||||
this.advanceToPlayer(next);
|
this.advanceToPlayer(next);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.highlightActiveSeat(seat);
|
||||||
if (p.isHuman) {
|
if (p.isHuman) {
|
||||||
this.showActionButtons();
|
this.showActionButtons();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1090,17 +1187,21 @@ export default class BlackjackGame extends Phaser.Scene {
|
||||||
const seat = this.gs.currentSeat;
|
const seat = this.gs.currentSeat;
|
||||||
const p = this.gs.players[seat];
|
const p = this.gs.players[seat];
|
||||||
const pos = SEAT_POS[seat];
|
const pos = SEAT_POS[seat];
|
||||||
const by = GAME_HEIGHT - 80;
|
const by = 918; // just under the table felt
|
||||||
|
let bx = pos.portraitX + pos.portraitR + 80; // first button, just right of the portrait
|
||||||
|
|
||||||
const btns = [
|
const btns = [
|
||||||
new Button(this, CX - 180, by, 'Hit', () => this.onHit(), { width: 120, height: 52, fontSize: 20 }),
|
new Button(this, bx, by, 'Hit', () => this.onHit(), { width: 120, height: 52, fontSize: 20 }),
|
||||||
new Button(this, CX - 50, by, 'Stand', () => this.onStand(), { width: 120, height: 52, fontSize: 20 }),
|
|
||||||
];
|
];
|
||||||
|
bx += 130;
|
||||||
|
btns.push(new Button(this, bx, by, 'Stand', () => this.onStand(), { width: 120, height: 52, fontSize: 20 }));
|
||||||
if (canDouble(p)) {
|
if (canDouble(p)) {
|
||||||
btns.push(new Button(this, CX + 80, by, 'Double', () => this.onDouble(), { width: 130, height: 52, fontSize: 20 }));
|
bx += 130;
|
||||||
|
btns.push(new Button(this, bx, by, 'Double', () => this.onDouble(), { width: 130, height: 52, fontSize: 20 }));
|
||||||
}
|
}
|
||||||
if (canSplit(p) && p.chips >= p.bet) {
|
if (canSplit(p) && p.chips >= p.bet) {
|
||||||
btns.push(new Button(this, CX + 220, by, 'Split', () => this.onSplit(), { width: 120, height: 52, fontSize: 20 }));
|
bx += 140;
|
||||||
|
btns.push(new Button(this, bx, by, 'Split', () => this.onSplit(), { width: 120, height: 52, fontSize: 20 }));
|
||||||
}
|
}
|
||||||
btns.forEach(btn => btn.setDepth(D.ui + 5));
|
btns.forEach(btn => btn.setDepth(D.ui + 5));
|
||||||
this.actionBtns = btns;
|
this.actionBtns = btns;
|
||||||
|
|
@ -1127,6 +1228,7 @@ export default class BlackjackGame extends Phaser.Scene {
|
||||||
|
|
||||||
onHit() {
|
onHit() {
|
||||||
this.hideActionButtons();
|
this.hideActionButtons();
|
||||||
|
this.animateActionText(this.gs.currentSeat, 'hit');
|
||||||
this.animating = true;
|
this.animating = true;
|
||||||
this.gs = applyHit(this.gs, this.gs.currentSeat, this.shoe);
|
this.gs = applyHit(this.gs, this.gs.currentSeat, this.shoe);
|
||||||
const p = this.gs.players[this.gs.currentSeat];
|
const p = this.gs.players[this.gs.currentSeat];
|
||||||
|
|
@ -1151,6 +1253,7 @@ export default class BlackjackGame extends Phaser.Scene {
|
||||||
onStand() {
|
onStand() {
|
||||||
this.hideActionButtons();
|
this.hideActionButtons();
|
||||||
const seat = this.gs.currentSeat;
|
const seat = this.gs.currentSeat;
|
||||||
|
this.animateActionText(seat, 'stand');
|
||||||
this.gs = applyStand(this.gs, seat);
|
this.gs = applyStand(this.gs, seat);
|
||||||
const p = this.gs.players[seat];
|
const p = this.gs.players[seat];
|
||||||
// If split and now playing hand 2, stay on same seat
|
// If split and now playing hand 2, stay on same seat
|
||||||
|
|
@ -1163,6 +1266,7 @@ export default class BlackjackGame extends Phaser.Scene {
|
||||||
|
|
||||||
onDouble() {
|
onDouble() {
|
||||||
this.hideActionButtons();
|
this.hideActionButtons();
|
||||||
|
this.animateActionText(this.gs.currentSeat, 'double');
|
||||||
this.animating = true;
|
this.animating = true;
|
||||||
this.gs = applyDouble(this.gs, this.gs.currentSeat, this.shoe);
|
this.gs = applyDouble(this.gs, this.gs.currentSeat, this.shoe);
|
||||||
this.renderSeatCards(this.gs.currentSeat);
|
this.renderSeatCards(this.gs.currentSeat);
|
||||||
|
|
@ -1181,6 +1285,7 @@ export default class BlackjackGame extends Phaser.Scene {
|
||||||
|
|
||||||
onSplit() {
|
onSplit() {
|
||||||
this.hideActionButtons();
|
this.hideActionButtons();
|
||||||
|
this.animateActionText(this.gs.currentSeat, 'split');
|
||||||
this.animating = true;
|
this.animating = true;
|
||||||
this.gs = applySplit(this.gs, this.gs.currentSeat, this.shoe);
|
this.gs = applySplit(this.gs, this.gs.currentSeat, this.shoe);
|
||||||
this.renderSeatCards(this.gs.currentSeat);
|
this.renderSeatCards(this.gs.currentSeat);
|
||||||
|
|
@ -1205,7 +1310,7 @@ export default class BlackjackGame extends Phaser.Scene {
|
||||||
this.showActionButtons();
|
this.showActionButtons();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const next = nextActiveSeat(this.gs);
|
const next = this.nextPlaySeat();
|
||||||
if (next === null) {
|
if (next === null) {
|
||||||
this.startDealerTurn();
|
this.startDealerTurn();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1223,6 +1328,7 @@ export default class BlackjackGame extends Phaser.Scene {
|
||||||
}
|
}
|
||||||
|
|
||||||
const action = chooseAction(p, this.gs.dealer.hand[0]);
|
const action = chooseAction(p, this.gs.dealer.hand[0]);
|
||||||
|
this.animateActionText(seat, action);
|
||||||
this.animating = true;
|
this.animating = true;
|
||||||
|
|
||||||
const doAction = () => {
|
const doAction = () => {
|
||||||
|
|
@ -1293,6 +1399,7 @@ export default class BlackjackGame extends Phaser.Scene {
|
||||||
|
|
||||||
// ── Dealer turn ───────────────────────────────────────────────────────────
|
// ── Dealer turn ───────────────────────────────────────────────────────────
|
||||||
startDealerTurn() {
|
startDealerTurn() {
|
||||||
|
this.clearActiveHighlight();
|
||||||
this.gs = { ...this.gs, phase: 'dealer_turn', currentSeat: -1 };
|
this.gs = { ...this.gs, phase: 'dealer_turn', currentSeat: -1 };
|
||||||
this.renderAll();
|
this.renderAll();
|
||||||
this.time.delayedCall(400, () => {
|
this.time.delayedCall(400, () => {
|
||||||
|
|
@ -1325,17 +1432,15 @@ export default class BlackjackGame extends Phaser.Scene {
|
||||||
}
|
}
|
||||||
|
|
||||||
showAllResults(onComplete) {
|
showAllResults(onComplete) {
|
||||||
const active = this.gs.players.filter(p => p.active);
|
// Reveal top-right then clockwise around the table (PLAY_ORDER).
|
||||||
if (active.length === 0) { onComplete(); return; }
|
const seats = PLAY_ORDER.filter(seat => this.gs.players[seat]?.active);
|
||||||
|
if (seats.length === 0) { onComplete(); return; }
|
||||||
|
|
||||||
// Reveal right-to-left (descending seat x position)
|
let pending = seats.length;
|
||||||
const sorted = [...active].sort((a, b) => SEAT_POS[b.seat].x - SEAT_POS[a.seat].x);
|
|
||||||
|
|
||||||
let pending = sorted.length;
|
|
||||||
const done = () => { if (--pending <= 0) onComplete(); };
|
const done = () => { if (--pending <= 0) onComplete(); };
|
||||||
|
|
||||||
sorted.forEach((p, i) => {
|
seats.forEach((seat, i) => {
|
||||||
this.time.delayedCall(i * 480, () => this.animateSeatResult(p.seat, done));
|
this.time.delayedCall(i * 480, () => this.animateSeatResult(seat, done));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1360,7 +1465,7 @@ export default class BlackjackGame extends Phaser.Scene {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const btn = new Button(this, CX, GAME_HEIGHT / 2 + 40, 'Next Round', () => {
|
const btn = new Button(this, CX, 925, 'Next Round', () => {
|
||||||
btn.destroy();
|
btn.destroy();
|
||||||
this.startNewRound();
|
this.startNewRound();
|
||||||
}, { width: 220, height: 60, fontSize: 24 });
|
}, { width: 220, height: 60, fontSize: 24 });
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue