feat(catan): add visual and audio feedback for card theft by robber
- Detect when the robber steals a resource from player 0 by comparing resource counts before and after the move. - Display a temporary "CARD STOLEN" banner with the stolen resource name and robber's name. - Play a lose sound effect to provide immediate audio feedback. - Apply this notification logic consistently across all three locations where the robber is moved (AI turn, player turn, and initial setup).
This commit is contained in:
parent
67500636cb
commit
58c4edf8fd
|
|
@ -1389,7 +1389,12 @@ export default class CatanGame extends Phaser.Scene {
|
|||
this.renderAll(); await this.delay(400);
|
||||
const m = AI.chooseRobberMove(this.gs, seat);
|
||||
const preRobberHex = this.gs.robberHex;
|
||||
const preRes0roll = { ...this.gs.players[0].resources };
|
||||
this.gs = L.moveRobber(this.gs, m.hexId, m.targetSeat);
|
||||
if (m.targetSeat === 0) {
|
||||
const stolen = RESOURCE_TYPES.find(r => this.gs.players[0].resources[r] < preRes0roll[r]);
|
||||
if (stolen) this._notifyStolenCard(stolen, this.pname(seat));
|
||||
}
|
||||
await this.animateRobber(preRobberHex, m.hexId);
|
||||
this.renderAll(); await this.delay(400);
|
||||
}
|
||||
|
|
@ -1412,9 +1417,14 @@ export default class CatanGame extends Phaser.Scene {
|
|||
await this.delay(450);
|
||||
const m = AI.chooseRobberMove(this.gs, seat);
|
||||
const preRobberHex = this.gs.robberHex;
|
||||
const preRes0 = { ...this.gs.players[0].resources };
|
||||
this.gs = L.moveRobber(this.gs, m.hexId, m.targetSeat);
|
||||
const animPromise = this.animateRobber(preRobberHex, m.hexId);
|
||||
if (m.targetSeat != null) this.opponentPortraits[seat]?.playEmotion?.('happy');
|
||||
if (m.targetSeat === 0) {
|
||||
const stolen = RESOURCE_TYPES.find(r => this.gs.players[0].resources[r] < preRes0[r]);
|
||||
if (stolen) this._notifyStolenCard(stolen, this.pname(seat));
|
||||
}
|
||||
await animPromise;
|
||||
this.renderAll();
|
||||
await this.delay(450);
|
||||
|
|
@ -1444,7 +1454,12 @@ export default class CatanGame extends Phaser.Scene {
|
|||
if (this.gs.phase === 'moveRobber') {
|
||||
const m = AI.chooseRobberMove(this.gs, seat);
|
||||
const preRobberHex = this.gs.robberHex;
|
||||
const preRes0action = { ...this.gs.players[0].resources };
|
||||
this.gs = L.moveRobber(this.gs, m.hexId, m.targetSeat);
|
||||
if (m.targetSeat === 0) {
|
||||
const stolen = RESOURCE_TYPES.find(r => this.gs.players[0].resources[r] < preRes0action[r]);
|
||||
if (stolen) this._notifyStolenCard(stolen, this.pname(seat));
|
||||
}
|
||||
await this.animateRobber(preRobberHex, m.hexId);
|
||||
}
|
||||
this.renderAll();
|
||||
|
|
@ -1779,6 +1794,21 @@ export default class CatanGame extends Phaser.Scene {
|
|||
this.statusText.setText(msg);
|
||||
}
|
||||
|
||||
_notifyStolenCard(resource, robberName) {
|
||||
playSound(this, SFX.CASINO_LOSE);
|
||||
const label = (RESOURCE_INFO[resource]?.label ?? resource).toUpperCase();
|
||||
const txt = this.add.text(GAME_WIDTH / 2, 855,
|
||||
`CARD STOLEN: ${label} BY ${robberName.toUpperCase()}`, {
|
||||
fontFamily: 'Righteous', fontSize: '38px', color: '#ffd700',
|
||||
stroke: '#000000', strokeThickness: 5,
|
||||
}
|
||||
).setOrigin(0.5).setDepth(D.banner + 2);
|
||||
this.tweens.add({
|
||||
targets: txt, alpha: 0, delay: 3000, duration: 500,
|
||||
onComplete: () => txt.destroy(),
|
||||
});
|
||||
}
|
||||
|
||||
showTurnBanner(text) {
|
||||
const banner = this.add.text(1000, 120, text, {
|
||||
fontFamily: 'Righteous', fontSize: '34px', color: COLORS.textHex,
|
||||
|
|
|
|||
Loading…
Reference in New Issue