1

私はビデオゲームを書いていますが、プレーヤーが(メインメニューに)負けたり終了したりしたときに音楽を停止したいと思います。

これが私のコードです:

public class Music{
    private static Clip clip;
    private static AudioInputStream stream;

    private static void loadMusic(){
        if(clip != null) return;
        try {
            AudioFormat format;
            DataLine.Info info;
            stream = AudioSystem.getAudioInputStream(Music.class.getResource("/resources/music/music.wav"));
            format = stream.getFormat();
            info = new DataLine.Info(Clip.class, format);
            clip = (Clip) AudioSystem.getLine(info);
            clip.open(stream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void playMusic(boolean loop){
        loadMusic();
        if(clip == null) return;
        if(loop) clip.loop(Clip.LOOP_CONTINUOUSLY);
        else clip.start();
    }

    public static void stopMusic(){
        clip.stop();
        clip.setMicrosecondPosition(0);
    }
}

Music.stopMusic()を呼び出すと、ゲームが数秒間ハングしてから続行します。

4

1 に答える 1

2

私があなたの説明から集めたものから、あなたはあなたのGUIの停止ボタンを押しています、そしてこれはを呼び出しますMusic.stopMusic()。その結果、オーディオクリップの再生は停止しますが、GUIが応答するまで3秒間待機します。

これは、で行っているMusic.stopMusic()呼び出しがI / Oリソースへのネイティブ呼び出しを行うためであり、これはEDTでは呼び出されるべきではありません。これを行うには、ワーカースレッドの実行を検討する必要があります。

Thread t = new Thread(new Runnable() { 
     public void run() {
         Music.stop();
     }
});
t.start();

または、SwingWorkerの使用を検討してください。

興味深いことに、どの実装が返されるかはわかりませんClipが、簡単に見るMixerClipと、ネイティブライブラリへの呼び出しが示され、おそらく苦境にある喫煙銃がコールバックを3秒間待ちます。

// stop the sample.  this invalidates the sample voice id.
nStop(id);

// wait for the callback
synchronized(lock) {
    if (id!=0) {
    try {
        //long time=System.currentTimeMillis();
        lock.wait(3000);
        //if (System.currentTimeMillis()-time > 2500) {
        //System.out.println(" WAITING TIMED OUT!"); System.out.flush();
        //id=0;
        //}
    } catch (InterruptedException e) { }
    }
}
于 2012-08-20T23:37:36.023 に答える