使用 AudioManager 类在 XNA 中播放控制声音和音乐,WPXNA(五)
平方已经开发了一些 Windows Phone 上的一些游戏,算不上什么技术大牛。在这里分享一下经验,仅为了和各位朋友交流经验。平方会逐步将自己编写的类上传到托管项目中,没有什么好名字,就叫 WPXNA 吧,最后请高手绕道而行吧,以免浪费时间。(为了突出重点和减少篇幅,有些示例代码可能不够严谨。)
管理音频
在 XNA 中,你可以通过 SoundEffectInstance,SoundEffect 或者 MediaPlayer 类播放音频,其中 SoundEffectInstance 和 SoundEffect 都可以用来播放一些短小的声音文件,但他们也存在细微的差别,可以参考 XNA 中 SoundEffect 与 SoundEffectInstance 的区别。MediaPlayer 可以播放 mp3 等时间较长的文件。
为了管理这些音频,平方创建了 AudioManager 类。首先,我们需要载入所需要的资源:
private readonly Dictionary<string, SoundEffectInstance> sounds = new Dictionary<string, SoundEffectInstance> ( ); private readonly Dictionary<string, Song> music = new Dictionary<string, Song> ( ); internal void LoadContent ( ResourceManager resourceManager ) { if ( null == resourceManager ) return; foreach ( Resource resource in resourceManager.Resources ) if ( resource.Type == ResourceType.Sound ) this.sounds.Add ( resource.Name, resourceManager.GetSound ( resource.Name ) ); else if ( resource.Type == ResourceType.Music ) this.music.Add ( resource.Name, resourceManager.GetMusic ( resource.Name ) ); }因为,我们所有的资源都是通过 ResourceManager 管理和加载的,所以这里的 LoadContent 方法将获取 ResourceManager 中所有类型为 Sound 和 Music 的资源,并将他们分别保存到字段 sounds 和 music 中。
我们并不需要去释放音频资源,因为他们都是被 ResourceManager 来管理的,所以在 AudioManager 的 UnloadContent 方法中,我们只需要停止音频的播放即可。
internal void UnloadContent ( ) { this.StopAllSound ( ); this.StopMusic ( ); this.sounds.Clear ( ); this.music.Clear ( ); } internal void StopAllSound ( ) { foreach ( SoundEffectInstance sound in this.sounds.Values ) sound.Stop ( ); } internal void StopMusic ( ) { if ( !MediaPlayer.GameHasControl || !this.isMusicPlaying ) return; MediaPlayer.Stop ( ); this.isMusicPlaying = false; }在上面的代码中,StopAllSound 和 StopMusic 方法,分别用来停止播放声音和音乐。对于方法 StopMusic,我们使用了类 MediaPlayer,因此,我需要使用属性 GameHasControl 判断游戏对 Media Player 的控制权。此外,你还需要在 WMAppManifest.xml 文件中,增加一个功能 ID_CAP_MEDIALIB,否则将不能播放音乐:
使用 PlaySound 和 PlayMusic 来播放音频,其中,你可以使用 isLoop 参数来指定是否循环播放音乐。每一次你调用 PlayMusic 都会立刻从开始播放音乐。
internal void PlaySound ( string name ) { if ( !IsSoundOn || string.IsNullOrEmpty ( name ) || !this.sounds.ContainsKey ( name ) ) return; if ( this.sounds[name].State != SoundState.Playing ) this.sounds[name].Play ( ); } internal void PlayMusic ( string name, bool isLoop ) { if ( !IsMusicOn || !MediaPlayer.GameHasControl || string.IsNullOrEmpty ( name ) || !this.music.ContainsKey ( name ) ) return; if ( MediaPlayer.State != MediaState.Stopped ) MediaPlayer.Stop ( ); try { MediaPlayer.Play ( this.music[name] ); MediaPlayer.IsRepeating = isLoop; this.isMusicPlaying = true; } catch { } }字段 IsSoundOn 和 IsMusicOn 用来控制是否播放声音和音乐。
internal static bool IsSoundOn = true; internal static bool IsMusicOn = true;
使用 AudioManager
像以前的例子一样,我们需要定义一个 ResourceManager。
private readonly ResourceManager resourceManager; private readonly AudioManager audioManager; private int step = 1;在构造函数中,我们定义所需要的音频资源并创建 AudioManager。
public World ( Color backgroundColor ) : base ( ) { // ... this.resourceManager = new ResourceManager ( new Resource[] { new Resource ( "click.s", ResourceType.Sound, @"sound\click" ), new Resource ( "music1", ResourceType.Music, @"sound\music1" ) } ); this.resourceManager.World = this; this.audioManager = new AudioManager ( ); }页面载入后,我们使用 ResourceManager 载入所有资源,并将资源传递给 AudioManager,这样 AudioManager 就可以控制音频了。
protected override void OnNavigatedTo ( NavigationEventArgs e ) { // ... this.resourceManager.LoadContent ( ); this.audioManager.LoadContent ( this.resourceManager ); base.OnNavigatedTo ( e ); }最后,平方编写了一段简单的代码。
private void OnUpdate ( object sender, GameTimerEventArgs e ) { this.step++; if ( this.step <= 60 ) this.audioManager.PlaySound ( "click.s" ); else if ( this.step == 61 ) this.audioManager.PlayMusic ( "music1" ); else if ( this.step == 300 ) this.audioManager.StopMusic ( ); }
本期视频 http://v.youku.com/v_show/id_XNTYzODcwMDYw.html
项目地址 http://wp-xna.googlecode.com/
更多内容 WPXNA
平方开发的游戏 http://zoyobar.lofter.com/
QQ 群 213685539
欢迎访问我在其他位置发布的同一文章:http://www.wpgame.info/post/decc4_65cbf7
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架