fertig-classic-games/src/ui/Sounds.js

229 lines
9.4 KiB
JavaScript

// Sound effect keys — must match the keys loaded in PreloadScene.
export const SFX = {
CARD_DEAL: 'sfx-card-deal',
CARD_PLACE: 'sfx-card-place',
CARD_SHOW: 'sfx-card-show',
CARD_SHUFFLE: 'sfx-card-shuffle',
COINS: 'sfx-coins',
PURCHASE: 'sfx-purchase',
CASINO_BLACKJACK: 'sfx-casino-blackjack',
CASINO_LOSE: 'sfx-casino-lose',
CASINO_WIN: 'sfx-casino-win',
CHIP_BET: 'sfx-chip-bet',
DICE_ROLL: 'sfx-dice-roll',
PENCIL_WRITE: 'sfx-pencil-write',
BINGO_BALLS: 'sfx-bingo-balls',
PIECE_CLICK: 'sfx-piece-click',
ROULETTE: 'sfx-roulette',
BATTLESHIP_HIT: 'sfx-battleship-hit',
BATTLESHIP_MISS: 'sfx-battleship-miss',
BATTLESHIP_LAUNCH: 'sfx-battleship-launch',
MASTERMIND_GLITCH_1: 'sfx-mastermind-glitch-1',
MASTERMIND_GLITCH_2: 'sfx-mastermind-glitch-2',
MASTERMIND_PLACE: 'sfx-mastermind-place',
MASTERMIND_GRANTED: 'sfx-mastermind-access-granted',
MASTERMIND_DENIED: 'sfx-mastermind-access-denied',
MASTERMIND_COLOR: 'sfx-mastermind-color',
MASTERMIND_MATCH: 'sfx-mastermind-match',
MASTERMIND_CALCULATE: 'sfx-mastermind-calculate',
VICTORY_SHORT: 'sfx-victory-short',
SCIFI_LAUNCH: 'sfx-scifi-launch',
SCIFI_EXPLODE: 'sfx-scifi-explode',
SCIFI_RISER: 'sfx-scifi-riser',
SCIFI_REVEAL: 'sfx-scifi-reveal',
SCIFI_WOOSH: 'sfx-scifi-woosh',
SCIFI_PLINK: 'sfx-scifi-plink',
SCIFI_PLONK: 'sfx-scifi-plonk',
SWORD_HIT: 'sfx-sword-hit',
SWORD_SLICE: 'sfx-sword-slice',
MONOPOLY_PURCHASE: 'sfx-monopoly-purchase',
MONOPOLY_EXPENSE: 'sfx-monopoly-expense',
MONOPAY: 'sfx-monopoly-pay',
MONOPOLY_PAID: 'sfx-monopoly-paid',
EIGHTBIT_SELECT: 'sfx-8bit-select',
EIGHTBIT_ACTIVATE: 'sfx-8bit-activate',
EIGHTBIT_ACTION: 'sfx-8bit-action',
EIGHTBIT_MOVE: 'sfx-8bit-move',
CLICK: 'sfx-click',
EIGHTBIT_JUMP: 'sfx-8bit-jump',
EIGHTBIT_CARD: 'sfx-card-deal-8bit',
EIGHTBIT_EXPLODE: 'sfx-8bit-explode',
EIGHTBIT_EXPLODE_2: 'sfx-8bit-explode2',
EIGHTBIT_COUNT: 'sfx-8bit-count',
EIGHTBIT_WIN: 'sfx-casino-win-8bit',
SQUISH: 'sfx-squish',
SQUASH: 'sfx-squash',
WOOSH: 'sfx-woosh',
// Loaded in PreloadScene since the Zuma work; named here so games stop
// reaching for the raw cache keys.
WATER_SPLASH: 'sfx-water-splash',
WATER_SINK: 'sfx-water-sink',
WATER_RAISE: 'sfx-water-raise',
WATER_DRY: 'sfx-water-dry',
JELLO_MONSTERS: 'sfx-jello-monsters',
COUNTDOWN_TICK: 'sfx-countdown-tick',
COUNTDOWN_GO: 'sfx-countdown-go',
UI_PICK: 'sfx-ui-pick',
UI_ACTIVATE: 'sfx-ui-activate',
UI_FLIP: 'sfx-ui-flip',
UI_PLACE: 'sfx-ui-place',
UI_CHIME: 'sfx-ui-chime',
GEM_MATCH_1: 'sfx-gem-match-1',
GEM_MATCH_2: 'sfx-gem-match-2',
GEM_MATCH_4: 'sfx-gem-match-4',
GEM_MATCH_5: 'sfx-gem-match-5',
GEM_CHAIN: 'sfx-gem-chain',
GEM_DROP: 'sfx-gem-drop',
GEM_BIG_DROP: 'sfx-gem-big-drop',
FIREWORK: 'sfx-firework',
SW_LIGHT_1: 'sfx-sw-light-1',
SW_LIGHT_2: 'sfx-sw-light-2',
SW_LIGHT_3: 'sfx-sw-light-3',
SW_DARK_1: 'sfx-sw-dark-1',
SW_DARK_2: 'sfx-sw-dark-2',
SW_DARK_3: 'sfx-sw-dark-3',
ENERGY_HUM: 'sfx-energy-hum',
LASER_ZAP: 'sfx-laser-zap',
REWIND: 'sfx-rewind',
ENGINE_START: 'sfx-engine-start',
ENGINE_HEAVY: 'sfx-engine-heavy',
ENGINE_FAST: 'sfx-engine-fast',
ENGINE_MEDIUM: 'sfx-engine-medium',
ENGINE_REV: 'sfx-engine-rev',
KART_COIN: 'sfx-kart-coin',
KART_FLATTEN: 'sfx-kart-flatten',
KART_THUMP: 'sfx-kart-thump',
KART_SHRINK: 'sfx-kart-shrink',
KART_SPIN: 'sfx-kart-spin',
KART_HIT: 'sfx-kart-hit',
KART_SHELL: 'sfx-kart-shell',
KART_STAR: 'sfx-kart-star',
KART_SPINNER: 'sfx-kart-spinner',
VEGA_SELECT: 'sfx-vega-select',
VEGA_BUILD: 'sfx-vega-build',
VEGA_CLOSE: 'sfx-vega-close',
VEGA_NEWTURN: 'sfx-vega-newturn',
VEGA_UNIT: 'sfx-vega-unit',
VEGA_VIEW: 'sfx-vega-view',
VEGA_WARP: 'sfx-vega-warp',
VEGA_STAR: 'sfx-vega-star',
VEGA_ZOOMIN: 'sfx-vega-zoomin',
VEGA_ZOOMOUT: 'sfx-vega-zoomout',
VEGA_VIEWCOLONY: 'sfx-vega-viewcolony',
VEGA_ENDTURN: 'sfx-vega-endturn',
VEGA_COUNTER: 'sfx-vega-counter',
VEGA_GNN_STING: 'sfx-vega-gnn-sting',
VEGA_GNN_LOOP: 'sfx-vega-gnn-loop',
VEGA_COUNCIL_INTRO: 'sfx-vega-council-intro',
VEGA_COUNCIL_LOOP: 'sfx-vega-council-loop',
// Beam cues split by the firing ship's Mark (I-VII); missile cues split the
// same way but only two ways, and further split into launch vs. impact.
// See VegaCombatView.js's weaponSfxKey()/missileLaunchSfxKey()/
// missileHitSfxKey() for the Mark bands.
VEGA_WEAPON_123: 'sfx-vega-weapon-123',
VEGA_WEAPON_45: 'sfx-vega-weapon-45',
VEGA_WEAPON_67: 'sfx-vega-weapon-67',
VEGA_MISSILE_LAUNCH_12345: 'sfx-vega-missle-launch-12345',
VEGA_MISSILE_LAUNCH_67: 'sfx-vega-missle-launch-67',
VEGA_MISSILE_HIT_12345: 'sfx-vega-missle-hit-12345',
VEGA_MISSILE_HIT_67: 'sfx-vega-missle-hit-67',
// Planetary defence battery fire — VegaCombatViewV2.js's handleEvents
// plays this instead of a weaponSfxKey() band whenever the shooter is the
// planet (ev.weaponKind is null for a planet's fire events, since it has
// no weapon mount to band by Mark).
VEGA_PLANET_BEAM: 'sfx-vega-planet-beam',
// One destroy cue per warship class — see VegaCombatView.js's/
// VegaCombatViewV2.js's destroySfxKey(). Only the four combatant hulls
// (frigate/destroyer/cruiser/battleship) have a clip; other hulls play no
// destroy cue. Cache key spelling is the correct "frigate" even though the
// clip on disk is named "vega-destroy-friggate.mp3" (typo in the filename
// Brian recorded) — see the asset manifest entry.
VEGA_DESTROY_FRIGATE: 'sfx-vega-destroy-frigate',
VEGA_DESTROY_DESTROYER: 'sfx-vega-destroy-destroyer',
VEGA_DESTROY_CRUISER: 'sfx-vega-destroy-cruiser',
VEGA_DESTROY_BATTLESHIP: 'sfx-vega-destroy-battleship',
};
export function playSound(scene, key) {
try { scene.sound.play(key); } catch (_) {}
}
// Same, but with a Phaser sound config — `{ rate, volume, detune }`. Use this
// for pitch-shifted cues rather than `scene.sound.add(...)`, which leaks a
// Sound object per call.
export function playSoundEx(scene, key, config) {
try { scene.sound.play(key, config); } catch (_) {}
}
// Picks and plays one of several keys at random (e.g. variations of the same cue).
export function playRandomSound(scene, keys) {
playSound(scene, keys[Math.floor(Math.random() * keys.length)]);
}
const SW_LIGHT_KEYS = [SFX.SW_LIGHT_1, SFX.SW_LIGHT_2, SFX.SW_LIGHT_3];
const SW_DARK_KEYS = [SFX.SW_DARK_1, SFX.SW_DARK_2, SFX.SW_DARK_3];
// SWDBG: Force track shifting toward the Rebel (light) or Empire (dark) side.
export function playForceMove(scene, towardLight) {
playRandomSound(scene, towardLight ? SW_LIGHT_KEYS : SW_DARK_KEYS);
}
// chip-bet is limited to one simultaneous instance.
let _chipBetSound = null;
export function playChipBet(scene) {
if (_chipBetSound?.isPlaying) return;
_chipBetSound?.destroy();
_chipBetSound = scene.sound.add(SFX.CHIP_BET);
_chipBetSound.play();
}
// Each plays at most one simultaneous instance (tie battles would otherwise double up).
let _scifiLaunchSound = null;
export function playScifiLaunch(scene) {
if (_scifiLaunchSound?.isPlaying) return;
_scifiLaunchSound?.destroy();
_scifiLaunchSound = scene.sound.add(SFX.SCIFI_LAUNCH);
_scifiLaunchSound.play();
}
let _scifiExplodeSound = null;
export function playScifiExplode(scene) {
if (_scifiExplodeSound?.isPlaying) return;
_scifiExplodeSound?.destroy();
_scifiExplodeSound = scene.sound.add(SFX.SCIFI_EXPLODE);
_scifiExplodeSound.play();
}
let _scifiRiserSound = null;
export function playScifiRiser(scene) {
if (_scifiRiserSound?.isPlaying) return;
_scifiRiserSound?.destroy();
_scifiRiserSound = scene.sound.add(SFX.SCIFI_RISER);
_scifiRiserSound.play();
}
let _scifiRevealSound = null;
export function playScifiReveal(scene) {
if (_scifiRevealSound?.isPlaying) return;
_scifiRevealSound?.destroy();
_scifiRevealSound = scene.sound.add(SFX.SCIFI_REVEAL);
_scifiRevealSound.play();
}
let _scifiWooshSound = null;
export function playScifiWoosh(scene) {
if (_scifiWooshSound?.isPlaying) return;
_scifiWooshSound?.destroy();
_scifiWooshSound = scene.sound.add(SFX.SCIFI_WOOSH);
_scifiWooshSound.play();
}
// Dot Link: plink/plonk with adjustable rate — even colour index → plink, odd → plonk
export function playDotLinkSound(scene, colorIdx, pathLength) {
const soundKey = colorIdx % 2 === 0 ? SFX.SCIFI_PLINK : SFX.SCIFI_PLONK;
const rate = 1 + (pathLength - 1) * 0.5;
const sound = scene.sound.add(soundKey);
sound.setRate(rate);
sound.play();
}