如何在 Java 游戏中播放声音?

Posted

技术标签:

【中文标题】如何在 Java 游戏中播放声音?【英文标题】:How to play sounds in Java games? 【发布时间】:2010-02-11 18:44:51 【问题描述】:

我正在使用以下代码在 Java (1.5) 小程序游戏中成功播放声音:

// get an available clip to play it
Clip clip = null;
for (Clip clipTemp : players) 
    if (!clipTemp.isOpen()) 
    clip = clipTemp;
        break;
    

if (clip == null) 
    // no available player found, don't play
    return;


clip.open(audioFormat, audioByteData, 0, audioByteData.length);

clip.start();

(播放器是我在开始时打开的剪辑列表,目的是减少延迟,线路侦听器在检索到停止事件时关闭线路。)

我面临的问题是播放声音时会出现长达 1 秒的间歇性延迟。这太可怜了。

有什么办法可以改善吗? SourceDataLines 值得考虑吗?

【问题讨论】:

【参考方案1】:

Java Applet 会在您想要播放剪辑时对其进行流式传输,这就是为什么您会遇到延迟,因为声音文件尚未加载到内存中。

我已经有一段时间没有进行 Java 小程序编程了,但我确实记得我曾经预加载所有剪辑,然后随后的播放调用不会重新打开文件。

这是我的一个旧项目中的一些代码

Clip shoot;

private loadShootWav()

    AudioInputStream sample;
    sample = Audiosystem.getAudioInputStream(this.getClass().getResource("shoot.wav"));
    shoot = AudioSystem.getClip();
    shoot.open(sample);


public void playShootSFX()

    shoot.stop();
    shoot.setFramePosition(0);
    shoot.start(); 

【讨论】:

嗨 - 感谢您的回答。可能需要多次播放相同的声音。你会建议事先为每个音效合并多个剪辑吗? 是的 - 我通常实现一个加载所有剪辑的“SoundManager”单例类。上面的代码会多次播放声音,但每次都会重置剪辑。如果您想说播放 5 个相同的声音,但以稍微不同的间隔混合,我建议您尝试加载 5 个剪辑,然后在您调用 playSFX() 时增加一个计数器,该计数器指向要播放的下一个剪辑. @JSmyth 我正在做这样的事情,但是如果我打开同一个声音文件的多个 AudioInputStream,我开始收到 LineUnavailableException。你能看看我的问题吗? ***.com/questions/20184650/…【参考方案2】:

如果我正确阅读了您的代码,您会发现一个未打开的剪辑并在播放之前将其打开。拍摄打开的剪辑并重新启动它们会更快。您可能必须先停止并重置它们的位置,如 playShootSFX() 示例中的 JSmyth 所示。

我对 SourceDataLines 的反应非常好。好消息是它们比未打开的剪辑启动得更快,因为它们会立即启动,而不是等到声音的所有数据都加载到 RAM 中(每次“打开”剪辑时都会发生这种情况)。

但是,是的,如果您有很多经常播放的小声音,那么剪辑池就是您的最佳选择。如果您希望它们重叠,或者总是玩到完整,那么您需要多个副本。如果不是,则停止,重置为 0 并重新启动。但不要继续重新开放!如果您这样做,您不妨使用 SourceDataLine。

【讨论】:

我遇到了一些问题。我想我可能需要做你在这里提到的事情。你可以发布一个例子吗?这是我的问题:***.com/questions/20184650/… 查看您的链接帖子,您似乎已经解决了问题。很好!我自己没有尝试过 Beads,但它看起来确实很有趣。我也听说过关于 TinySound 库的好消息,它支持多重播放。虽然我一直在使用我自己的代码。 甜蜜。我得去看看 TinySound。珠子很好,因为它为您提供了“机器”(我称之为它们),您可以将输入插入并将输出插入外部机器输入。您可以使用效果等过滤声音。很酷的是,它通过将所有同时发出的声音的值相加来自动处理数据线以产生最终输出。 酷,我刚刚检查了 TinySound。它既好又简单。 Beads 的简单用例与 TinySound 一样简单,但如果您愿意,Beads 允许您使用它变得更复杂(TinySound 不能)。感谢您向我展示 TinySound!

以上是关于如何在 Java 游戏中播放声音?的主要内容,如果未能解决你的问题,请参考以下文章

在 Java 中混合声音?

使用 javax.sound.sampled.Clip 在游戏中播放、循环和停止多个声音。意外错误

在 JavaScript \ jQuery 上播放游戏声音

如何在 WPF 中播放声音?

游戏会话声音播放/录音

如何在 python (Windows) 中播放声音