执行线程和WindowsMediaPlayer导致屏幕闪烁和滞后

时间:2014-01-26 17:30:08

标签: c# multithreading windows-media-player slimdx wmp

我一直试图在我的C#2D游戏引擎中找出一个恼人的性能错误。

只有当我启用声音时才会发生这种情况,而我正试图找出我做错了什么。我怀疑有很多东西,因为声音功能是在很久以前实现的,以实现基本功能。在发展的这个阶段,现在是一个更高的优先事项。我需要解决它。

当我实现声音时,它经过了大量的声音API实验。我尝试过SoundPlayer,MediaPlayer和WindowsMediaPlayer--后者是唯一一个我能以可接受的方式工作的人。

我的实施基于为我想要播放的每种声音设置一系列播放器。它们都是预先实例化的。使用它们的方法是:

  1. 搜索播放器数组,直至找到当前未播放的播放器阵列。

  2. 播放声音。

  3. 现在由于某些原因,我无法弄清楚,这个实现导致了一个奇怪的问题。我有一种方法可以在你死的时候开火,而且从我能说的这个方法来说,这听起来并没有任何声音。它基本上等了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
        }       
    

    我知道这很笨重,但它在当时有效 - 反正还不够好。任何人都可以看到任何可以解释我屏幕闪烁的原因吗?

    我的线程专业知识目前非常基础。

    提前致谢

0 个答案:

没有答案