使用javax.sound.sampled.Clip在游戏中播放,循环和停止多个声音。 意外错误

我正试图在游戏中同时播放两个wav声音(背景音乐和效果)。 我首先使用java中的另一个音频处理程序构建了这段代码,它将处理声音的播放,停止和循环。 此构造将播放背景音乐或效果,但一次只能播放一个。 我环顾互联网并被告知使用javax.sound.sampled.Clip处理声音,因此重复使用相同的构造(播放,停止,循环),但将其切换为使用javax.sound.sampled.Clip。 现在我完全迷失了。 从我到目前为止所读到的,我已经完成了一切正确的操作并且在eclipse编辑器中没有出现任何错误,但是当我运行它时,我得到了两个错误之一。 在eclipse(在Linux上运行)中抛出LineUnavailableException。 在eclipse(在Windows 7上运行)中,我在此代码的loop()部分中获得了java.lang.NullPointerException。 如果你能告诉我我做错了什么,或者给我一些相关文档,我会很感激。 我假设我的代码处理exception,但我不确定。 如果你看到任何其他可怕的代码失误,请让我知道我正在努力成为最好的程序员,我真的很感激建设性的批评。 感谢您的时间。

import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.UnsupportedAudioFileException; /** * Handles play, pause, and looping of sounds for the game. * @author Tyler Thomas * */ public class Sound { private Clip myClip; public Sound(String fileName) { try { File file = new File(fileName); if (file.exists()) { Clip myClip = AudioSystem.getClip(); AudioInputStream ais = AudioSystem.getAudioInputStream(file.toURI().toURL()); myClip.open(ais); } else { throw new RuntimeException("Sound: file not found: " + fileName); } } catch (MalformedURLException e) { throw new RuntimeException("Sound: Malformed URL: " + e); } catch (UnsupportedAudioFileException e) { throw new RuntimeException("Sound: Unsupported Audio File: " + e); } catch (IOException e) { throw new RuntimeException("Sound: Input/Output Error: " + e); } catch (LineUnavailableException e) { throw new RuntimeException("Sound: Line Unavailable: " + e); } } public void play(){ myClip.setFramePosition(0); // Must always rewind! myClip.loop(0); myClip.start(); } public void loop(){ myClip.loop(Clip.LOOP_CONTINUOUSLY); } public void stop(){ myClip.stop(); } } 

我能够使代码工作,现在可以更好地理解Clips。 帮助我最多的页面是http://www3.ntu.edu.sg/home/ehchua/programming/java/J8c_PlayingSound.html它打破了一切,帮助我看到了我犯错误的地方。 这是我最后的工作代码。 如果你看到任何可怕的错误或逻辑或风格的景点让我知道。

 import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.UnsupportedAudioFileException; /** * Handles playing, stoping, and looping of sounds for the game. * @author Tyler Thomas * */ public class Sound { private Clip clip; public Sound(String fileName) { // specify the sound to play // (assuming the sound can be played by the audio system) // from a wave File try { File file = new File(fileName); if (file.exists()) { AudioInputStream sound = AudioSystem.getAudioInputStream(file); // load the sound into memory (a Clip) clip = AudioSystem.getClip(); clip.open(sound); } else { throw new RuntimeException("Sound: file not found: " + fileName); } } catch (MalformedURLException e) { e.printStackTrace(); throw new RuntimeException("Sound: Malformed URL: " + e); } catch (UnsupportedAudioFileException e) { e.printStackTrace(); throw new RuntimeException("Sound: Unsupported Audio File: " + e); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("Sound: Input/Output Error: " + e); } catch (LineUnavailableException e) { e.printStackTrace(); throw new RuntimeException("Sound: Line Unavailable Exception Error: " + e); } // play, stop, loop the sound clip } public void play(){ clip.setFramePosition(0); // Must always rewind! clip.start(); } public void loop(){ clip.loop(Clip.LOOP_CONTINUOUSLY); } public void stop(){ clip.stop(); } } 

我找到了一种有用的技术来阻止声音。 您可以将这两个类复制下来并自行测试。 尽管如此,clip.stop()方法更像是一种暂停方法。 它会停止播放声音,是的,但它不能清除声音。 结果,声音仍然排队等待播放,并且不能播放新的声音。 因此,使用clip.close()方法将清除此排队数据并允许播放新声音或执行其他操作。 另请注意,在下面的代码中,声音文件被放置在名为“predator.wav”的项目文件夹中。此声音可以是您要使用的任何类型的声音,而不是我选择的声音,但请确保它是.wav格式,声音必须位于项目文件夹的最顶层。

 /* * File: KeyMap.java * Author: Andrew Peturis Chaselyn Langley; UAB EE Students * Assignment: SoundBox - EE333 Fall 2015 * Vers: 1.0.0 10/20/2015 agp - initial coding * * Credits: Dr. Green, UAB EE Engineering Professor */ import java.io.File; import java.io.IOException; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.UnsupportedAudioFileException; public class KeyMap { private char keyCode; private String song; private Clip clip; // Don't allow default constructor private KeyMap() { } public KeyMap(char keyCode, String song) throws LineUnavailableException { this.keyCode = keyCode; this.song = song; // Create an audiostream from the inputstream clip = AudioSystem.getClip(); } public boolean match(char key) { return key == keyCode; } // Play a sound using javax.sound and Clip interface public String play() { try { // Open a sound file stored in the project folder clip.open(AudioSystem.getAudioInputStream(new File(song + ".wav"))); // Play the audio clip with the audioplayer class clip.start(); // Create a sleep time of 2 seconds to prevent any action from occuring for the first // 2 seconds of the sound playing Thread.sleep(2000); } catch (LineUnavailableException | UnsupportedAudioFileException | IOException | InterruptedException e) { System.out.println("Things did not go well"); System.exit(-1); } return song; } // Stop a sound from playing and clear out the line to play another sound if need be. public void stop() { // clip.stop() will only pause the sound and still leave the sound in the line // waiting to be continued. It does not actually clear the line so a new action could be performed. clip.stop(); // clip.close(); will clear out the line and allow a new sound to play. clip.flush() was not // used because it can only flush out a line of data already performed. clip.close(); } } 

 /* * File: SoundBox.java * Author: Andrew Peturis, Chaselyn Langley; UAB EE Students * Assignment: GUI SoundBox - EE333 Fall 2015 * Vers: 1.0.0 09/08/2015 agp - initial coding */ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Scanner; import javax.sound.sampled.LineUnavailableException; /** * * @author Andrew Peturis, Chaselyn Langley * */ public class SoundBox { static Scanner scanner = new Scanner(System.in); //Scanner object to read user input InputStream input; /** * @param args the command line arguments * @throws java.io.IOException */ public static void main(String[] args) throws IOException, LineUnavailableException { String line; Character firstChar; String predator = "predator"; String explosion = "explosion"; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); KeyMap[] keyedSongs = { new KeyMap('a', predator),}; while (true) { line = br.readLine(); firstChar = line.charAt(0); for (int i = 0; i < keyedSongs.length; i++) { if (keyedSongs[i].match(firstChar)) { // Notice now by running the code, after the first second of sleep time the sound can // and another sound can be played in its place keyedSongs[i].stop(); System.out.println("Played the sound: " + keyedSongs[i].play()); break; } } if (firstChar == 'q') { break; } } } }