我已经浏览了互联网上有关播放wav文件的方法,但我发现它们不会在单独的线程上播放,因此导致程序停止直到歌曲完成,这对游戏无效。但是,当我尝试在单独的线程上播放所有内容时,它会滞后。有人有解决方法吗?
注意:我也在不断地在背景上画画:
public class DrawThread extends Thread {
JFrame j;
public DrawThread(JFrame frame) {
j = frame;
}
public void run() {
while (!(isInterrupted())) {
if (j.isDisplayable() && j.isActive() && j.isEnabled())
j.update(j.getGraphics());
}
}
}
并更新只调用paint:
public void paint(Graphics g) {
Graphics2D bg = (Graphics2D) g;
bg.setBackground(Color.black);
int w = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth();
int h = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight();
if (time < 500) {
x[time] = r.nextInt(w) + 150;
y[time] = h;
z[time] = r.nextInt(w) + 150;
time++;
}
for (int i = 0; i < time; i++) {
y[i] -= forward;
x[i] -= right;
if (y[i] < 1) {
x[i] = r.nextInt(400) - 200;
y[i] = 300;
z[i] = r.nextInt(400) - 200;
} else if (y[i] > 300) {
x[i] = r.nextInt(400) - 200;
y[i] = 1;
z[i] = r.nextInt(400) - 200;
}
if (x[i] > 200)
x[i] = -200;
else if (x[i] < -200)
x[i] = 200;
bg.setColor(color);
bg.drawLine(
getWidth() / 2 + (int) Math.round(x[i] * 200 / y[i]),
getHeight() / 2 + (int) Math.round(z[i] * 200 / y[i]),
getWidth()
/ 2
+ (int) Math.round((x[i] + right) * 200
/ Math.abs(y[i] + forward)),
getHeight()
/ 2
+ (int) Math.round((z[i]) * 200
/ Math.abs(y[i] + forward)));
}
}
编辑:添加我正在使用的音乐播放器类(我已切换到BigClip):
import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import org.crystalix.util.SoundListener;
public class MSHandler {
public static boolean pause = false;
public static boolean stop = false;
private static HashMap<String, BigClip> clips = new HashMap<String, BigClip>();
public static void stopAll() {
Collection<BigClip> c = clips.values();
for (BigClip b : c) {
System.out.println("Stopping "+b.toString());
b.stop();
System.out.println("Stopped "+b.toString());
}
}
public static void playMusic(File file) {
try {
AudioInputStream audioIn = AudioSystem.getAudioInputStream(file);
BigClip clip = new BigClip();
clip.open(audioIn);
clip.addLineListener(new SoundListener());
clip.loop(1);
clip.start();
clips.put(file.getName(), clip);
} catch (Exception e) {
System.err.println("Sound could not be started!");
e.printStackTrace(System.err);
}
}
}
答案 0 :(得分:0)
您尚未显示用于播放wav文件的代码。这使得诊断可能出错的地方有点困难!
1)wav应该只是在自己的线程上。如果你这样做,它不会阻止任何其他。 Java声音教程并没有特别好地指出这一点。所以:把调用wav播放的代码放在自己的runnable中,你应该没问题。
2)你可以在你希望播放之前“打开”wav。然后,当你最终告诉它时,它应该立即“开始”。
另一个注意事项:播放wav文件的代码如果已经在内存中运行得更快。因此,有时第一次wav播放只是在稍微犹豫之后开始。但是有可能通过播放零音量的另一种声音来解决这个问题,以便将声音播放代码放入内存中。我经常在有声音的节目开始时这样做。
如果您使用了如此多的cpus而JVM没有时间处理声音,则后台连续绘画只是一个问题。如果那是问题,我真的会感到惊讶。如果是的话,你可能听到的是声音回放,其中有很多点击。