您的位置:首页 > 其它

[翻译]XNA 3.0 Game Programming Recipes之fifty-two

2009-09-04 11:12 633 查看



PS:自己翻译的,转载请著明出处

7-5 从相对于相机的3D位置播放一个声音:3D声音
问题
为了添加一些更多的真实感觉到你的3D游戏中,你想要能够给你每个声音一个3D空间的位置。这样,一个爆炸在你的相机的右边,将会在右边的扬声器里播放,这样悠忽得到爆炸的效果仿佛真的在右边。甚至如果爆炸不在相机的视景内,用户将可能知道某些发生在他的右边。
注意:直到Zune不支持XACT工具,并且使用的Apply3D()方法在下面的解决方案里,只接收Cue对象,3D声音只支持在PC上和Xbox360上。

解决方案

XNA已经使这些变的很容易。每一个声音,你不得不设置相机的3D位置和声音的初始位置,使用声音的Cue对象的Apply3D方法。注意,每一次相机或者声源移动了,你需要去更新你的Cue通过调用这个方法。
它是如何实现的
如果你想要设置声源的3D位置,你首先需要创建一个AudioEmitter对象为这个声源和AudioListener对象为你的相机。当你传递Cue的Applay3D方法,XNA将计算这个声音是如何分布在连接在你系统里的扬声器中(或者耳机中)。
这个方法创建两个对象:

1 private void UpdateSoundPosition(Cue cue,Vector3 sourcePos,Vector3 camPos,Vector3 camForward,Vector3 camUp)
2 {
3 AudioEmitter emitter=new AudioEmitter();
4 emitter.Position=sourcePos;
5 AudioListenter listener=new AudioListener();
6 listener.Position=camPos;
7 listener.Forward=camForward;
8 listener.Up=camUp;
9 cue.Apply3D(listener,emitter);
10 } 为了这个发射器(你的声源),你只需要去设置位置。为了听众(你的相机),虽然,你同样需要设置前面和Up向量,因为,当这个相机被旋转了180度,左右转换。
当你已经创建并添满两个对象,你可以传递它们到Cue的Apply3D方法中。这需要被做无论声源或者你的相机的移动。
你需要调用这个Apply3D方法在你首先调用cue的Play方法之前。因此,确保你不调用Play在你的Cue上:
1 protected override void Initialize()
2 {
3 fpsCam=new QuakeCamera(GraphicsDevice.Viewport,new Vector3(0,0,5),0,0);
4 audioEngine=new AudioEngine("Content/Audio/MyXACTproject.xgs");
5 waveBank=new WaveBank(audioEngine,"Content/Audio/myWaveBank.xwb");
6 soundBank=new SoundBank(audioEngine,"Content/Audio/mySoundBank.xsb");
7 cue1=soundBank.GetCue("audio1");
8 base.Initialize();
9 } 在你的Update方法中,无论你更新你的相机的位置或者声源的位置,你应该调用UpdateSoundPosition方法:
1 protected override void Update(GameTime gameTime)
2 {
3 GamePadState gamePadState=GamePad.GetState(PlayerIndex.One);
4 if(gamePadState.Buttons.Back==ButtonState.Pressed)
5 this.Exit();
6 MouseState mouseState=Mouse.GetState();
7 KeyboardState keyState=keyboard.GetState();
8 fpsCam.Update(mouseState,keyState,gamePadState);
9 float time=(float)gameTime.TotalGameTime.TotalMillseconds/1000.0f;
10 Vector3 startingPos=new Vector3(0,0,-10);
11 Matrix rotMatrix=Matrix.CreateRotationY(time);
12 modelPos=Vector3.Transform(startingPos,rotMatrix);
13 UpdateSoundPosition(cue1,modelPos,fpsCam.Position,fpsCam.Forward,fpsCam.UpVector);
14 if(cue1.IsPrepared)
15 cue1.Play()p;
16 audioEngin.Update();
17 base.Update(gameTime);
18 }
这个方法的上半部分检查用户的输入和传递这个输入到你的3D相机里,如2-3节所解释的。代码的中间块更新你的声源的位置。随着你的相机和声源更新,你应该调用UpdateSoundPosition方法,这样你的cue1对象通知最近的位置。如果你的cue1没有正在播放,现在就开始播放它。
注意:3D效果通过控制单独的左右扬声器的音量实现。意思是任何在这个声音中的立体声信息将会丢失:首先这个声音被转换为单声道,然后左右音量被相应设置到对象的3D位置。

代码
(略)
课外阅读
这个XACT音频工具允许你去图形化添加一些非常不错的3D声音效果到你的cues中,例如距离的衰减和多铺勒转换。因为这是通过图象完成的,这可以证明一个电影比一本书好多了:http://creators.xna.com/站点包含很多非常不错的电影在添加3D声音效果到你的cues上!
源代码:http://shiba.hpe.cn/jiaoyanzu/WULI/soft/xna.aspx?classId=4
(完)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: