我制作游戏,在将游戏导出到.jar文件后,我偶然发现了一个问题:我无法播放声音。
我对此进行了大量研究,我开始认为这是JAVA的一些问题。我也意识到我并不是唯一一个有这个问题的人,但没有给那些可以帮助我的人提供答案。
我研究了getClass()和getClassLoader()之间的区别,并尝试了两种情况,但仍然没有。但问题不在于加载资源,而是关于声音没有播放,即使它加载了。
游戏很好玩,加载所有的精灵,但没有任何声音。
在我研究这个过程中,我了解到我可以使用" java -jar file.jar"来执行游戏。在命令,声音开始工作。然而,这对我来说听起来不是一个好选择,因为我打算分发游戏。
这是我做的一个测试,它显示了我正在谈论的内容。 您可以添加任何图像和声音,并自行测试。
package testando;
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class Testando extends JFrame {
private final LineListener myLineListener;
public Testando() {
super();
setLayout( new BorderLayout() );
setBounds( 200, 200, 500, 500 );
myLineListener = new MyLineListener();
MultiSound multiSoundPanel = new MultiSound();
addWindowListener( new WindowAdapter() {
@Override public void windowClosing( WindowEvent e ) {
System.exit( 0 );
}
});
add( multiSoundPanel );
}
private class MultiSound extends JPanel {
final BufferedImage desertImage;
MultiSound(){
super( null, true );
final AudioInfo audioInfos = new AudioInfo( "testando/Iron_Click.wav" );
addMouseListener( new MouseListener() {
final AudioInfo audioInfo = audioInfos;
@Override
public void mousePressed( MouseEvent e ) {
Sound sound = new Sound( audioInfo );
new Thread(sound).start();
}
@Override public void mouseClicked( MouseEvent e ) {}
@Override public void mouseReleased( MouseEvent e ) {}
@Override public void mouseEntered( MouseEvent e ) {}
@Override public void mouseExited( MouseEvent e ) {}
});
java.net.URL streamURL = Thread.currentThread().getContextClassLoader().getResource( "testando/Desert.jpg" );
BufferedImage desertImagebuff = null;
try {
desertImagebuff = ImageIO.read( streamURL );
}
catch ( IOException ex ) {
StringBuilder sb = new StringBuilder(ex.toString());
for (StackTraceElement ste : ex.getStackTrace()) {
sb.append("\n\tat ");
sb.append(ste);
}
String trace = sb.toString();
JOptionPane.showMessageDialog( null, trace, "ERROR", JOptionPane.INFORMATION_MESSAGE);
System.exit( -1 );
}
desertImage = desertImagebuff;
}
@Override
protected void paintComponent( Graphics g ) {
super.paintComponent( g ); //To change body of generated methods, choose Tools | Templates.
Graphics2D g2 = (Graphics2D)g.create();
Rectangle rect = getVisibleRect();
double desSx = ((rect.width*1.0d)/desertImage.getWidth());
double desSy = ((rect.height*1.0d)/desertImage.getHeight());
//To keep the image scalled to the panel;
AffineTransform scale = AffineTransform.getScaleInstance( desSx, desSy );
AffineTransformOp transformer = new AffineTransformOp( scale, null );
g2.drawImage( desertImage, transformer , rect.x, rect.y );
g2.dispose();
}
}
private class AudioInfo {
final AudioFormat audioFormat;
final int size;
final byte[] audio;
final DataLine.Info info;
AudioInfo( String path ){
java.net.URL streamURL = Thread.currentThread().getContextClassLoader().getResource( path );
AudioFormat toAudioFormat = null;
int toSize = -1;
byte[] toByte = null;
DataLine.Info toInfo = null;
try {
InputStream stream = new BufferedInputStream( streamURL.openStream() );
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream( stream );
toAudioFormat = audioInputStream.getFormat();
toSize = (int) ( toAudioFormat.getFrameSize() * audioInputStream.getFrameLength() );
toByte = new byte[toSize];
toInfo = new DataLine.Info(Clip.class, toAudioFormat, toSize);
audioInputStream.read(toByte, 0, toSize);
}
catch ( UnsupportedAudioFileException | IOException ex ) {
StringBuilder sb = new StringBuilder(ex.toString());
for (StackTraceElement ste : ex.getStackTrace()) {
sb.append("\n\tat ");
sb.append(ste);
}
String trace = sb.toString();
JOptionPane.showMessageDialog( null, trace, "ERROR", JOptionPane.INFORMATION_MESSAGE);
System.exit( -1 );
}
audioFormat = toAudioFormat;
size = toSize;
audio = toByte;
info = toInfo;
}
}
private class MyLineListener implements LineListener {
@Override
public void update( LineEvent event ) {
if ( event.getType( ) == LineEvent.Type.STOP )
event.getLine().close();
}
}
private class Sound implements Runnable {
private final Clip sound;
Sound( AudioInfo audioInfo ){
AudioFormat audioFormat = audioInfo.audioFormat;
int size = audioInfo.size;
byte[] audio = audioInfo.audio;
DataLine.Info info = audioInfo.info;
Clip clip = null;
try {
clip = (Clip) AudioSystem.getLine( info );
clip.open( audioFormat, audio, 0, size );
clip.addLineListener( myLineListener );
}
catch ( LineUnavailableException ex ) {
clip = null;
}
sound = clip;
}
@Override
public void run() {
sound.start();
}
}
public static void main( String[] args ) {
Testando testando = new Testando();
testando.setVisible( true );
}
}
如果你想更好地分析它,我还用它编译了带有源代码的可执行版本。 https://www.dropbox.com/s/328dr47i39vbart/testando_dist.zip
我不知道它是否有用,但我使用的是NetBeans 7.4。
有人可以帮帮我吗?
提前谢谢你, saclyr。
答案 0 :(得分:0)
我刚刚发现为什么没有声音。
我试了很多次,包括更新JDK和JRE,但仍然没有。我尝试安装32位的JRE,但仍然没有,但在取消了64位版本后,我开始得到声音。
游戏现在很好,但出于某种原因,它无法用于64位。
问题在于64位版本。