声音赢了';我不会玩java。。JFrame和Canvas不是小程序

声音赢了';我不会玩java。。JFrame和Canvas不是小程序,java,canvas,embedded-resource,javasound,audio,Java,Canvas,Embedded Resource,Javasound,Audio,我目前正在用java编写我的第一个游戏,我正试图在宇宙飞船被击中时实现声音。。这是我的密码。我得到一个空指针异常,但我的声音在正确的位置“workspace/project/src/sounds/” 这是stacktrace java.lang.NullPointerException at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(Unknown Source) at javax.sound.

我目前正在用java编写我的第一个游戏,我正试图在宇宙飞船被击中时实现声音。。这是我的密码。我得到一个空指针异常,但我的声音在正确的位置“workspace/project/src/sounds/”

这是stacktrace

java.lang.NullPointerException
    at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(Unknown Source)
    at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
    at sound.GameSounds.hit(GameSounds.java:16)
    at main.Main.doLogic(Main.java:135)
    at main.Main.run(Main.java:101)
    at java.lang.Thread.run(Unknown Source)

package sound;
import java.io.InputStream;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
public class GameSounds 
{
    public static synchronized void hit()
    {
        try
        {
            String resPath = "/sounds/8bit_bomb_explosion.wav"; // *** this is the key ***
            InputStream audioInStream = GameSounds.class.getResourceAsStream(resPath);
            System.out.println("is audioInStream null?: " + (audioInStream == null)); // test it!
            AudioInputStream inputStream = AudioSystem.getAudioInputStream(audioInStream);          Clip clip = AudioSystem.getClip();
            clip.open(inputStream);
            clip.start(); 
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

感谢您的建议,现在它可以正常工作了

,很可能您没有以正确的路径获取资源。了解资源路径是基于类加载器加载类文件的位置,而不是基于src或“user.dir”目录的位置

也许你想做:

// almost always better to break up a long code line into smaller lines.
String resPath = "/sounds/8bit_bomb_explosion.wav"; // *** this is the key ***
InputStream audioInStream = GameSounds.class.getResourceAsStream(resPath);
System.out.println("is audioInStream null?: " + (audioInStream == null)); // test it!
AudioInputStream inputStream = AudioSystem.getAudioInputStream(audioInStream);

同样,路径字符串将取决于类文件相对于src目录的位置

我也有同样的问题。但在搜索了几个小时后,我发现了Javazoom,它是一种外部自由软件,您可以将其导入到项目中,使声音播放变得更加容易:

您可以这样使用它:

  import javazoom.jl.player.advanced.*;

class SoundJLayer extends PlaybackListener implements Runnable
{
    private String filePath;
    private AdvancedPlayer player;
    private Thread playerThread;    

    public SoundJLayer(String filePath)
    {
        this.filePath = filePath;
    }

    public void play()
    {
        try
        {
            String urlAsString = 
                "file:///" 
                + new java.io.File(".").getCanonicalPath() 
                + "/" 
                + this.filePath;

            this.player = new AdvancedPlayer
            (
                new java.net.URL(urlAsString).openStream(),
                javazoom.jl.player.FactoryRegistry.systemRegistry().createAudioDevice()
            );

            this.player.setPlayBackListener(this);

            this.playerThread = new Thread(this, "AudioPlayerThread");

            this.playerThread.start();
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
    }

    public void stop() {
        player.stop();
    }
    // PlaybackListener members

    public void playbackStarted(PlaybackEvent playbackEvent)
    {
    }

    public void playbackFinished(PlaybackEvent playbackEvent)
    {
    }    

    // Runnable members

    public void run()
    {
        try
        {
            this.player.play();
        }
        catch (javazoom.jl.decoder.JavaLayerException ex)
        {
            ex.printStackTrace();
        }

    }
}
之后,您只需创建一个新的SoundJLayer对象,并使用play()启动ir

希望这有帮助


Jan

是否调用了您的
hit()
方法?你在用println语句检查这个吗?剪辑是否找到声音资源?你能通过println检查一下吗(我不确定,因为我没有处理这个类)?你的代码会抛出异常吗?您是否注意在后台线程而不是在Swing线程中调用此代码?打印异常的堆栈跟踪,并告诉我们它引用的是哪一行。堆栈跟踪告诉问题所在。不显示它就像去看医生,拒绝告诉你的疼痛在哪里。我看到你现在发布了你得到了NPE。当最初询问时,这应该是一个问题,因为这是一种关键的材料,并且NPE是按照@JBNizet抛出的。很可能,您没有以正确的路径获取资源。请理解,资源路径是基于类加载器加载类文件的位置,而不是基于src或“user.dir”目录的位置。您的第一次尝试几乎是正确的。你的第二个错了。您正在使用类加载器加载资源,该加载器在类路径中放置的目录和jar中查找资源,从而使用相对于这些目录和jar的路径。不使用绝对文件系统路径。由于它现在可以工作,您应该通过单击答案旁边的复选标记来接受显示答案的答案。这就是你在这里说谢谢的方式。应该是
/sounds/8bit_bomb_explosion.wav
路径应该是绝对的,而不是相对的。而且../无论如何都不受支持(AFAIR)@JBNizet:我还以为是的。好的,我改变了我的答案。更好,但是绝对路径的优点就是它们不依赖于加载资源的类的包。仅显示已加载资源的位置。所以答案的最后一行是错误的+无论如何,这不会让OP从类路径读取声音文件,这肯定比从文件系统读取声音文件要好。
  import javazoom.jl.player.advanced.*;

class SoundJLayer extends PlaybackListener implements Runnable
{
    private String filePath;
    private AdvancedPlayer player;
    private Thread playerThread;    

    public SoundJLayer(String filePath)
    {
        this.filePath = filePath;
    }

    public void play()
    {
        try
        {
            String urlAsString = 
                "file:///" 
                + new java.io.File(".").getCanonicalPath() 
                + "/" 
                + this.filePath;

            this.player = new AdvancedPlayer
            (
                new java.net.URL(urlAsString).openStream(),
                javazoom.jl.player.FactoryRegistry.systemRegistry().createAudioDevice()
            );

            this.player.setPlayBackListener(this);

            this.playerThread = new Thread(this, "AudioPlayerThread");

            this.playerThread.start();
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
    }

    public void stop() {
        player.stop();
    }
    // PlaybackListener members

    public void playbackStarted(PlaybackEvent playbackEvent)
    {
    }

    public void playbackFinished(PlaybackEvent playbackEvent)
    {
    }    

    // Runnable members

    public void run()
    {
        try
        {
            this.player.play();
        }
        catch (javazoom.jl.decoder.JavaLayerException ex)
        {
            ex.printStackTrace();
        }

    }
}