feat(phase10): add character voiceovers and enforce staging rules
- Add speech assets and configuration for Brad and Mario - Update opponents.json with new speech arrays for intro, happy, and upset states - Prevent discarding cards while cards are staged in Phase 10 - Add visual feedback (_shakeStagingButtons) when staging rules are violated - Add _hasStagedCards helper to check staging group state - Move staged cards back to hand if user attempts to discard during staging
This commit is contained in:
parent
3fcfbcc921
commit
6856baa395
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -30,7 +30,27 @@
|
|||
"id": "brad",
|
||||
"spriteIndex": 1,
|
||||
"name": "Brad",
|
||||
"bio": "Came for the honey, stayed for the salmon!"
|
||||
"bio": "Came for the honey, stayed for the salmon!",
|
||||
"speech": {
|
||||
"intro": [
|
||||
"brad-intro-01",
|
||||
"brad-intro-02"
|
||||
],
|
||||
"happy": [
|
||||
"brad-happy-01",
|
||||
"brad-happy-02",
|
||||
"brad-happy-03",
|
||||
"brad-happy-04",
|
||||
"brad-happy-05"
|
||||
],
|
||||
"upset": [
|
||||
"brad-upset-01",
|
||||
"brad-upset-02",
|
||||
"brad-upset-03",
|
||||
"brad-upset-04",
|
||||
"brad-upset-05"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "victor",
|
||||
|
|
@ -88,7 +108,20 @@
|
|||
"id": "mario",
|
||||
"spriteIndex": 4,
|
||||
"name": "Mario",
|
||||
"bio": "Can you find your way out of my maze of puzzles, games and fun!"
|
||||
"bio": "Can you find your way out of my maze of puzzles, games and fun!",
|
||||
"speech": {
|
||||
"intro": [
|
||||
"mario-intro-01"
|
||||
],
|
||||
"happy": [
|
||||
"mario-happy-01",
|
||||
"mario-happy-02"
|
||||
],
|
||||
"upset": [
|
||||
"mario-upset-01",
|
||||
"mario-upset-02"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "ethel",
|
||||
|
|
|
|||
|
|
@ -599,6 +599,15 @@ export default class Phase10Game extends Phaser.Scene {
|
|||
|
||||
// ── Discard path ──────────────────────────────────────────────────────
|
||||
if (dropTarget?.type === 'discard') {
|
||||
if (this._hasStagedCards()) {
|
||||
this.tweens.killTweensOf(card);
|
||||
this._settleNonDraggedCards();
|
||||
this.dragState = null;
|
||||
this.tweens.add({ targets: card, x: 460 + ds.cardIdx * HAND_SPREAD, y: 990, rotation: 0, scaleX: 1, scaleY: 1, duration: 200, ease: 'Back.easeOut' });
|
||||
this.setStatus('Submit or clear your phase first — you have cards staged.');
|
||||
this._shakeStagingButtons();
|
||||
return;
|
||||
}
|
||||
const handIdx = ds.cardIdx;
|
||||
const handCard = this.gs.players[0].hand[handIdx];
|
||||
this.tweens.killTweensOf(card);
|
||||
|
|
@ -1305,6 +1314,11 @@ export default class Phase10Game extends Phaser.Scene {
|
|||
if (!this.isLocalTurn() || this.animating) return;
|
||||
// If we have a card selected and we've already drawn, discarding ends turn.
|
||||
if (this.gs.drawnThisTurn && this.selectedHandIdx != null) {
|
||||
if (this._hasStagedCards()) {
|
||||
this.setStatus('Submit or clear your phase first — you have cards staged.');
|
||||
this._shakeStagingButtons();
|
||||
return;
|
||||
}
|
||||
const handIdx = this.selectedHandIdx;
|
||||
this.selectedHandIdx = null;
|
||||
this.clearHighlights();
|
||||
|
|
@ -1737,6 +1751,27 @@ export default class Phase10Game extends Phaser.Scene {
|
|||
|
||||
// ── HUD helpers ─────────────────────────────────────────────────────────
|
||||
|
||||
_hasStagedCards() {
|
||||
return this.stagingGroups?.some((g) => g.slots.some((s) => s !== null)) ?? false;
|
||||
}
|
||||
|
||||
_shakeStagingButtons() {
|
||||
const targets = [this.submitBtn, this.clearBtn].filter(Boolean);
|
||||
if (!targets.length) return;
|
||||
for (const btn of targets) {
|
||||
const ox = btn.x;
|
||||
this.tweens.add({
|
||||
targets: btn,
|
||||
x: { from: ox - 8, to: ox + 8 },
|
||||
duration: 60,
|
||||
ease: 'Sine.easeInOut',
|
||||
yoyo: true,
|
||||
repeat: 3,
|
||||
onComplete: () => { btn.x = ox; },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
setStatus(s) {
|
||||
if (!this.statusText) return;
|
||||
this.statusText.setText(s);
|
||||
|
|
|
|||
Loading…
Reference in New Issue