我正在做一个简单的坦克游戏,它有背景音乐。每当播放器死亡时,我都需要停止播放音乐(播放器健康状态为0)。我该怎么办?
我尝试通过在play()
函数外部释放线程并使用t.stop()
停止线程来停止线程,但这没有用。
package com.company;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.*;
public class Sound implements Runnable
{
private String fileLocation;
public String getFileLocation() {
return fileLocation;
}
public Sound() {
}
public void play(String fileLocation)
{
Thread t = new Thread(this);
this.fileLocation = fileLocation;
t.start();
}
public void run ()
{
playSound(fileLocation);
}
public void playSound(String fileName)
{
File soundFile = new File(fileName);
AudioInputStream audioInputStream = null;
try
{
audioInputStream = AudioSystem.getAudioInputStream(soundFile);
}
catch (Exception e)
{
e.printStackTrace();
}
AudioFormat audioFormat = audioInputStream.getFormat();
SourceDataLine line = null;
DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
try
{
line = (SourceDataLine) AudioSystem.getLine(info);
line.open(audioFormat);
}
catch (LineUnavailableException e)
{
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
line.start();
int nBytesRead = 0;
byte[] abData = new byte[128000];
while (nBytesRead != -1)
{
try
{
nBytesRead = audioInputStream.read(abData, 0, abData.length);
}
catch (IOException e)
{
e.printStackTrace();
}
if (nBytesRead >= 0)
{
int nBytesWritten = line.write(abData, 0, nBytesRead);
}
}
line.drain();
line.close();
}
}
答案 0 :(得分:0)
声明一个易失的布尔值。为什么易挥发?因为它需要跨线程更新。
private volatile boolean playing;
在while子句中包含布尔值。
while(playing && nBytesRead != -1)
使布尔值可从播放线程外部访问。
public void setPlaying(boolean) {
this.playing = playing;
}
要关闭声音时,请致电setPlaying(false)
。不要忘记在声音开始之前将布尔值设为true。
这里唯一的缺点是声音可能会以喀哒声结束,因为它会立即发出声音。添加淡入淡出包括设置和调用javax.sound.sampled.Control对象(我对它们有好运),或摆弄PCM数据本身。
至少使用SourceDataLine
,我们可以访问字节(在您的abData
数组中)。可以根据您的音频格式将数据组合成PCM,然后将其乘以推子值(在诸如64帧之类的过程中,从1到0),逐渐将PCM值降低到0,然后取这些新的PCM值。并将其转换回字节并写入。是的,要摆脱点击会带来很多麻烦。但是值得。