Additional Animations
This commit is contained in:
parent
53db492c83
commit
9469440122
|
|
@ -601,39 +601,164 @@ export default class GoFishGame extends Phaser.Scene {
|
|||
const after = applyAsk(before, targetSeat, rank);
|
||||
if (after === before) { this.animating = false; return; }
|
||||
const last = after.lastAsk;
|
||||
this.showBanner(this.formatAskBanner(last));
|
||||
playSound(this, last.result === 'catch' ? SFX.CARD_PLACE : SFX.CARD_DEAL);
|
||||
|
||||
this.gs = after;
|
||||
this.selectedRank = null;
|
||||
this.animateAsk(askerSeat, targetSeat, rank, last, before, () => {
|
||||
this.showBanner(this.formatAskBanner(last));
|
||||
playSound(this, last.result === 'catch' ? SFX.CARD_PLACE : SFX.CARD_DEAL);
|
||||
|
||||
for (let s = 0; s < this.gs.players.length; s++) {
|
||||
observeLog(this.aiMemory[s], this.gs, s);
|
||||
}
|
||||
this.gs = after;
|
||||
this.selectedRank = null;
|
||||
|
||||
if (last.newPairs > 0 && last.pairedCards?.length >= 2) {
|
||||
this.time.delayedCall(600, () => {
|
||||
this.hideBanner();
|
||||
this.renderAll();
|
||||
this.updateStatus();
|
||||
this.animatePairedCards(askerSeat, last.pairedCards, () => {
|
||||
for (let s = 0; s < this.gs.players.length; s++) {
|
||||
observeLog(this.aiMemory[s], this.gs, s);
|
||||
}
|
||||
|
||||
if (last.newPairs > 0 && last.pairedCards?.length >= 2) {
|
||||
this.time.delayedCall(600, () => {
|
||||
this.hideBanner();
|
||||
this.renderAll();
|
||||
this.updateStatus();
|
||||
this.animatePairedCards(askerSeat, last.pairedCards, () => {
|
||||
this.animating = false;
|
||||
if (isGameOver(this.gs)) { this.endGame(); return; }
|
||||
this.maybeStartAITurn();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.time.delayedCall(900, () => {
|
||||
this.renderAll();
|
||||
this.updateStatus();
|
||||
this.animating = false;
|
||||
if (isGameOver(this.gs)) { this.endGame(); return; }
|
||||
this.hideBanner();
|
||||
this.maybeStartAITurn();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
animateAsk(askerSeat, targetSeat, rank, last, beforeState, onComplete) {
|
||||
const askerSlot = this.slotForSeat[askerSeat];
|
||||
const askerLayout = slotLayout(askerSlot);
|
||||
const askerShow = this.slotShowPos(askerSlot, askerLayout);
|
||||
|
||||
const askerCard = beforeState.players[askerSeat].hand.find(c => c.rank === rank);
|
||||
if (!askerCard) { onComplete(); return; }
|
||||
|
||||
const askerSprite = this.makeCardSprite(askerCard, askerLayout.handCenter.x, askerLayout.handCenter.y, {
|
||||
faceUp: false, rotation: 0,
|
||||
});
|
||||
askerSprite.setDepth(D.banner - 4);
|
||||
this.transientObjs.push(askerSprite);
|
||||
|
||||
this.tweens.add({
|
||||
targets: askerSprite,
|
||||
x: askerShow.x, y: askerShow.y,
|
||||
duration: 280,
|
||||
ease: 'Cubic.easeOut',
|
||||
onComplete: () => this.flipCardFaceUp(askerSprite, askerCard),
|
||||
});
|
||||
|
||||
if (last.result === 'catch') {
|
||||
const targetSlot = this.slotForSeat[targetSeat];
|
||||
const targetLayout = slotLayout(targetSlot);
|
||||
const targetShow = this.slotShowPos(targetSlot, targetLayout);
|
||||
const n = last.cardsTransferred.length;
|
||||
|
||||
this.time.delayedCall(640, () => {
|
||||
const isTargetVert = targetSlot === 'left' || targetSlot === 'right';
|
||||
const targetSprites = last.cardsTransferred.map((card, i) => {
|
||||
const tx = isTargetVert ? targetShow.x
|
||||
: targetShow.x + (i - (n - 1) / 2) * (CARD_W + 8);
|
||||
const ty = isTargetVert ? targetShow.y + (i - (n - 1) / 2) * (CARD_H + 8)
|
||||
: targetShow.y;
|
||||
|
||||
const sprite = this.makeCardSprite(card, targetLayout.handCenter.x, targetLayout.handCenter.y, {
|
||||
faceUp: false, rotation: 0,
|
||||
});
|
||||
sprite.setDepth(D.banner - 4);
|
||||
this.transientObjs.push(sprite);
|
||||
|
||||
this.tweens.add({
|
||||
targets: sprite,
|
||||
x: tx, y: ty,
|
||||
duration: 250,
|
||||
delay: i * 80,
|
||||
ease: 'Cubic.easeOut',
|
||||
onComplete: () => this.flipCardFaceUp(sprite, card),
|
||||
});
|
||||
|
||||
return { sprite, tx, ty };
|
||||
});
|
||||
|
||||
const waitMs = 250 + (n - 1) * 80 + 380;
|
||||
this.time.delayedCall(waitMs, () => {
|
||||
if (askerSprite.active) {
|
||||
this.tweens.add({
|
||||
targets: askerSprite, alpha: 0, duration: 200,
|
||||
onComplete: () => { if (askerSprite.active) askerSprite.destroy(); },
|
||||
});
|
||||
}
|
||||
for (const { sprite } of targetSprites) {
|
||||
if (!sprite.active) continue;
|
||||
this.tweens.add({
|
||||
targets: sprite,
|
||||
x: askerLayout.handCenter.x, y: askerLayout.handCenter.y,
|
||||
alpha: 0, duration: 380, ease: 'Cubic.easeIn',
|
||||
onComplete: () => { if (sprite.active) sprite.destroy(); },
|
||||
});
|
||||
}
|
||||
this.time.delayedCall(420, onComplete);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.time.delayedCall(900, () => {
|
||||
this.renderAll();
|
||||
this.updateStatus();
|
||||
this.animating = false;
|
||||
if (isGameOver(this.gs)) { this.endGame(); return; }
|
||||
this.hideBanner();
|
||||
this.maybeStartAITurn();
|
||||
this.time.delayedCall(880, () => {
|
||||
this.flipCardFaceDown(askerSprite);
|
||||
this.time.delayedCall(340, () => {
|
||||
this.tweens.add({
|
||||
targets: askerSprite,
|
||||
x: askerLayout.handCenter.x, y: askerLayout.handCenter.y,
|
||||
duration: 280, ease: 'Cubic.easeIn',
|
||||
onComplete: () => { if (askerSprite.active) askerSprite.destroy(); },
|
||||
});
|
||||
this.time.delayedCall(320, onComplete);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
slotShowPos(slot, layout) {
|
||||
const GAP = 10;
|
||||
switch (slot) {
|
||||
case 'bottom': return { x: layout.handCenter.x, y: layout.handCenter.y - CARD_H / 2 - GAP - CARD_H / 2 };
|
||||
case 'top': return { x: layout.handCenter.x, y: layout.handCenter.y + CARD_H / 2 + GAP + CARD_H / 2 };
|
||||
case 'left': return { x: layout.handCenter.x + CARD_H / 2 + GAP + CARD_W / 2, y: layout.handCenter.y };
|
||||
case 'right': return { x: layout.handCenter.x - CARD_H / 2 - GAP - CARD_W / 2, y: layout.handCenter.y };
|
||||
default: return { x: CX, y: CY };
|
||||
}
|
||||
}
|
||||
|
||||
flipCardFaceUp(container, card) {
|
||||
this.tweens.add({
|
||||
targets: container, scaleX: 0, duration: 150, ease: 'Linear',
|
||||
onComplete: () => {
|
||||
container.setRotation(0);
|
||||
this.renderCardFace(container, card, true);
|
||||
this.tweens.add({ targets: container, scaleX: 1, duration: 150, ease: 'Linear' });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
flipCardFaceDown(container) {
|
||||
this.tweens.add({
|
||||
targets: container, scaleX: 0, duration: 150, ease: 'Linear',
|
||||
onComplete: () => {
|
||||
this.renderCardFace(container, container.card, false);
|
||||
this.tweens.add({ targets: container, scaleX: 1, duration: 150, ease: 'Linear' });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
animatePairedCards(askerSeat, pairedCards, onComplete) {
|
||||
const slot = this.slotForSeat[askerSeat];
|
||||
const layout = slotLayout(slot);
|
||||
|
|
|
|||
Loading…
Reference in New Issue