**feat(triominoes): animate drawn tiles from pool to player portrait**
Add `animateDrawTile()` to tween a face-down triangle from the pool area to the drawing player's portrait over 1.2 seconds. Integrates the animation into both the human draw flow (`onPoolClick`) and the AI draw loop (`runAITurn`), ensuring visual feedback before the game state updates and the hand refreshes.
This commit is contained in:
parent
a231d821ca
commit
74d5470d11
|
|
@ -527,6 +527,49 @@ export default class TriominoesGame extends Phaser.Scene {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─── Draw animation ─────────────────────────────────────────────────────
|
||||||
|
// Animate a face-down triangle from the pool to the player's portrait.
|
||||||
|
// Returns a promise that resolves when the animation completes.
|
||||||
|
animateDrawTile(seat) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const portrait = this.portraitCtrls[seat];
|
||||||
|
if (!portrait) { resolve(); return; }
|
||||||
|
const px = portrait.x;
|
||||||
|
const py = portrait.y;
|
||||||
|
const poolX = POOL_X;
|
||||||
|
const poolY = POOL_Y;
|
||||||
|
|
||||||
|
const size = HAND_BASE * 0.45;
|
||||||
|
const h = Math.round(size * 0.8660254);
|
||||||
|
const triPts = [[0, -h * 2 / 3], [size / 2, h / 3], [-size / 2, h / 3]];
|
||||||
|
|
||||||
|
const container = this.add.container(poolX, poolY).setDepth(DEPTH.drag);
|
||||||
|
const gfx = this.add.graphics();
|
||||||
|
// Face-down: dark fill, subtle border, small center dot.
|
||||||
|
gfx.fillStyle(COLORS.panel, 1);
|
||||||
|
gfx.fillTriangle(triPts[0][0], triPts[0][1], triPts[1][0], triPts[1][1], triPts[2][0], triPts[2][1]);
|
||||||
|
gfx.lineStyle(2, COLORS.accent, 0.9);
|
||||||
|
gfx.strokeTriangle(triPts[0][0], triPts[0][1], triPts[1][0], triPts[1][1], triPts[2][0], triPts[2][1]);
|
||||||
|
gfx.fillStyle(COLORS.accent, 0.35);
|
||||||
|
gfx.fillCircle(0, 0, Math.max(3, size * 0.06));
|
||||||
|
container.add(gfx);
|
||||||
|
|
||||||
|
container.setScale(1).setAngle(0);
|
||||||
|
|
||||||
|
this.tweens.add({
|
||||||
|
targets: container,
|
||||||
|
x: px,
|
||||||
|
y: py,
|
||||||
|
duration: 1200,
|
||||||
|
ease: 'Cubic.easeInOut',
|
||||||
|
onComplete: () => {
|
||||||
|
container.destroy();
|
||||||
|
resolve();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ─── AI tile animation ──────────────────────────────────────────────────
|
// ─── AI tile animation ──────────────────────────────────────────────────
|
||||||
// Create a small triangle at the opponent's portrait and tween it to the
|
// Create a small triangle at the opponent's portrait and tween it to the
|
||||||
// board cell over 1.2 s, rotating and scaling as it goes. Returns a promise
|
// board cell over 1.2 s, rotating and scaling as it goes. Returns a promise
|
||||||
|
|
@ -625,10 +668,13 @@ export default class TriominoesGame extends Phaser.Scene {
|
||||||
if (!this._poolActive) return;
|
if (!this._poolActive) return;
|
||||||
this.showPoolClickable(false);
|
this.showPoolClickable(false);
|
||||||
playSound(this, SFX.CARD_DEAL);
|
playSound(this, SFX.CARD_DEAL);
|
||||||
|
// Animate tile from pool → player's portrait.
|
||||||
|
this.animateDrawTile(0).then(() => {
|
||||||
this.gs = drawTile(this.gs);
|
this.gs = drawTile(this.gs);
|
||||||
this.refresh();
|
this.refresh();
|
||||||
// Re-evaluate: a drawn tile may now be playable.
|
// Re-evaluate: a drawn tile may now be playable.
|
||||||
this.time.delayedCall(260, () => this.beginHumanTurn());
|
this.time.delayedCall(260, () => this.beginHumanTurn());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
showPoolClickable(on) {
|
showPoolClickable(on) {
|
||||||
|
|
@ -656,6 +702,7 @@ export default class TriominoesGame extends Phaser.Scene {
|
||||||
if (canDraw(this.gs) && this.gs.players[seat].draws < MAX_DRAWS) {
|
if (canDraw(this.gs) && this.gs.players[seat].draws < MAX_DRAWS) {
|
||||||
await this.delay(360);
|
await this.delay(360);
|
||||||
playSound(this, SFX.CARD_DEAL);
|
playSound(this, SFX.CARD_DEAL);
|
||||||
|
await this.animateDrawTile(seat);
|
||||||
this.gs = drawTile(this.gs);
|
this.gs = drawTile(this.gs);
|
||||||
this.refresh();
|
this.refresh();
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue