我一直试图在我的C#2D游戏引擎中找出一个恼人的性能错误。
只有当我启用声音时才会发生这种情况,而我正试图找出我做错了什么。我怀疑有很多东西,因为声音功能是在很久以前实现的,以实现基本功能。在发展的这个阶段,现在是一个更高的优先事项。我需要解决它。
当我实现声音时,它经过了大量的声音API实验。我尝试过SoundPlayer,MediaPlayer和WindowsMediaPlayer--后者是唯一一个我能以可接受的方式工作的人。
我的实施基于为我想要播放的每种声音设置一系列播放器。它们都是预先实例化的。使用它们的方法是:
搜索播放器数组,直至找到当前未播放的播放器阵列。
播放声音。
现在由于某些原因,我无法弄清楚,这个实现导致了一个奇怪的问题。我有一种方法可以在你死的时候开火,而且从我能说的这个方法来说,这听起来并没有任何声音。它基本上等了5秒才重新开始游戏。但是,随着屏幕上的声音闪烁一毫秒,锐利发展的东西会刷新,就好像游戏中突然出现延迟一样。从功能的角度来看,我没有问题 - 但性能是不可接受的。
为了让您知道我在做什么,这里有一些来自我的声音初始化方法的代码:
if(soundLibrary=="WindowsMediaPlayer")
{
// Music player
WMP_Music = new WMPLib.WindowsMediaPlayer();
WMP_Music.settings.autoStart = false;
WMP_Music.URL = "D:\\Programming\\SFX\\MUSIC\\IN_GAME_1.wav";
// Array of players ----------------------------------------
WMP_EATEN_GHOST_Array = new WMPLib.WindowsMediaPlayer[EATEN_GHOST_noOfPlayers];
WMP_EATEN_PILL_Array = new WMPLib.WindowsMediaPlayer[EATEN_PILL_noOfPlayers];
WMP_EATEN_POWERPILL_Array = new WMPLib.WindowsMediaPlayer[EATEN_POWERPILL_noOfPlayers];
WMP_KILLED_BY_GHOST_Array = new WMPLib.WindowsMediaPlayer[KILLED_BY_GHOST_noOfPlayers];
for(int i=0;i<WMP_EATEN_GHOST_Array.Length;i++)
{
WMP_EATEN_GHOST_Array[i] = new WMPLib.WindowsMediaPlayer();
WMP_EATEN_GHOST_Array[i].settings.autoStart = false;
WMP_EATEN_GHOST_Array[i].URL = "D:\\Programming\\SFX\\EATEN_GHOST\\Hit_55.wav";
WMP_EATEN_PILL_Array[i] = new WMPLib.WindowsMediaPlayer();
WMP_EATEN_PILL_Array[i].settings.autoStart = false;
WMP_EATEN_PILL_Array[i].URL = "D:\\Programming\\SFX\\EATEN_PILL\\Hit_43_s.wav";
WMP_EATEN_POWERPILL_Array[i] = new WMPLib.WindowsMediaPlayer();
WMP_EATEN_POWERPILL_Array[i].settings.autoStart = false;
WMP_EATEN_POWERPILL_Array[i].URL = "D:\\Programming\\SFX\\EATEN_POWERPILL\\Hit_49.wav";
WMP_KILLED_BY_GHOST_Array[i] = new WMPLib.WindowsMediaPlayer();
WMP_KILLED_BY_GHOST_Array[i].settings.autoStart = false;
WMP_KILLED_BY_GHOST_Array[i].URL = "D:\\Programming\\SFX\\KILLED_BY_GHOST\\Hit_55.wav";
}
所以通过这些设置,这里是播放声音的代码:
public void PlayPCM_WindowsMediaPlayer_FX(string effectIn)
{
int i=-1;
bool found = false;
if(soundEnabled)
{
switch(effectIn)
{
case "KILLED_BY_GHOST":
// 1. Choose a media player which is not playing.
i = 0;
do
{
if(WMP_KILLED_BY_GHOST_Array[i].playState == WMPLib.WMPPlayState.wmppsPlaying)
{
// Keep looking
i++;
}
else
{
found = true;
}
} while( (i<WMP_KILLED_BY_GHOST_Array.Length) && (!found));
// Now 'i' holds the index of the player which is not playing.
// 2. Play effect
if(found)
{
Thread thread = new Thread(new ThreadStart( WMP_KILLED_BY_GHOST_Array[i].controls.play ));
thread.Start();
}
break;
case "EATEN_PILL":
// 1. Choose a media player which is not playing.
i = 0;
do
{
if(WMP_EATEN_PILL_Array[i].playState == WMPLib.WMPPlayState.wmppsPlaying)
{
// Keep looking
i++;
}
else
{
found = true;
}
} while( (i<WMP_EATEN_PILL_Array.Length) && (!found));
// Now 'i' holds the index of the player which is not playing.
// 2. Play effect
if(found)
{
Thread thread = new Thread(new ThreadStart( WMP_EATEN_PILL_Array[i].controls.play ));
thread.Start();
}
break;
case "EATEN_GHOST":
// 1. Choose a media player which is not playing.
i = 0;
do
{
if(WMP_EATEN_GHOST_Array[i].playState == WMPLib.WMPPlayState.wmppsPlaying)
{
// Keep looking
i++;
}
else
{
found = true;
}
} while( (i<WMP_EATEN_GHOST_Array.Length) && (!found));
// Now 'i' holds the index of the player which is not playing.
// 2. Play effect
if(found)
{
Thread thread = new Thread(new ThreadStart( WMP_EATEN_GHOST_Array[i].controls.play ));
thread.Start();
}
break;
case "EATEN_POWERPILL":
// 1. Choose a media player which is not playing.
i = 0;
do
{
if(WMP_EATEN_POWERPILL_Array[i].playState == WMPLib.WMPPlayState.wmppsPlaying)
{
// Keep looking
i++;
}
else
{
found = true;
}
} while( (i<WMP_EATEN_POWERPILL_Array.Length) && (!found));
// Now 'i' holds the index of the player which is not playing.
// 2. Play effect
if(found)
{
Thread thread = new Thread(new ThreadStart( WMP_EATEN_POWERPILL_Array[i].controls.play ));
thread.Start();
}
break;
} // switch
} // soundEnabled
}
我知道这很笨重,但它在当时有效 - 反正还不够好。任何人都可以看到任何可以解释我屏幕闪烁的原因吗?
我的线程专业知识目前非常基础。
提前致谢