我有一个运行在Silverlight环境下的XNA街机游戏。游戏中有几个声音片段,以随机顺序播放作为背景音乐。
如http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.media.songcollection.aspx所述,开发人员无法完全控制Media Player。特别是,开发人员无法创建他们的歌曲集合或将歌曲添加到播放队列。建议通过调用MediaPlayer.Play()一次播放一首歌曲。
这正是我正在做的事情,但每当另一首歌开始播放时我就会遇到性能缺陷。尽管在游戏初始化过程中加载了所有声音片段,但在运行时没有加载,所以当我调用MediaPlayer.Play()时,游戏会暂停一段时间。这仅在某些设备上发生(例如HTC Mozart)。相反,如果我在运行游戏时禁用游戏声音并在手机的音乐播放器中播放相同的剪辑,则歌曲更改期间不会出现性能问题。如果我们使用SoundEffect类播放剪辑,我也不会遇到性能问题。但是,由于两个原因,我非常愿意将MediaPlayer用于背景声音目的: - 播放完成后,SoundEffect不会发出通知 - SoundEffect似乎不适用于.mp3文件,使用.wav文件非常昂贵
我还运行了性能分析测试,确认性能时间不佳的帧在MediaPlayer.Play()之后的几毫秒内开始,并在大约0.4秒内继续。在此期间,我的游戏不执行任何重量级操作,只需常规游戏计时器的Update()函数。
以下是我的代码段:
public void PlayBackgroundMusic(Song song)
{
if ((!(App.Current as App).AppModel.SoundDisabled) && (song != null))
{
if (MediaPlayer.State != MediaState.Stopped)
{
StopBackgroundMusic();
}
MediaPlayer.Play(song);
}
}
public void StopBackgroundMusic()
{
MediaPlayer.Stop();
}
和处理程序:
private void OnMediaStateChanged(object sender, EventArgs e)
{
if (MediaPlayer.State != MediaState.Playing)
{
if (!AppModel.SoundDisabled)
{
int index = soundRandomizer.Next(0, sounds.Length - 1);
PlayBackgroundMusic(sounds[index]);
}
}
}
有什么建议吗?
答案 0 :(得分:1)
毕竟,我找到了一个我满意的解决方案。它几乎完全消除了摇晃。它的想法是在从线程池获得的单独线程中使用每个MediaPlayer API。我不知道它是如何解决这个问题的,但这对我很有用:
public void PlayBackgroundMusic(Song song)
{
if ((!(App.Current as App).AppModel.SoundDisabled) && (song != null))
{
if (MediaPlayer.State != MediaState.Stopped)
{
StopBackgroundMusic();
}
ThreadPool.QueueUserWorkItem((o) =>
{
MediaPlayer.Play(song);
}
}
}
public void StopBackgroundMusic()
{
ThreadPool.QueueUserWorkItem((o) =>
{
MediaPlayer.Stop();
}
}