近期发布
专辑列表

Windows Phone 游戏合集
JQueryElement
IEBrowser
WPXNA

使用 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

posted @ 2013-05-30 13:28  麦丝平方  阅读(1123)  评论(0编辑  收藏  举报