2013-03-19 156 views
0

每當我在遊戲中播放聲音時,線程會在聲音播放完畢後繼續凍結。代碼聲音引擎:java中的聲音 - 播放聲音時遊戲會凍結

package com.kgt.platformer; 

import java.io.File; 
import java.io.IOException;  
import javax.sound.sampled.AudioFormat; 
import javax.sound.sampled.AudioInputStream; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.DataLine; 
import javax.sound.sampled.LineUnavailableException; 
import javax.sound.sampled.SourceDataLine; 

public class Sound { 
    private final static int BUFFER_SIZE = 12800000; 
    private static File soundFile; 
    private static AudioInputStream audioStream; 
    private static AudioFormat audioFormat; 
    private static SourceDataLine sourceLine; 

    /** 
    * 
    * @param filename the name of the file that is going to be played 
    * 
    */ 
    public static void playSound(String filename){ 

     String strFilename = filename; 

     try { 
      soundFile = new File(strFilename); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      System.exit(1); 
     } 

     try { 
      audioStream = AudioSystem.getAudioInputStream(soundFile); 
     } catch (Exception e){ 
      e.printStackTrace(); 
      System.exit(1); 
     } 

     audioFormat = audioStream.getFormat(); 

     DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat); 
     try { 
      sourceLine = (SourceDataLine) AudioSystem.getLine(info); 
      sourceLine.open(audioFormat); 
     } catch (LineUnavailableException e) { 
      e.printStackTrace(); 
      System.exit(1); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      System.exit(1); 
     } 


     sourceLine.start(); 

     int nBytesRead = 0; 
     byte[] abData = new byte[BUFFER_SIZE]; 
     while (nBytesRead != -1) { 
      try { 
       nBytesRead = audioStream.read(abData, 0, abData.length); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      if (nBytesRead >= 0) { 
       @SuppressWarnings("unused") 
       int nBytesWritten = sourceLine.write(abData, 0, nBytesRead); 
      } 
     } 

     sourceLine.drain(); 
     sourceLine.close(); 
    } 
} 

什麼結束了發生的事情是我開始遊戲,它播放聲音,遊戲凍結然後繼續。

+4

如果你不想讓遊戲阻塞,那你爲什麼要調用['drain'方法](http://docs.oracle.com/javase/6/docs/api/javax/聲音/採樣/ DataLine.html#漏極%28%29)? – ruakh 2013-03-19 18:25:38

回答

4

您可以啓動一個線程來處理流的讀寫。看看這裏: How can I play sound in Java?

示例代碼:

基於
new Thread(new Runnable() { 
    public void run() { 
    Sound.playSound("Test.wav"); 
    } 
}.start(); 
+0

嘿thx,它的工作! – user1979117 2013-03-19 18:39:44

1

一個Java聲音Clip使用它自己的進程(daemon)Thread。看到這個例子,它將在一個循環2剪輯(雖然被警告,關掉音量)。還要注意,第二個剪輯需要一些時間來加載。等到你看到JOptionPane - 那麼這兩個剪輯應該循環。

import java.net.URL; 
import javax.swing.*; 
import javax.sound.sampled.*; 

public class LoopSounds { 

    public static void main(String[] args) throws Exception { 
     URL url1 = new URL(
      "http://pscode.org/media/leftright.wav"); 
     URL url2 = new URL("http://pscode.org/media/100_2817-linear.wav"); 
     Clip clip1 = AudioSystem.getClip(); 
     Clip clip2 = AudioSystem.getClip(); 
     // getAudioInputStream() also accepts a File or InputStream 
     AudioInputStream ais1 = AudioSystem. 
      getAudioInputStream(url1); 
     clip1.open(ais1); 
     clip1.loop(Clip.LOOP_CONTINUOUSLY); 

     AudioInputStream ais2 = AudioSystem. 
      getAudioInputStream(url2); 
     clip2.open(ais2); 
     clip2.loop(Clip.LOOP_CONTINUOUSLY); 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       // A GUI element to prevent the Clip's daemon Thread 
       // from terminating at the end of the main() 
       JOptionPane.showMessageDialog(null, "Close to exit!"); 
      } 
     }); 
    } 
}