• [翻译]XNA 3.0 Game Programming Recipes之fiftyone



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

                                                                  7-4 循环声音
    问题
                                     你想要循环声音去播放背景音乐或者播放一个持续的声音,例如汽车引擎的噪音。
    注意:由于Zune不支持XACT,你想要使用三个重载的SoundEffect.Play()方法去循环你的声音,正如7-1节相应的内容。
    解决方案
                                     使用XACT声音工具,它是非常的容易去表示一个声音应该持续循环。你想要去创建并跟踪Cue对象在你的XNA代码,因为你需要能够暂停或者停止正在播放的声音。
                                     你同样可以编程的方式检测当一个声音是否已经完成了播放,这是非常有用的,如果你想要选择背景音乐。通过检查Cue的IsStopped成员来实现这个。
    它是如何实现的

    Looping a Sound Indefinitely(无限循环一个声音)
                                     你可以很容易产生一个循环通过设置它的LoopEvent属性到Infinite在XACT音频工具。为了实现这个,打开你的XACT项目,并且选择在你的sound bank中这个你想要循环的声音。一旦你已经选择这个声音,这Play Wave的条目应该可见在Sound Bank 框架的右上角。点击Play Wave节点,如图7-2显示的。
                                     在点击Play Wave节点,它的属性应该可见在属性合子里在你的XACT窗口的左下角。找到LoopEvent属性,并设置它到Infinite.确保你保存你的XACT属性。

                                     现在,当你重新编译你的XNA项目并且播放cue使用从前面中的代码,它将无限循环。由于你想要某些种类的控制,它允许你去停止cue,你需要创建一个Cue对象去保存一个相关的cue:
    1 Cue cue1;
                                     填充这个对象通过调用GetCue方法在你的soundBank变量中。在这个Cue对象,你可以调用这个Play方法去开始一个cue:
    1 cue1=soundBank.GetCue("audio1");
    2 cue1.Play();
                                     这将开始无限播放cue,正如你定义在XACT音频工具。只在这时,你有一个相关的cue,你可以使用它暂停,重新开始,或者停止这个cue:
    1 cue1.Pause();
    2 cue1.Resume();
    3 cue1.Stop(AudioStopOptions.Immediate);

    注意:在你已经停止一个正在播放的cue,你不可以简单的调用Play在cue上。你首先需要从soundBank通过调用它的GetCue方法去加载它

    Checking Whether a Sound Has Finished Playing/Changing Background Music
                                     通过它的IsStopped属性,你可以检查一个声音cue是否已经播放:

    1 if(currentCue.IsStopped)
    2     //do something
                                     如果你想要你的XNA项目去通过一些背景声音来循环,你应该创建一个数组去保留cues的名字,并且不是cues它们自己,一旦它们已经播放,它将是没有用的。你需要这些额外变量去创建一个背景循环系统:
    1 string[] bgCueNames;
    2 Cue currentCue;
    3 int currentCueNr=0;
                                     这个数组将保留被播放的背景cues的名字。currentCue将保留这个正在播放的cue,这样你可以检查是否它被完成了,并且currentCueNr变量被需要的,这样你的程序可以激活下一个cue.
                                     这个方法它初始化cue名字的数组,并且开始第一个cue:
     1 private void InitSounds()
     2 {
     3      audioEngine=new AudioEngine("Content/Audio/MyXACTproject.xgs");
     4      waveBank=new WaveBank(audioEngine,"Content/Audio/myWaveBank.xwb");
     5      soundBank=new SoundBank(audioEngine,"Content/Audio/mySoundBank.xsb");
     6      bgCueNames=new string[5];
     7      bgCueNames[0]="bgAudio1";
     8      bgCueNames[1]="bgAudio2";
     9      bgCueNames[2]="bgAudio3";
    10      bgCueNames[3]="bgAudio4";
    11      bgCueNames[4]="bgAudio5";
    12      PlayBGCue(0);
    13 }
                                     你首先不得不创建一个XACT项目,如图7-1所示,包含五个cues.这个PlayBGCue方法,他实际上开始一个cue很容易:
    1 private void PlayBGCue(int cueNr)
    2 {
    3     currentCue=soundBank.GetCue(bgCueNames[cueNr]);
    4     currentCue.Play();
    5 }
                                     它保存一个相关的当前播放的cue在currentCue变量中,这样你可以检查它的IsPlayed属性在一个UpdateSounds方法中,这样你可以从你的主Update方法中调用:
    Code

                                     如果当前的cue已经正在播放了,你增加currentCueNr,同时设置它回到0,如果已经比可播放cues的数量大,在这种情况下是5。最后,你调用PlayBGCue,所以下一个音频开始播放。
    注意:在currentCueNr之前++表示你想要currentCueNr的值去增加在整个行前得到评估。如果你写了currentCueNr++,这个条件将会是false,如果currentCueNr是4,并且在此之后,这个值增加到5,这将得到一个OutOfRange异常在GetCue方法中。通过写++currentCueNr,如果currentCueNr是4,这个值首先增加到5,这样这个条件将会是true,并且值将重新设置成0。
                                     通过把Update访问在这个方法中的audioEngine,在这个Update方法中所有你不得不调用的是UpdateSounds方法。

    代码
                                    直到你可以找到所有的代码为本章前面这个背景播放列表的循环,下面的代码开始一个循环默认的声音在这节的第一部分,通过压下空格键并且通过Enter键结束它:

     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     KeyboardState keyState=Keyboard.GetState();
     7     if(keyState.IskeyDown(Keys.Space)||(gamePadState.Buttons.B==ButtonState.Pressed))
     8     {
     9         if((cue1==null)||(cue1.IsStopped))
    10         {
    11             cue1=soundBank.GetCue("audio1");
    12             cue1.Play(); 
    13         }
    14     }
    15     if(keyState.IsKeyDown(Keys.Enter)||(gamePadState.Buttons.A==ButtonState.Pressed))
    16             if(cue1!=null)
    17                 cue1.Stop(AudioStopOptions.Immediate);
    18     audioEngine.Update();
    19     base.Update(gameTime);
    20 }
                                     首先空格键被压下,这个cue1变量将会是null。当用户压下Enter键,这个cue被停止。当用户再次压下空格键,这个cue被重新设置。
                                     再一次,注意,你需要去重新创建这个cue1变量(通过调用GetCue方法)在cue已经停止之后。
    源代码:http://shiba.hpe.cn/jiaoyanzu/WULI/soft/xna.aspx?classId=4
    (完)
  • 相关阅读:
    超详细的Chrome插件Vimium使用教程!
    Chrome浏览器快捷键详细介绍,让你摆脱鼠标的束缚!
    为什么你的电脑越来越卡?很可能是因为这个!
    像黑客一样用命令打开应用!
    电脑桌面乱?看完这篇文章是不存在这种情况的!
    任务栏简化,让你的任务栏更美观!
    USB无法识别?简单详细的驱动程序安装教程!
    文件扩展名是什么?有什么用?通俗易懂的文件扩展名讲解!
    Win2008 IIS7.5安装配置PHP7.3.2步骤,及500错误解决
    用命令行方式关闭CentOS防火墙
  • 原文地址:https://www.cnblogs.com/315358525/p/1560155.html
Copyright © 2020-2023  润新知