feat(dominion): add sparkle particles and coin sound to supply piles

- Add a particle emitter effect to supply pile cards using a generated sparkle texture.
- Include a `coins.mp3` sound effect for purchase interactions.
- Implement `_clearSupplyFx` to manage emitter lifecycle during render cycles.
This commit is contained in:
Brian Fertig 2026-05-27 17:58:58 -06:00
parent 41466e14f3
commit 0536a261f6
2 changed files with 31 additions and 0 deletions

BIN
public/assets/fx/coins.mp3 Normal file

Binary file not shown.

View File

@ -100,10 +100,18 @@ export default class DominionGame extends Phaser.Scene {
this._suppressTurnUi = false;
this._handFxGraphics = [];
this._handFxTweens = [];
this._supplyFxEmitters = [];
}
create() {
new MusicPlayer(this, this.cache.json.get('music').tracks);
if (!this.textures.exists('dominion-sparkle')) {
const g = this.add.graphics();
g.fillStyle(0xffffff, 1);
g.fillCircle(3, 3, 3);
g.generateTexture('dominion-sparkle', 6, 6);
g.destroy();
}
this.buildBackground();
this.buildPortraits();
this.buildTurnArrow();
@ -421,6 +429,7 @@ export default class DominionGame extends Phaser.Scene {
render() {
this._clearHandFx();
this._clearSupplyFx();
if (this.hoverTimer) { this.hoverTimer.remove(); this.hoverTimer = null; }
this.hideHover();
this.dynamicLayer?.destroy(true);
@ -500,6 +509,7 @@ export default class DominionGame extends Phaser.Scene {
hit.setInteractive({ useHandCursor: true });
hit.on('pointerup', () => this.humanBuy(id));
this.markBuyable(face);
this._buildSupplyFxItem(x, y);
}
}
}
@ -510,6 +520,27 @@ export default class DominionGame extends Phaser.Scene {
face.addAt(glow, 0);
}
_clearSupplyFx() {
this._supplyFxEmitters.forEach(e => e.destroy());
this._supplyFxEmitters = [];
}
_buildSupplyFxItem(x, y) {
const emitter = this.add.particles(x, y, 'dominion-sparkle', {
x: { min: -SUPPLY_W / 2 + 4, max: SUPPLY_W / 2 - 4 },
y: -SUPPLY_H / 2,
speedX: { min: -18, max: 18 },
speedY: { min: -70, max: -30 },
alpha: { start: 0.9, end: 0 },
scale: { start: 0.8, end: 0.15 },
lifespan: 900,
frequency: 100,
tint: [0xffffff, 0xffeebb, 0xd4a017, 0xc8a84b],
depth: D.supply + 8,
});
this._supplyFxEmitters.push(emitter);
}
renderInPlay() {
const gs = this.gs;
const p = gs.players[gs.turn];