首页 > 解决方案 > 如何停止播放 JAVA 中的 WAV 剪辑

问题描述

我试图在按下开始按钮时停止播放介绍歌曲。我尝试使用此代码这样做。请注意,此代码并不包含我的所有代码。GUI 看起来不错,Actionlistener 也可以正常工作。只有按下开始按钮时音乐不会停止播放

File introPath = new File("src/BattleshipGUI/423499__soundflakes__epic-heroic-orchestral- 
                                                                      dramatic.wav");
File buttonPressedPath = new File("src/BattleshipGUI/sfx_patcher_button_launch.wav");
static Clip introWAV;


    Menu() {


    super("BattleBoard");


    this.setContentPane(this.panelMain);
    this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    this.setLocationRelativeTo(null);
    this.pack();
    
    play(introPath); // playing when launching 


    // when the game starts, the sound should stop

    ButtonStartGame.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            super.mouseClicked(e);
            play(buttonPressedPath);

            try {
                if (random) {

                    currentCols = (Integer) spinnerColumns.getValue();
                    currentRows = (Integer) spinnerRows.getValue();
                    if (currentCols < 5 || currentRows < 5) {
                        
                        throw (new IllegalArgumentException());
                    } else {
                        BoardFrame b = new BoardFrame(currentRows, currentCols);
                        b.SetFrame(currentRows, currentCols);
                        b.AddRandomShips(currentRows, currentCols);
                        b.ScoreMethod(adjustedScoreMethod);
                        introWAV.stop();
                        introWAV.flush();
                        introWAV.close();
                        dispose();



public static void SetIntroWAV(Clip clip){

    introWAV=clip;
}

public static void play(File file) {
    try {
        Clip sound = AudioSystem.getClip();
        sound.open(AudioSystem.getAudioInputStream(file));
        SetIntroWAV(sound);
        sound.start();

    } catch (Exception e) {
        System.out.println(e);
    }
}

我尝试了其他方法,比如在 Play-class 中使用 while 循环、'if-else'-statements,......有人知道如何解决这个问题吗?提前致谢!

标签: javaaudiojavasound

解决方案


罪魁祸首是你play方法的一部分。每当您想播放任何声音时,您也可以在SetIntroWAV内部调用。这将导致您的introWAV变量被设置。

这就是问题的原因:第一次调用 时play,您的介绍声音会被播放并introWAV具有正确的值。但是,一旦您开始游戏并播放不同的声音(即使用buttonPressedPath),您的introWAV变量就会设置为不同的值:最近开始的声音。然后,当您尝试停止播放声音时,您使用的实际上introWAV不再包含对您的介绍声音的引用。相反,这将导致您最近播放的声音停止,因为这是现在保持的。introWAV

要解决此问题,只需设置introWAV一次变量而不是每次play都调用它。有多种方法可以做到这一点,包括:

  1. 您可以让您的play方法返回Clip之后将播放的结果:

    public static Clip play(File file) {
        Clip sound = null;
        try {
            sound = AudioSystem.getClip();
            sound.open(AudioSystem.getAudioInputStream(file));
            sound.start();
        } catch (Exception e) {
            System.out.println(e);
        } finally {
            return sound;
        }
    }
    

然后,您可以使用此返回值调用SetIntroWAV一次:SetIntroWAV(play(introPath)); 您还可以将此返回值用于其他目的,例如保持对声音的本地引用。但是,您不必每次都使用它,并且在不需要该参考时仍然可以忽略它。

  1. 您可以重写您的play方法,使其还包含一个参数,告诉该方法您尝试播放的声音是否是介绍声音:

    public static void play(File file, boolean intro) {
        try {
            Clip sound = AudioSystem.getClip();
            sound.open(AudioSystem.getAudioInputStream(file));
            if(intro) {
                SetIntroWAV(sound);
            }
            sound.start();
        } catch (Exception e) {
            System.out.println(e);
        }
    }
    

这也将导致SetIntroWAV只被调用一次。

我还建议您为此使用更多的面向对象的编程风格,因为它可以使这些事情变得更加明显和更容易修复。例如,您可以为音频播放和游戏创建单独的类。


推荐阅读