如何停止播放 JAVA 中的 WAV 剪辑
How to stop a WAV clip in JAVA from playing
我试图在按下开始按钮时停止播放介绍歌曲。我尝试使用此代码这样做。请注意,此代码并不包含我的所有代码。 GUI 看起来不错,Actionlisteners 也可以正常工作。只有按下开始按钮时音乐不会停止播放。
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、'if-else'-语句中使用 while 循环,...有人知道如何解决这个问题吗?提前致谢!
罪魁祸首是您 play
方法的一部分。
每当您想播放 any 声音时,您也会在内部调用 SetIntroWAV
。这会导致您的 introWAV
变量被设置。
这就是问题所在:
第一次调用 play
时,会播放您的开场音并且 introWAV
具有正确的值。
但是,一旦您开始游戏并播放不同的声音(即使用 buttonPressedPath
),您的 introWAV
变量就会设置为不同的值:最近开始的声音。
当您随后尝试停止播放声音时,您使用的 introWAV
实际上 不再包含对您的介绍声音的引用。相反,这将导致您最近播放的声音停止,因为这是 introWAV
现在持有的声音。
要解决此问题,只需将 introWAV
变量设置一次,而不是每次调用 play
时都设置一次。有多种方法可以做到这一点,包括这些:
您可以让您的 play
方法 return 结果 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;
}
}
然后您可以使用此 returned 值调用 SetIntroWAV
一次:SetIntroWAV(play(introPath));
您还可以将此 return 值用于其他目的,例如保留对您的声音的本地引用。但是,您不必每次都使用它,并且在不需要该引用时仍然可以忽略它。
您可以重写您的 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
只被调用一次。
我还建议您为此使用更多面向对象的编程风格,因为它可以使类似的事情变得更加明显和更容易修复。
例如,您可以为音频播放和游戏创建单独的 类。
恕我直言,使用 Clip
变量的最佳做法是加载和打开,然后将它们保存在内存中。这可以在管理音效的 class 中完成。在那个 class 中,将 Clip 作为实例变量并预加载并在构造函数中打开它。
这个 class 也可以有两个从你的游戏中调用的方法。
public void play() {
clip.setFramePosition(0); // ensures Clip will start from the beginning
clip.start();
}
public void stop() {
clip.stop();
}
使用这种结构,管理多个声音也变得更加容易。例如,您可以拥有此声音管理 class 的两个实例,并将每个实例设置为不同的声源。然后,您可以轻松地停止一个并开始另一个。
我试图在按下开始按钮时停止播放介绍歌曲。我尝试使用此代码这样做。请注意,此代码并不包含我的所有代码。 GUI 看起来不错,Actionlisteners 也可以正常工作。只有按下开始按钮时音乐不会停止播放。
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、'if-else'-语句中使用 while 循环,...有人知道如何解决这个问题吗?提前致谢!
罪魁祸首是您 play
方法的一部分。
每当您想播放 any 声音时,您也会在内部调用 SetIntroWAV
。这会导致您的 introWAV
变量被设置。
这就是问题所在:
第一次调用 play
时,会播放您的开场音并且 introWAV
具有正确的值。
但是,一旦您开始游戏并播放不同的声音(即使用 buttonPressedPath
),您的 introWAV
变量就会设置为不同的值:最近开始的声音。
当您随后尝试停止播放声音时,您使用的 introWAV
实际上 不再包含对您的介绍声音的引用。相反,这将导致您最近播放的声音停止,因为这是 introWAV
现在持有的声音。
要解决此问题,只需将 introWAV
变量设置一次,而不是每次调用 play
时都设置一次。有多种方法可以做到这一点,包括这些:
您可以让您的
play
方法 return 结果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; } }
然后您可以使用此 returned 值调用 SetIntroWAV
一次:SetIntroWAV(play(introPath));
您还可以将此 return 值用于其他目的,例如保留对您的声音的本地引用。但是,您不必每次都使用它,并且在不需要该引用时仍然可以忽略它。
您可以重写您的
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
只被调用一次。
我还建议您为此使用更多面向对象的编程风格,因为它可以使类似的事情变得更加明显和更容易修复。 例如,您可以为音频播放和游戏创建单独的 类。
恕我直言,使用 Clip
变量的最佳做法是加载和打开,然后将它们保存在内存中。这可以在管理音效的 class 中完成。在那个 class 中,将 Clip 作为实例变量并预加载并在构造函数中打开它。
这个 class 也可以有两个从你的游戏中调用的方法。
public void play() {
clip.setFramePosition(0); // ensures Clip will start from the beginning
clip.start();
}
public void stop() {
clip.stop();
}
使用这种结构,管理多个声音也变得更加容易。例如,您可以拥有此声音管理 class 的两个实例,并将每个实例设置为不同的声源。然后,您可以轻松地停止一个并开始另一个。