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


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
(完)

转载于:https://www.cnblogs.com/315358525/archive/2009/09/04/1560162.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值