我有一个游戏,使用这种方法播放音效:
AudioInputStream inputStream = AudioSystem.getAudioInputStream(
TheGame.class.getResource(url));
Clip clip = AudioSystem.getClip();
clip.open(inputStream);
clip.start();
但是,不关闭剪辑显然会增加内存,并且我尝试过的修复会导致游戏偶尔卡住。 我尝试过:
- 为每个剪辑创建一个新的 LineListener,在剪辑停止时关闭该剪辑。游戏经常卡住。
- 拥有一个 LineListener,用于监听每个剪辑,并在它们停止时关闭它们。也经常卡住。
- 与 #2 相同,但将剪辑分配给多个 LineListener,我尝试过 4、6 和 10 个,所有这些都至少使游戏卡住一次。
- 永远不要关闭剪辑,最终游戏将停止播放声音并卡住
- 打开剪辑后立即将其设置为 null,结果与 #4 相同
我不知道为什么关闭剪辑似乎要花很多时间,以至于整个游戏都卡住了,有没有更省时的方法?
这是我正在使用的 LineListener 更新方法的代码:
@Override
public void update(LineEvent event) {
if (event.getType() == LineEvent.Type.STOP){
Clip c = (Clip) event.getSource();
c.close();
c.removeLineListener(this);
}
}
最佳答案
根据我上面的评论,您应该重用现有的 Clip
对象。
Map<String, Clip> clips = new HashMap<String, Clip>();
public synchronized void play(String url) {
Clip clip = clips.get(url);
if(clip == null) {
AudioInputStream inputStream = AudioSystem.getAudioInputStream(
TheGame.class.getResource(url));
Clip clip = AudioSystem.getClip();
clip.open(inputStream);
clips.put(url, clip);
}
if(clip.isRunning())
clip.stop();
clip.setFramePosition(0);
clip.start();
}
如果您需要将相同的声音与其自身重叠,您将需要更有创意。请注意,如果您碰巧从多个线程调用此方法,我已将其放置在 synchronized
方法中,以保护 Map
免受并发修改。
关于java - 如何在播放完毕后立即有效地关闭大量剪辑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50378794/