feat: animate AI chip placement in Craps

Adds a staggered slide-and-fade animation for AI bets in Craps, making chips appear to fly from each player's seat to the felt. Updates `renderAiBets` to accept an `animate` flag and triggers the effect only during the betting phase. Removes the call from `beginRound` to avoid redundant rendering.
This commit is contained in:
Brian Fertig 2026-05-21 00:04:21 -06:00
parent 73f50e2106
commit 327d3d7019
1 changed files with 24 additions and 8 deletions

View File

@ -523,7 +523,7 @@ export default class CrapsGame extends Phaser.Scene {
return { x, y: z.center.y + jitter.dy };
}
renderAiBets() {
renderAiBets(animate = false) {
for (const o of this.aiBetObjs) o.destroy();
this.aiBetObjs = [];
@ -546,27 +546,44 @@ export default class CrapsGame extends Phaser.Scene {
const base = this.boxChipPos(number, slot);
entries.forEach((e, idx) => {
const dx = n > 1 ? (idx - (n - 1) / 2) * 22 : 0;
const finalX = base.x + dx;
const finalY = base.y;
const label = `$${e.bet.amount}`;
const shortN = e.pi < this.gs.players.length
const shortN = this.gs.players[e.pi]
? (this.gs.players[e.pi].name.length > 6 ? this.gs.players[e.pi].name.slice(0, 5) + '…' : this.gs.players[e.pi].name)
: '';
this.aiBetObjs.push(this.drawAiChip(base.x + dx, base.y, e.pi, label, shortN));
const chip = this.drawAiChip(finalX, finalY, e.pi, label, shortN);
if (animate) this.animateChipFromSeat(chip, e.pi, finalX, finalY, idx);
this.aiBetObjs.push(chip);
});
} else {
const z = this.zones[key];
if (!z) continue;
entries.forEach((e, idx) => {
const { x, y } = this.chipSidePos(z, key, idx, n, e.pi);
const { x: finalX, y: finalY } = this.chipSidePos(z, key, idx, n, e.pi);
const label = `$${e.bet.amount}`;
const shortN = e.pi < this.gs.players.length
const shortN = this.gs.players[e.pi]
? (this.gs.players[e.pi].name.length > 6 ? this.gs.players[e.pi].name.slice(0, 5) + '…' : this.gs.players[e.pi].name)
: '';
this.aiBetObjs.push(this.drawAiChip(x, y, e.pi, label, shortN));
const chip = this.drawAiChip(finalX, finalY, e.pi, label, shortN);
if (animate) this.animateChipFromSeat(chip, e.pi, finalX, finalY, idx);
this.aiBetObjs.push(chip);
});
}
}
}
animateChipFromSeat(chip, pi, finalX, finalY, betIdx) {
const delay = (pi - 1) * 90 + betIdx * 35;
chip.setPosition(SEAT_X[pi] ?? CX, SEAT_Y).setAlpha(0).setScale(0.4);
if (betIdx === 0) this.time.delayedCall(delay, () => playChipBet(this));
this.tweens.add({
targets: chip, x: finalX, y: finalY,
alpha: 1, scaleX: 1, scaleY: 1,
duration: 400, ease: 'Quad.Out', delay,
});
}
updateBalances() {
const human = this.gs.players[0];
this.balanceText.setText(`Balance $${human.chips.toLocaleString()}`);
@ -641,7 +658,6 @@ export default class CrapsGame extends Phaser.Scene {
: `Come-out roll — ${this.gs.players[this.gs.shooterIndex].name} is shooting. Place your bets.`);
this.renderHumanBets();
this.renderAiWagers();
this.renderAiBets();
this.updateBalances();
this.refreshControls();
}
@ -655,7 +671,7 @@ export default class CrapsGame extends Phaser.Scene {
}
}
this.renderAiWagers();
this.renderAiBets();
this.renderAiBets(true);
}
onShoot() {