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

使用javax.sound.sampled.Clip在游戏中播放、循环和停止多个声音。意外错误,java,exception,audio,game-development,Java,Exception,Audio,Game Development,我试图在游戏中同时播放两个wav声音(背景音乐和效果)。我首先使用java中的另一个音频处理程序构建了这段代码,该处理程序将处理声音的播放、停止和循环。此结构将播放背景音乐或效果,但一次只能播放一个。我环顾了一下互联网,被告知使用javax.sound.sampled.Clip来处理声音,因此重复使用了相同的结构(播放、停止、循环),但将其切换为使用javax.sound.sampled.Clip。现在我完全迷路了。从我到目前为止所读到的内容来看,我在eclipse编辑器中做的一切都是正确的,没

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

    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();
        }
    }

我能够让代码正常工作,现在对剪辑有了更好的理解。对我帮助最大的一页是它把所有的东西都分解了,帮助我看到了我犯的错误。这是我最后的工作代码。如前所述,如果您在逻辑或风格上看到任何可怕的错误或过度,请告诉我

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();
    }
}

/*
*文件:SoundBox.java
*作者:Andrew Peturis,Chaselyn Langley;UAB EE学生
*任务:GUI音箱-EE333 2015年秋季
*版本:1.0.0 2015年8月9日agp-初始编码
*/
导入java.io.BufferedReader;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.InputStreamReader;
导入java.util.Scanner;
导入javax.sound.sampled.LineUnavailableException;
/**
*
*@作者Andrew Peturis,Chaselyn Langley
*
*/
公共级音箱{
静态扫描器Scanner=新扫描器(System.in);//要读取用户输入的扫描器对象
输入流输入;
/**
*@param指定命令行参数
*@抛出java.io.IOException
*/
公共静态void main(字符串[]args)引发IOException、LineUnavailableException{
弦线;
字符firstChar;
String predator=“predator”;
字符串爆炸=“爆炸”;
BufferedReader br=新的BufferedReader(新的InputStreamReader(System.in));
KeyMap[]keyedSongs={
新的键图('a',捕食者),};
while(true){
line=br.readLine();
firstChar=line.charAt(0);
for(int i=0;i
你能再解释一下这个链接吗,以防它坏掉?
/*
 * 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;
            }
        }
    }
}