我估计你以前可能用过DirectSound,当你在XNA中编写第一个游戏时您会发现sound命名空间与DirectSound有很大不同。快速浏览一下Managed DirectX中的DirectSound是如何使用的。首先,你必须初始化DirectSound设备:
soundDevice = new DirectSound.Device(); soundDevice.SetCooperativeLevel(form, CooperativeLevel.Priority);
现在,您可以载入所有的声音,确保您有多个声音缓冲器和处理文件不存在的情况有点复杂,这将导致DirectSound提示InvalidOperationException错误。在Managed DirectX Rocket Commander代码中,下列代码是用来确保所有的声音文件存在,以确保您可以多次播放声音:
if (File.Exists(Directories.SoundsDirectory + "\\" + filename) == false) { Log.Write("Sample " + filename + " was not found!"); loaded = false; return; } // if (File.Exists) BufferDescription bufferDesc = new BufferDescription(); bufferDesc.StaticBuffer = true; bufferDesc.ControlPan = true; bufferDesc.ControlVolume = true; bufferDesc.ControlFrequency = true; buffer = new SecondaryBuffer[setNumberOfSimultaneousSounds]; channelVolume = new float[setNumberOfSimultaneousSounds]; channelPanning = new float[setNumberOfSimultaneousSounds]; buffer[0] = new SecondaryBuffer( Directories.SoundsDirectory + "\\" + filename, bufferDesc, Sound.Device); defaultFrequency = buffer[0].Frequency; for (int i = 1; i < buffer.Length; i++) buffer[i] = buffer[0]; try { for (int i = 1; i < buffer.Length; i++) buffer[i] = buffer[0].Clone(Sound.Device); } // try catch { } // catch
最后,代码处理播放声音。借助于Sample类(ControlPan,ControlVolume,ControlFrequency等)的构造函数中的代码您可以设定每个声音缓冲通道的音量和panning。因为Rocket Commander中的Sample类代码很长,所以这里没有显示用来管理所有声音缓冲器和每个声音的属性(音量,panning,频率)的额外代码,如果您有兴趣可以去看原始代码。
// Make sure to start at position 0 buffer[currentBufferNum].SetCurrentPosition(0); // And play the sound buffer[currentBufferNum].Play(0, BufferPlayFlags.Default);
在XNA中你不再需要Sample类,你可以扩展Sound类以支持你需要的一切,包括MusicManager,Sample类和Rocket Commander中的Sound命名空间的其他东西。
由于XACT的结构(这将在下面讨论),你必须自己加载XACT项目、wave和sound banks。但不必担心,代码非常简单。
audioEngine = new AudioEngine("YourSoundProject.xgs"); waveBank = new WaveBank(audioEngine, "Wave Bank.xwb"); soundBank = new SoundBank(audioEngine, "Sound Bank.xsb");
就是这些,你要做的只是调用它:
soundBank.PlayCue(soundName);
看起来很容易,不是吗?您可能会要求DirectSound中的额外功能。它们没有丢失,但在XNA中处理声音的思路不一样。声音文件已不再完全由自定义代码管理,作为替代,XACT声音项目包含了所有预定义的声音参数。你无需自己修改每个声音的音量或音调,你可以在XACT工具中处理这一切。这对确保所有的声音有相同的音量,并确保声音不是太大是很有用的。你可以指定某些声音只被允许播放一次(如背景音乐),为开火或爆炸播放相同声音的多个实例。您将在本章后面学到更多的相关知识。
DirectSound和XACT都要求声音文件必须是.wav格式。如果您有其他格式的声音文件则必须首先进行转换。例如,MP3文件不被支持,你不能在DirectSound播放它们或简单地把它们拖动到您的XACT项目中。你必须首先转换为.wav文件。另请注意,在XACT中某些特定的.wav文件不被支持,当你添加声音文件到wave bank时将获得一个警告讯息告知格式不支持。
确保一个音乐文件的格式是正确的,并在XACT中以最佳途径压缩不是很容易(见图9-1)。
您要将声音文件都转换成16位44千赫立体声的PCM wav文件以确保可以压缩它们。如果音乐只有单声道,你还必须将它保存为立体声,如果您有8-bit的PCM文件,那就不要尝试去使用它们。一定要转换为16bit和立体声,否则XACT不会允许你正确地压缩声音文件。对于8bit文件你会得到如图9-2所示的错误讯息,而单声道文件压缩得不好。压缩时16bit立体声文件会损失一些音质,但选择正确的XMA和ADPCM压缩级别会让这种损失降到最小。
请注意,XACT并不真正支持音乐文件,它更擅长处理音效文件。在PC平台上,如果你有MP3音乐文件,那么使用ADPCM编码可能没有多大意义,而且已经有一些代码可以播放它们。但在Xbox 360平台上,您目前别无选择,只能使用XMA压缩和XACT。
音效文件也可以被压缩,但我建议您尝试使用高压缩比。对于PC游戏使用高度压缩的声音文件是非常少见的,通常使用低音质的文件(22KHz单声道),因为这样载入更快,使用MP3文件是不切实际的,因为这样做将使CPU在每次播放声音时解压缩或者在游戏开始时解压缩,这可能需要占用一段时间。在大多数情况下,增加了一些额外的MB到您的游戏不会影响很大,但如果你想和我一样确保游戏尽可能小而不丧失任何功能或任何质量下降,你仍将尝试压缩所有文件直到一切足够小但仍听起来不错。
我还压缩本书中所有游戏使用到的所有纹理,使用不同的格式以找出一个最佳的格式。例如,菜单和图形界面使用PNG格式,因为它以无损方式储存点阵图,但对模型纹理或场景纹理来说png文件太大。在这种情况下使用DDS格式,这也有利于节省显存,这对Xbox 360来说是很重要的。不要浪费你的主内存,磁盘空间或显存——它们在游戏机平台上是宝贵的。
例如,Rocket Commander游戏使用了约15个声音文件(见图9-3),使用了压缩使得小了大约1MB。
基本知识和文件格式讲完了,下面您将在XACT中创建首个声音项目了。