World sounds are local: fade with distance and pan (distant sizzles snapped constantly)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+22
-3
@@ -75,7 +75,7 @@ function tone(freq, dur, opts = {}) {
|
||||
g.gain.exponentialRampToValueAtTime(v, t + a);
|
||||
g.gain.setValueAtTime(v, t + Math.max(a, dur - rel));
|
||||
g.gain.exponentialRampToValueAtTime(0.0001, t + dur);
|
||||
o.connect(g); g.connect(opts.bus || AU.sfx);
|
||||
o.connect(g); g.connect(opts.bus || AU.bus || AU.sfx);
|
||||
o.start(t); o.stop(t + dur + 0.02);
|
||||
}
|
||||
function noiseBurst(dur, opts = {}) {
|
||||
@@ -87,7 +87,7 @@ function noiseBurst(dur, opts = {}) {
|
||||
if (opts.sweep) f.frequency.exponentialRampToValueAtTime(opts.sweep, t + dur);
|
||||
const g = ctx.createGain(); const v = opts.vol || 0.08;
|
||||
g.gain.setValueAtTime(v, t); g.gain.exponentialRampToValueAtTime(0.0001, t + dur);
|
||||
s.connect(f); f.connect(g); g.connect(opts.bus || AU.sfx);
|
||||
s.connect(f); f.connect(g); g.connect(opts.bus || AU.bus || AU.sfx);
|
||||
s.start(t, Math.random() * 1.5); s.stop(t + dur + 0.02);
|
||||
}
|
||||
const SFX = {
|
||||
@@ -118,7 +118,26 @@ const SFX = {
|
||||
sale() { if (!AU.ctx) return; const t = AU.ctx.currentTime; [784, 988, 1175, 1568].forEach((f, k) => tone(f, 0.09, { wave: 'p25', vol: 0.05, at: t + k * 0.06 })); },
|
||||
discover() { if (!rateOk('disc', 500)) return; const t = AU.ctx && AU.ctx.currentTime; tone(880, 0.06, { wave: 'p25', vol: 0.04, at: t }); tone(1175, 0.1, { wave: 'p25', vol: 0.04, at: t + 0.06 }); },
|
||||
};
|
||||
function playSfx(name, arg) { if (!AU.ctx || !SFX[name]) return; try { SFX[name](arg); } catch (e) { /* ignore */ } }
|
||||
function sfxPlace(x, y) {
|
||||
if (typeof R === 'undefined' || !R.bw) return { gain: 1, pan: 0 };
|
||||
const dx = Math.max(R.vx0 - x, 0, x - R.vx0 - R.bw), dy = Math.max(R.vy0 - y, 0, y - R.vy0 - R.bh);
|
||||
return { gain: Math.max(0, 1 - Math.hypot(dx, dy) / R.bw), pan: Math.max(-1, Math.min(1, (x - R.vx0 - R.bw / 2) / (R.bw / 2))) * 0.6 };
|
||||
}
|
||||
function playSfx(name, arg, x, y) {
|
||||
if (!AU.ctx || !SFX[name]) return;
|
||||
const place = typeof x === 'number' && typeof y === 'number' ? sfxPlace(x, y) : null;
|
||||
if (place && place.gain < 0.02) return;
|
||||
const prev = AU.bus; let gain, pan;
|
||||
try {
|
||||
if (place) {
|
||||
gain = AU.ctx.createGain(); pan = AU.ctx.createStereoPanner();
|
||||
gain.gain.value = place.gain; pan.pan.value = place.pan;
|
||||
gain.connect(pan); pan.connect(AU.sfx); AU.bus = gain;
|
||||
}
|
||||
SFX[name](arg);
|
||||
} catch (e) { /* ignore */ }
|
||||
finally { AU.bus = prev; if (gain || pan) setTimeout(() => { if (gain) gain.disconnect(); if (pan) pan.disconnect(); }, 1500); }
|
||||
}
|
||||
|
||||
// Ambient layer driven by what is on screen.
|
||||
function auAmbient(info) {
|
||||
|
||||
Reference in New Issue
Block a user