namespace ElementalGame { #region Using Statements using System; using System.Collections.Generic; using System.Diagnostics; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Storage; using System.Xml; #endregion public class Cue3D { public Cue cue; public AudioEmitter emitter = new AudioEmitter(); public AudioListener listener = new AudioListener(); public Vector3 entityPosition; } public class ParticleSounds { public Cue3D earthAttack = new Cue3D(); public Cue3D waterAttack = new Cue3D(); public Cue3D airAttack = new Cue3D(); public Stopwatch particleSoundTimer = new Stopwatch(); public ParticleSounds() { earthAttack.cue = Audio.soundBank.GetCue("EarthBurst"); waterAttack.cue = Audio.soundBank.GetCue("WaterBurst"); airAttack.cue = Audio.soundBank.GetCue("AirBurst"); particleSoundTimer.Start(); } } public class PlayerSounds { public Cue3D jump = new Cue3D(); public Cue3D smackDownHit = new Cue3D(); public Cue3D walking = new Cue3D(); public Cue3D terrainMod = new Cue3D(); public Cue3D fireAttack = new Cue3D(); public Stopwatch walkingSoundTimer = new Stopwatch(); public Stopwatch terrainModSoundTimer = new Stopwatch(); public PlayerSounds() { jump.cue = Audio.soundBank.GetCue("Jump"); smackDownHit.cue = Audio.soundBank.GetCue("Hit"); walking.cue = Audio.soundBank.GetCue("Walking"); terrainMod.cue = Audio.soundBank.GetCue("TerrainMod"); fireAttack.cue = Audio.soundBank.GetCue("FireBurst"); walkingSoundTimer.Start(); terrainModSoundTimer.Start(); } } public static class Audio { static AudioEngine audioEngine; // XNA audio API static WaveBank music; // Level Music static WaveBank effects; // Sound Effects static WaveBank storyMode; // Story Mode Music public static SoundBank soundBank; // Organizes waves into tracks and cues static XmlNode orchestration; // Holds the xml branch containing instruments and timings // Put Metranome and Cue in a Track object // static Stopwatch metranome; // The metranome static List cues; // Background music queue. Effects are handles by GameObjects static bool musicPlaying = true; public static float SOUND_CUTOFF_DISTANCE = 1500; public static void Initialize() { // Load Audio Engine Files audioEngine = new AudioEngine("_audio/Elemental.xgs"); music = new WaveBank(audioEngine, "_audio/Music.xwb"); effects = new WaveBank(audioEngine, "_audio/Effects.xwb"); storyMode = new WaveBank(audioEngine, "_audio/StoryMode.xwb"); soundBank = new SoundBank(audioEngine, "_audio/Sound Bank.xsb"); if (orchestration != null) { orchestration.RemoveAll(); } // Reset time metranome = new Stopwatch(); metranome.Start(); // Clear music cue list cues = new List(); } public static void LoadXML(XmlNode musicNode) { // Save for later orchestration = musicNode; if (orchestration.Name == "music") { try { PlayLevelSong(orchestration.Attributes["background"].Value); } catch { System.Diagnostics.Debug.WriteLine("Error reading music filename"); return; } } } public static void PlayTitleSong() { // Kill everthing for (int i = 0; i < cues.Count; i++) { cues[i].Stop(AudioStopOptions.Immediate); } // Unload all the cues cues.Clear(); // Start new theme Cue playCue = soundBank.GetCue("Theme4"); musicPlaying = true; cues.Add(playCue); if (XML.SystemSettings.music) { playCue.Play(); } } public static void PlayLevelSong(string songName) { // Kill everthing for (int i = 0; i < cues.Count; i++) { cues[i].Stop(AudioStopOptions.Immediate); } // Unload all the cues cues.Clear(); // Start new theme Cue playCue = soundBank.GetCue(songName); musicPlaying = true; cues.Add(playCue); if (XML.SystemSettings.music) { playCue.Play(); } } // Wind the clock public static void Update() { if (XML.SystemSettings.music && !musicPlaying) { for (int i = 0; i < cues.Count; i++) { cues[i].Resume(); musicPlaying = true; } } else if (!XML.SystemSettings.music && musicPlaying) { for (int i = 0; i < cues.Count; i++) { cues[i].Pause(); musicPlaying = false; } } audioEngine.Update(); } private static void PlayCue2D(string cueName) { if (XML.SystemSettings.soundFX) { soundBank.PlayCue(cueName); } } public static void Attack(ParticleSounds pSound, Particle particle, Mass listener, float timestep) { //check the distance first! if (Vector3.Distance(particle.mass.currentPosition, listener.currentPosition) > SOUND_CUTOFF_DISTANCE) { return; } if(timestep < 1000 ){ timestep = 1.0f; } else{ timestep /= 1000.0f; //timestep *= timestep; } // Play Sound if (particle.particleType == Particle.ParticleType.Earth) { pSound.earthAttack.emitter.Position = particle.mass.currentPosition * timestep; pSound.earthAttack.emitter.Velocity = particle.mass.velocity; pSound.earthAttack.listener.Position = listener.currentPosition * timestep; pSound.earthAttack.listener.Velocity = listener.velocity; pSound.earthAttack.cue.Apply3D(pSound.earthAttack.listener, pSound.earthAttack.emitter); if (!pSound.earthAttack.cue.IsPlaying) { pSound.earthAttack.cue = Audio.soundBank.GetCue("EarthBurst"); pSound.earthAttack.cue.Apply3D(pSound.earthAttack.listener, pSound.earthAttack.emitter); pSound.earthAttack.cue.Play(); } } if (particle.particleType == Particle.ParticleType.Water) { pSound.waterAttack.emitter.Position = particle.mass.currentPosition * timestep; pSound.waterAttack.emitter.Velocity = particle.mass.velocity; pSound.waterAttack.listener.Position = listener.currentPosition * timestep; pSound.waterAttack.listener.Velocity = listener.velocity; pSound.waterAttack.cue.Apply3D(pSound.waterAttack.listener, pSound.waterAttack.emitter); if (!pSound.waterAttack.cue.IsPlaying) { pSound.waterAttack.cue = Audio.soundBank.GetCue("WaterBurst"); pSound.waterAttack.cue.Apply3D(pSound.waterAttack.listener, pSound.waterAttack.emitter); pSound.waterAttack.cue.Play(); } } if (particle.particleType == Particle.ParticleType.Air) { pSound.airAttack.emitter.Position = particle.mass.currentPosition * timestep; pSound.airAttack.emitter.Velocity = particle.mass.velocity; pSound.airAttack.listener.Position = listener.currentPosition * timestep; pSound.airAttack.listener.Velocity = listener.velocity; pSound.airAttack.cue.Apply3D(pSound.airAttack.listener, pSound.airAttack.emitter); if (!pSound.airAttack.cue.IsPlaying) { pSound.airAttack.cue = Audio.soundBank.GetCue("AirBurst"); pSound.airAttack.cue.Apply3D(pSound.airAttack.listener, pSound.airAttack.emitter); pSound.airAttack.cue.Play(); } } } public static void FireAttack(PlayerSounds pSound, Vector3 emitterPosition, Vector3 listenerPosition) { //check the distance first! if (Vector3.Distance(emitterPosition, listenerPosition) > SOUND_CUTOFF_DISTANCE) { return; } pSound.fireAttack.emitter.Position = emitterPosition; pSound.fireAttack.listener.Position = listenerPosition; pSound.fireAttack.cue.Apply3D(pSound.fireAttack.listener, pSound.fireAttack.emitter); if (!pSound.fireAttack.cue.IsPlaying) { pSound.fireAttack.cue = Audio.soundBank.GetCue("FireBurst"); pSound.fireAttack.cue.Apply3D(pSound.fireAttack.listener, pSound.fireAttack.emitter); pSound.fireAttack.cue.Play(); } } public static void StopAttack(ParticleSounds pSound) { // Stop Sound if (pSound.earthAttack.cue != null) { pSound.earthAttack.cue.Stop(AudioStopOptions.Immediate); } if (pSound.waterAttack.cue != null) { pSound.waterAttack.cue.Stop(AudioStopOptions.Immediate); } if (pSound.airAttack.cue != null) { pSound.airAttack.cue.Stop(AudioStopOptions.Immediate); } // Kill timer pSound.particleSoundTimer.Stop(); } public static void Jump(PlayerSounds pSound, Vector3 emitterPosition, Vector3 listenerPosition) { //check the distance first! if (Vector3.Distance(emitterPosition, listenerPosition) > SOUND_CUTOFF_DISTANCE) { return; } pSound.jump.cue = soundBank.GetCue("Jump"); pSound.jump.emitter.Position = emitterPosition; pSound.jump.listener.Position = listenerPosition; pSound.jump.cue.Apply3D(pSound.jump.listener, pSound.jump.emitter); pSound.jump.cue.Play(); } public static void SmackDownHit(PlayerSounds pSound, Vector3 emitterPosition, Vector3 listenerPosition) { //check the distance first! if (Vector3.Distance(emitterPosition, listenerPosition) > SOUND_CUTOFF_DISTANCE) { return; } pSound.smackDownHit.cue = soundBank.GetCue("Hit"); pSound.smackDownHit.emitter.Position = emitterPosition; pSound.smackDownHit.listener.Position = listenerPosition; pSound.smackDownHit.cue.Apply3D(pSound.smackDownHit.listener, pSound.smackDownHit.emitter); pSound.smackDownHit.cue.Play(); } public static void Walking(PlayerSounds pSound, Vector3 emitterPosition, Vector3 listenerPosition) { //check the distance first! if (Vector3.Distance(emitterPosition, listenerPosition) > SOUND_CUTOFF_DISTANCE) { return; } //pSound.walking.emitter.Position = emitterPosition; //pSound.walking.listener.Position = listenerPosition; //pSound.walking.cue.Apply3D(pSound.walking.listener, pSound.walking.emitter); //if (pSound.walkingSoundTimer.ElapsedMilliseconds > 100) //{ // pSound.walking.cue = soundBank.GetCue("Walking"); // pSound.walking.cue.Apply3D(pSound.walking.listener, pSound.walking.emitter); // pSound.walking.cue.Play(); // pSound.walkingSoundTimer = Stopwatch.StartNew(); //} } public static void TerrainMod(PlayerSounds pSound, Vector3 emitterPosition, Vector3 listenerPosition) { //check the distance first! if (Vector3.Distance(emitterPosition, listenerPosition) > SOUND_CUTOFF_DISTANCE) { return; } pSound.terrainMod.emitter.Position = emitterPosition; pSound.terrainMod.listener.Position = listenerPosition; pSound.terrainMod.cue.Apply3D(pSound.terrainMod.listener, pSound.terrainMod.emitter); if (pSound.terrainModSoundTimer.ElapsedMilliseconds > 900) { pSound.terrainMod.cue = soundBank.GetCue("TerrainMod"); pSound.terrainMod.cue.Apply3D(pSound.terrainMod.listener, pSound.terrainMod.emitter); pSound.terrainMod.cue.Play(); pSound.terrainModSoundTimer = Stopwatch.StartNew(); } } // 2D Sounds public static void KeyFound() { PlayCue2D("KeyFound"); } public static void MenuStart() { PlayCue2D("menuClose"); } public static void MenuBack() { PlayCue2D("wrongButton"); } public static void MenuUp() { PlayCue2D("Tin"); } public static void MenuDown() { PlayCue2D("Tin"); } public static void MenuLeft() { PlayCue2D("wrongButton"); } public static void MenuRight() { PlayCue2D("wrongButton"); } public static void MenuPlayerShuffleRight() { PlayCue2D("MenuFolderShuffleRight"); } public static void MenuPlayerShuffleLeft() { PlayCue2D("MenuFolderShuffleRight"); } public static void MenuDPad() { PlayCue2D("Tin"); } } }