131 lines
3.3 KiB
JavaScript
131 lines
3.3 KiB
JavaScript
/**
|
|
* Star Wars Hearthstone - Web Audio sound effects
|
|
*/
|
|
(function (global) {
|
|
'use strict';
|
|
|
|
let ctx = null;
|
|
|
|
function init() {
|
|
if (ctx) {
|
|
if (ctx.state === 'suspended') ctx.resume().catch(function () {});
|
|
return ctx;
|
|
}
|
|
try {
|
|
ctx = new (global.AudioContext || global.webkitAudioContext)();
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
return ctx;
|
|
}
|
|
|
|
function beep(freq, duration, type, vol) {
|
|
const c = init();
|
|
if (!c) return;
|
|
const osc = c.createOscillator();
|
|
const gain = c.createGain();
|
|
osc.connect(gain);
|
|
gain.connect(c.destination);
|
|
osc.frequency.value = freq;
|
|
osc.type = type || 'sine';
|
|
gain.gain.setValueAtTime(vol ?? 0.15, c.currentTime);
|
|
gain.gain.exponentialRampToValueAtTime(0.001, c.currentTime + duration);
|
|
osc.start(c.currentTime);
|
|
osc.stop(c.currentTime + duration);
|
|
}
|
|
|
|
function playCard() {
|
|
const c = init();
|
|
if (!c) return;
|
|
const osc = c.createOscillator();
|
|
const gain = c.createGain();
|
|
osc.connect(gain);
|
|
gain.connect(c.destination);
|
|
osc.type = 'sine';
|
|
osc.frequency.setValueAtTime(523, c.currentTime);
|
|
osc.frequency.exponentialRampToValueAtTime(784, c.currentTime + 0.08);
|
|
gain.gain.setValueAtTime(0.12, c.currentTime);
|
|
gain.gain.exponentialRampToValueAtTime(0.001, c.currentTime + 0.15);
|
|
osc.start(c.currentTime);
|
|
osc.stop(c.currentTime + 0.15);
|
|
}
|
|
|
|
function attack() {
|
|
const c = init();
|
|
if (!c) return;
|
|
const osc = c.createOscillator();
|
|
const gain = c.createGain();
|
|
osc.connect(gain);
|
|
gain.connect(c.destination);
|
|
osc.type = 'square';
|
|
osc.frequency.value = 180;
|
|
gain.gain.setValueAtTime(0.08, c.currentTime);
|
|
gain.gain.exponentialRampToValueAtTime(0.001, c.currentTime + 0.12);
|
|
osc.start(c.currentTime);
|
|
osc.stop(c.currentTime + 0.12);
|
|
}
|
|
|
|
function endTurn() {
|
|
beep(392, 0.06, 'sine', 0.1);
|
|
setTimeout(() => beep(523, 0.08, 'sine', 0.08), 80);
|
|
}
|
|
|
|
function victory() {
|
|
const notes = [523, 659, 784, 1047];
|
|
notes.forEach((f, i) => {
|
|
setTimeout(() => beep(f, 0.25, 'sine', 0.12), i * 120);
|
|
});
|
|
}
|
|
|
|
function defeat() {
|
|
const notes = [392, 349, 294];
|
|
notes.forEach((f, i) => {
|
|
setTimeout(() => beep(f, 0.2, 'sine', 0.1), i * 150);
|
|
});
|
|
}
|
|
|
|
function drawCard() {
|
|
beep(440, 0.06, 'sine', 0.08);
|
|
}
|
|
|
|
function hoverCard() {
|
|
beep(600, 0.04, 'sine', 0.05);
|
|
}
|
|
|
|
function timerWarning() {
|
|
const c = init();
|
|
if (!c) return;
|
|
const osc = c.createOscillator();
|
|
const gain = c.createGain();
|
|
osc.connect(gain);
|
|
gain.connect(c.destination);
|
|
osc.type = 'sawtooth';
|
|
osc.frequency.setValueAtTime(220, c.currentTime);
|
|
osc.frequency.exponentialRampToValueAtTime(440, c.currentTime + 0.15);
|
|
gain.gain.setValueAtTime(0.08, c.currentTime);
|
|
gain.gain.exponentialRampToValueAtTime(0.001, c.currentTime + 0.2);
|
|
osc.start(c.currentTime);
|
|
osc.stop(c.currentTime + 0.2);
|
|
}
|
|
|
|
function timerEnd() {
|
|
const notes = [262, 330, 392];
|
|
notes.forEach((f, i) => {
|
|
setTimeout(() => beep(f, 0.1, 'square', 0.08), i * 80);
|
|
});
|
|
}
|
|
|
|
global.Sounds = {
|
|
init,
|
|
playCard,
|
|
attack,
|
|
endTurn,
|
|
victory,
|
|
defeat,
|
|
drawCard,
|
|
hoverCard,
|
|
timerWarning,
|
|
timerEnd,
|
|
};
|
|
})(typeof window !== 'undefined' ? window : globalThis);
|