在 Java 游戏中使用音效
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/647252/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using Sound Effects in a java game
提问by Eddie
Basically I am trying to use this SoundEffect class in a simple java game I'm working on for my assignment.
基本上,我正在尝试在一个简单的 Java 游戏中使用这个 SoundEffect 类来完成我的作业。
import java.io.*;
import java.net.URL;
import javax.sound.sampled.*;
/**
* This enum encapsulates all the sound effects of a game, so as to separate the sound playing
* codes from the game codes.
* 1. Define all your sound effect names and the associated wave file.
* 2. To play a specific sound, simply invoke SoundEffect.SOUND_NAME.play().
* 3. You might optionally invoke the static method SoundEffect.init() to pre-load all the
* sound files, so that the play is not paused while loading the file for the first time.
* 4. You can use the static variable SoundEffect.volume to mute the sound.
*/
public enum SoundEffect {
EAT("eat.wav"), // explosion
GONG("gong.wav"), // gong
SHOOT("shoot.wav"); // bullet
// Nested class for specifying volume
public static enum Volume {
MUTE, LOW, MEDIUM, HIGH
}
public static Volume volume = Volume.LOW;
// Each sound effect has its own clip, loaded with its own sound file.
private Clip clip;
// Constructor to construct each element of the enum with its own sound file.
SoundEffect(String soundFileName) {
try {
// Use URL (instead of File) to read from disk and JAR.
URL url = this.getClass().getClassLoader().getResource(soundFileName);
// Set up an audio input stream piped from the sound file.
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(url);
// Get a clip resource.
clip = AudioSystem.getClip();
// Open audio clip and load samples from the audio input stream.
clip.open(audioInputStream);
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}
// Play or Re-play the sound effect from the beginning, by rewinding.
public void play() {
if (volume != Volume.MUTE) {
if (clip.isRunning())
clip.stop(); // Stop the player if it is still running
clip.setFramePosition(0); // rewind to the beginning
clip.start(); // Start playing
}
}
// Optional static method to pre-load all the sound files.
static void init() {
values(); // calls the constructor for all the elements
}
}
Here is an implementation of the EAT sound in my game's Reward class-
这是我游戏的奖励类中 EAT 声音的实现 -
public void react(CollisionEvent e)
{
Player player = game.getPlayer();
if (e.contact.involves(player)) {
player.changePlayerImageEAT();
SoundEffect.EAT.play();
player.addPoint();
System.out.println("Player now has: "+player.getPoints()+ " points.");
game.getCurrentLevel().getWorld().remove(this);
}
}
This should play the EAT sound when player comes in contact with a reward in my game.
当玩家在我的游戏中接触到奖励时,这应该会播放 EAT 声音。
However, when my player collides with a reward, I get the following errors in the terminal-
但是,当我的玩家与奖励发生冲突时,我在终端中收到以下错误-
javax.sound.sampled.LineUnavailableException: line with format ALAW 8000.0 Hz, 8 bit, stereo, 2 bytes/frame, not supported. at com.sun.media.sound.DirectAudioDevice$DirectDL.implOpen(DirectAudioDevice.java:494) at com.sun.media.sound.DirectAudioDevice$DirectClip.implOpen(DirectAudioDevice.java:1280) at com.sun.media.sound.AbstractDataLine.open(AbstractDataLine.java:107) at com.sun.media.sound.DirectAudioDevice$DirectClip.open(DirectAudioDevice.java:1061) at com.sun.media.sound.DirectAudioDevice$DirectClip.open(DirectAudioDevice.java:1151) at SoundEffect.(SoundEffect.java:39) at SoundEffect.(SoundEffect.java:15) at Reward.react(Reward.java:41) at city.soi.platform.World.despatchCollisionEvents(World.java:425) at city.soi.platform.World.step(World.java:608) at city.soi.platform.World.access$000(World.java:42) at city.soi.platform.World$1.actionPerformed(World.java:756) at javax.swing.Timer.fireActionPerformed(Timer.java:271) at javax.swing.Timer$DoPostEvent.run(Timer.java:201) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) at java.awt.EventQueue.dispatchEvent(EventQueue.java:597) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) at java.awt.EventDispatchThread.run(EventDispatchThread.java:122) Exception in thread "AWT-EventQueue-0" java.lang.ExceptionInInitializerError at Reward.react(Reward.java:41) at city.soi.platform.World.despatchCollisionEvents(World.java:425) at city.soi.platform.World.step(World.java:608) at city.soi.platform.World.access$000(World.java:42) at city.soi.platform.World$1.actionPerformed(World.java:756) at javax.swing.Timer.fireActionPerformed(Timer.java:271) at javax.swing.Timer$DoPostEvent.run(Timer.java:201) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) at java.awt.EventQueue.dispatchEvent(EventQueue.java:597) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) at java.awt.EventDispatchThread.run(EventDispatchThread.java:122) Caused by: java.lang.NullPointerException at com.sun.media.sound.WaveFileReader.getAudioInputStream(WaveFileReader.java:180) at javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:1128) at SoundEffect.(SoundEffect.java:35) at SoundEffect.(SoundEffect.java:16) ... 15 more
javax.sound.sampled.LineUnavailableException:不支持格式为 ALAW 8000.0 Hz、8 位、立体声、2 字节/帧的行。在 com.sun.media.sound.DirectAudioDevice$DirectDL.implOpen(DirectAudioDevice.java:494) 在 com.sun.media.sound.DirectAudioDevice$DirectClip.implOpen(DirectAudioDevice.java:1280) 在 com.sun.media.sound .AbstractDataLine.open(AbstractDataLine.java:107) 在 com.sun.media.sound.DirectAudioDevice$DirectClip.open(DirectAudioDevice.java:1061) 在 com.sun.media.sound.DirectAudioDevice$DirectClip.open(DirectAudioDevice.java) :1151) at SoundEffect.(SoundEffect.java:39) at SoundEffect.(SoundEffect.java:15) at Reward.react(Reward.java:41) at city.soi.platform.World.despatchCollisionEvents(World.java:425) ) 在 city.soi.platform.World.step(World.java:608) 在 city.soi.platform。
I can't figure out what wrong. I'm guessing it has something to do with my audio files (WAV) being unsupported. However, no matter how many ways I convert them they still don't work.
我想不出哪里错了。我猜这与我的音频文件 (WAV) 不受支持有关。但是,无论我以多少方式转换它们,它们仍然不起作用。
It would be really helpful if someone can kindly enlighten me on what might be wrong and how I can resolve this.
如果有人可以告诉我可能出了什么问题以及我如何解决这个问题,那将非常有帮助。
Sample code and any modifications you can offer to help make this code work will be greatly appreciated.
示例代码和您可以提供的任何修改以帮助使此代码正常工作,我们将不胜感激。
Thank you.
谢谢你。
回答by Eddie
Your root cause Exception is
您的根本原因异常是
javax.sound.sampled.LineUnavailableException:
line with format ALAW 8000.0 Hz, 8 bit, stereo, 2 bytes/frame, not supported
This occurs because not all sound drivers support all bit rates or encodings, or because the machine just doesn't have a sound card. Sound can be encoded in A lawor mu law(or others, such as MP3) and can be encoded at different bit rates and sample sizes. Java does not always support all possible sound formats, depending on what is supported by the base system.
发生这种情况是因为并非所有声音驱动程序都支持所有比特率或编码,或者因为机器没有声卡。声音可以以A 律或mu 律(或其他,例如 MP3)进行编码,并且可以以不同的比特率和样本大小进行编码。Java 并不总是支持所有可能的声音格式,这取决于基本系统支持的内容。
You probably want to do the following:
您可能想要执行以下操作:
- Ensure that the computer on which you're running the program has a reasonable sound card. Most of the time when I see the above Exception, I'm running on server machine with no built-in sound card or with a really lame sound card or with no audio path.
- If you're using a remote terminal or something like this, ensure that the sound has a configured way to play.
- Try re-encoding your sound sample at a different rate, or perhaps as a WAV file, and then try playing it.
- 确保运行该程序的计算机具有合理的声卡。大多数情况下,当我看到上述异常时,我在没有内置声卡或声卡非常差或没有音频路径的服务器机器上运行。
- 如果您使用的是远程终端或类似的东西,请确保声音具有配置的播放方式。
- 尝试以不同的速率重新编码您的声音样本,或者作为 WAV 文件,然后尝试播放它。

