我在path
的游戏中播放声音效果(WAV文件)。但是,有2秒的效果并非完全播放,只是其中的一部分。如果我添加javax.sound.sampled.Clip
,则声音会正确播放多次,即整整2秒。有什么问题以及如何解决?
clip.loop(2)
答案 0 :(得分:1)
你是否意识到并且考虑到当播放剪辑时(通过start()方法),播放代码的线程是一个守护进程?与常规线程不同,守护程序线程不会阻止Java程序关闭。如果您的程序在声音执行完毕之前结束,守护程序状态线程也会结束,即使它没有完成。
您是否尝试运行示例代码SoundClipTest或SoundEffectDemo?在我看来,SoundClipTest将在程序执行start()方法后立即退出,而SoundEffectDemo将保持并允许声音完成播放。
**编辑1 **
我刚才注意到你已经将SoundEffect作为枚举。我以前从没见过这种方法。
我使用的一种方法是创建一个名为GameSound的类,让它的构造函数单独预加载每个Clip并将它们保存在内存中,准备播放。然后,我为他们的播放创建一个或多个方法。
gameSound.playExplosion();
GameSound类将为每个声音效果提供实例变量。
private Clip explosion;
private Clip cannon;
GameSound构造函数将具有:
URL url = this.getClass().getResource("resources/explosion.wav");
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
explosion = AudioSystem.getClip();
explosion.open(ais);
和GameSound会有方法:
public void playExplosion()
{
if (explosion.isRunning()) {
explosion.stop();
}
explosion.setFramePosition(0);
explosion.start();
}
如果您希望让play方法使用参数并在开关结构上使用它来选择要播放的声音,那也没关系,特别是因为它消除了一些代码重复。
这种方法可能效果更好(随着代码变得更加复杂,很容易添加到GameSound中),而且编码也不会太难。我很想知道改变这个计划是否会使问题消失。
**编辑2 **
对于上述代码中的错误,我们深表歉意。当我做出以下示例时,我修复了它们。但是,有人想到,当我去听你所连接的声音效果时,有几个爆炸开始被截断了。您是否在其他应用程序中播放了这些声音(如Windows Groove音乐,或者从您获得它们的网站),并在您的代码中播放它们时验证它们是不同的?
这是一个快速的游戏" GameSound"。我从您的参考文件中下载了Explosion + 2.wav文件,因为它比其他文件更长并且有一个明确的结尾,并且正在引用它。
package stackoverflow.janbodnar;
import java.io.IOException;
import java.net.URL;
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;
public class GameSound {
private final Clip explosion;
public GameSound() throws LineUnavailableException,
IOException, UnsupportedAudioFileException
{
URL url = this.getClass().getResource(
"resources/Explosion+2.wav");
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
explosion = AudioSystem.getClip();
explosion.open(ais);
}
public void playExplosion()
{
if (explosion.isRunning()) {
explosion.stop();
}
explosion.setFramePosition(0);
explosion.start();
}
}
这是一个简单的Swing按钮,可以调用GameSound。
package stackoverflow.janbodnar;
import java.io.IOException;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class GameSoundTest extends JFrame
{
private static final long serialVersionUID = 1L;
private final GameSound gameSound;
public GameSoundTest() throws LineUnavailableException,
IOException, UnsupportedAudioFileException
{
gameSound = new GameSound();
JButton button = new JButton("Play Explosion");
button.addActionListener(e -> gameSound.playExplosion());
getContentPane().add(button);
}
private static void createAndShowGUI()
{
JFrame frame;
try
{
frame = new GameSoundTest();
frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
frame.setBounds(0, 0, 200, 200);
frame.setVisible(true);
}
catch (LineUnavailableException | IOException
| UnsupportedAudioFileException e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(() -> createAndShowGUI());
}
}
当然,这一切都假定有一个名为" resources"的子文件夹。随着爆炸SFX。