2010-04-19 39 views
3

我有这样的:C#XP声音的QuickFix

ThreadPool.QueueUserWorkItem(new WaitCallback(FireAttackProc), fireResult); 

和FireAttackProc:

private void FireAttackProc(Object stateInfo) 
    { 
     // Process Attack/Fire (local) 
     lock (_procLock) 
     { 
      // build status message 
      String status = "(Away vs. Home)"; 

      // get Fire Result state info 
      FireResult fireResult = (FireResult)stateInfo; 

      // update home grid with attack information 
      GameModel.HomeCellStatusSet(fireResult.FireGridLocation, Cell.cellState.Lock); 
      this.Invoke(new Action(delegate() { RefreshHomeGrid(); })); 

      status = status + "(Attack Coordinate: (" + GameModel.alphaCoords(fireResult.FireGridLocation.Column) + 
       "," + fireResult.FireGridLocation.Row + "))(Result: "; 

      // play audio data if true 
      if (audio) 
      { 
       String Letters; 

       Stream stream; 
       SoundPlayer player; 

       Letters = GameModel.alphaCoords(fireResult.FireGridLocation.Column); 
       stream = Properties.Resources.ResourceManager.GetStream("_" + Letters); 
       player = new System.Media.SoundPlayer(stream); 
       player.PlaySync(); 


       Letters = fireResult.FireGridLocation.Row.ToString(); 
       stream = Properties.Resources.ResourceManager.GetStream("__" + Letters); 
       player = new System.Media.SoundPlayer(stream); 
       player.PlaySync(); 

       stream.Dispose(); 
       player.Dispose(); 
      } 

      if (audio) 
      { 
       SoundPlayer fire = new SoundPlayer(Properties.Resources.fire); 
       fire.PlaySync(); 
       fire.Dispose(); 
      } 

      // deal with hit/miss 
      switch (fireResult.Hit) 
      { 
       case true: 
        this.Invoke(new Action(delegate() 
        { 
         GameModel.HomeCellStatusSet(fireResult.FireGridLocation, Cell.cellState.Hit); 
         status = status + "(Hit)"; 
        })); 

        if (audio) 
        { 
         SoundPlayer hit = new SoundPlayer(Properties.Resources.firehit); 
         hit.PlaySync(); 
         hit.Dispose(); 

        } 
        break; 

       case false: 
        this.Invoke(new Action(delegate() 
        { 
         GameModel.HomeCellStatusSet(fireResult.FireGridLocation, Cell.cellState.Miss); 
         status = status + "(Miss)"; 
        })); 

        GameModel.PlayerNextTurn = NietzscheBattleshipsGameModel.GamePlayers.Home; 

        if (audio) 
        { 
         SoundPlayer miss = new SoundPlayer(Properties.Resources.firemiss); 
         miss.PlaySync(); 
         miss.Dispose(); 
        } 
        break; 
      } 

      // refresh home grid with updated data 
      this.Invoke(new Action(delegate() { RefreshHomeGrid(); })); 

      GameToolStripStatusLabel.Text = status + ")"; 

      // deal with ship destroyed 
      if (fireResult.ShipDestroyed) 
      { 
       status = status + "(Destroyed: " + GameModel.getShipDescription(fireResult.DestroyedShipType) + ")"; 

       if (audio) 
       { 
        Stream stream; 
        SoundPlayer player; 

        stream = Properties.Resources.ResourceManager.GetStream("_home"); 
        player = new System.Media.SoundPlayer(stream); 
        player.PlaySync(); 
        player.Dispose(); 
        stream.Dispose(); 

        string ShipID = fireResult.DestroyedShipType.ToString(); 
        stream = Properties.Resources.ResourceManager.GetStream("_" + ShipID); 
        player = new System.Media.SoundPlayer(stream); 
        player.PlaySync(); 
        player.Dispose(); 
        stream.Dispose(); 

        stream = Properties.Resources.ResourceManager.GetStream("_destroyed"); 
        player = new System.Media.SoundPlayer(stream); 
        player.PlaySync(); 
        player.Dispose(); 
        stream.Dispose(); 
       } 
      } 

      // deal with win condition 
      if (fireResult.Win) 
      { 
       if (audio) 
       { 
        Stream stream; 
        SoundPlayer player; 

        stream = Properties.Resources.ResourceManager.GetStream("_home"); 
        player = new System.Media.SoundPlayer(stream); 
        player.PlaySync(); 
        player.Dispose(); 

        stream = Properties.Resources.ResourceManager.GetStream("_loses"); 
        player = new System.Media.SoundPlayer(stream); 
        player.PlaySync(); 
        player.Dispose(); 
       } 

       GameModel.gameContracts = new GameContracts(); 
      } 

      // update status message 
      if (fireResult.Hit) 
      { 
       if (!fireResult.Win) 
       { 
        status = status + "(Turn: Away)"; 

        LockGUIControls(); 
       } 
      } 

      // deal with turn logic 
      if (GameModel.PlayerNextTurn == NietzscheBattleshipsGameModel.GamePlayers.Home) 
      { 
       this.Invoke(new Action(delegate() 
       { 
        if (!fireResult.Win) 
        { 
         status = status + "(Turn: Home)"; 

         AwayTableLayoutPanel.Enabled = true; 
        } 
       })); 
      } 

      // deal with win condition 
      if (fireResult.Win) 
      { 
       this.Invoke(new Action(delegate() 
       { 
        status = status + "(Game: Home Loses)"; 

        CancelToolStripMenuItem.Enabled = false; 
        NewToolStripMenuItem.Enabled = true; 
        LockGUIControls(); 
       })); 
      } 

      // display completed status message 
      GameToolStripStatusLabel.Text = status + ")"; 
     } 
    } 

的问题是这样的:

在VISTA/WIN7的声音片段在FireAttackProc播放。

但是在XP下,FireAttackProc中包含的逻辑被执行,但没有声音片段播放。

有没有一个快速的解决方案,这样声音将在XP下播放?

我要求一个快速解决方案,因为我很高兴能够在Vista/Win7中完全执行,但如果有快速解决方案,那么它会很好,所以它也会是XP兼容的。

谢谢。

+0

你可以验证快报变量总是包含对应于一个完善的资源名称_Let​​ters的东西吗? – 2010-04-28 12:14:06

+0

如果删除(至少暂时)lock() - 块会发生什么?看起来很奇怪,你在_procLock上锁定了这么多的代码。有可能这个锁是禁止你不打算的一些事情:-) – 2010-04-28 12:15:21

+0

@Bob:是的,我已经检查过,没有问题。 lock()在那里实现逻辑流程,即在处理时不处理任何其他内容。 – iTEgg 2010-04-28 12:59:53

回答

1

SoundPlayer真的非常乏味,但这就是所有的.NET 2.0自带的。试试我的播放器(基于this article)代替,它使用MCI播放声音:

http://pastebin.com/aVDWBJ45

您可以使用其他音频编解码器(如MP3),而你只需要加载该文件一次(而不是每次攻击都会导致延迟)。你可以在不创建额外线程的情况下异步播放声音。

它真的很容易使用。只需创建一个新的QueuedSamplesPlayer,其中包含任何想要识别声音的通用参数(例如enumstringint)。使用AddSample方法在启动时加载所有声音。然后分别使用PlayPlayAsync来同步或异步播放文件。

您可以多次呼叫PlayAsync,并且声音会依次播放(不会阻塞当前线程)。在播放声音时,您甚至可以拨打PlayAsync,并将其添加到要播放的声音队列中。当所有声音播放完毕后,将会引发QueueEmpty事件。

这款播放器已经过测试,在Windows XP,Vista和7