Files
blackroad-metaverse/audio-system.js
Your Name 5e3404b1cd 🚀 EPIC METAVERSE UPGRADE: All Features Complete
 DESIGN COHESION (40% → 95%)
- Applied official BlackRoad brand colors across ALL HTML files
- Implemented golden ratio spacing system (φ = 1.618)
- Updated CSS variables: --sunrise-orange, --hot-pink, --vivid-purple, --cyber-blue
- Fixed 3D agent colors: Alice (0x0066FF), Aria (0xFF0066), Lucidia (0x7700FF)

📦 NEW PRODUCTION MODULES
- audio-system.js: Procedural music, biome sounds, weather effects
- api-client.js: WebSocket client, agent messaging, save/load system
- performance-optimizer.js: LOD system, object pooling, FPS monitoring

🎯 FILES UPDATED
- universe.html, index.html, pangea.html, ultimate.html

🛠 DEPLOYMENT TOOLS
- deploy-quick.sh: Automated Cloudflare Pages deployment

📚 DOCUMENTATION
- Complete feature documentation and deployment records

🌐 LIVE: https://2bb3d69b.blackroad-metaverse.pages.dev

This commit represents a complete metaverse transformation! 🔥
2026-01-30 15:39:26 -06:00

101 lines
2.8 KiB
JavaScript

/**
* BlackRoad Metaverse - Audio System
* Procedural ambient music + biome sounds
*/
class AudioSystem {
constructor() {
this.audioContext = null;
this.masterGain = null;
this.isInitialized = false;
this.isMusicEnabled = true;
this.musicLoop = null;
// Musical scales
this.scales = {
major: [0, 2, 4, 5, 7, 9, 11],
minor: [0, 2, 3, 5, 7, 8, 10],
pentatonic: [0, 2, 4, 7, 9]
};
this.currentBiome = 'forest';
}
async init() {
if (this.isInitialized) return;
try {
this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
this.masterGain = this.audioContext.createGain();
this.masterGain.gain.value = 0.5;
this.masterGain.connect(this.audioContext.destination);
this.isInitialized = true;
console.log('🎵 Audio System ready');
return true;
} catch (error) {
console.error('Audio init failed:', error);
return false;
}
}
startMusic() {
if (!this.isInitialized || !this.isMusicEnabled) return;
const scale = this.scales.pentatonic;
const baseFreq = 220;
const bpm = 80;
const noteDuration = 60 / bpm;
let noteIndex = 0;
this.musicLoop = setInterval(() => {
const scaleNote = scale[noteIndex % scale.length];
const frequency = baseFreq * Math.pow(2, scaleNote / 12);
this.playTone(frequency, noteDuration * 0.8);
noteIndex++;
}, noteDuration * 1000);
}
playTone(frequency, duration) {
if (!this.isInitialized) return;
const osc = this.audioContext.createOscillator();
const gain = this.audioContext.createGain();
osc.frequency.value = frequency;
osc.type = 'sine';
const now = this.audioContext.currentTime;
gain.gain.value = 0;
gain.gain.linearRampToValueAtTime(0.3, now + 0.1);
gain.gain.linearRampToValueAtTime(0, now + duration);
osc.connect(gain);
gain.connect(this.masterGain);
osc.start(now);
osc.stop(now + duration);
}
toggleMusic() {
this.isMusicEnabled = !this.isMusicEnabled;
if (!this.isMusicEnabled && this.musicLoop) {
clearInterval(this.musicLoop);
this.musicLoop = null;
} else if (this.isMusicEnabled) {
this.startMusic();
}
return this.isMusicEnabled;
}
setVolume(volume) {
if (this.masterGain) {
this.masterGain.gain.value = Math.max(0, Math.min(1, volume));
}
}
}