[英]How to stop a sound played in a new thread?
I'm making a simple tank game and it has its background music. 我正在做一个简单的坦克游戏,它有背景音乐。 I need the music to stop whenever the player dies (players health int becomes 0).
每当播放器死亡时,我都需要停止播放音乐(播放器健康状态为0)。 How do i do it?
我该怎么做?
I tried stopping the thread by declraring the thread outside of the play()
function and stopping it with t.stop()
but it didn't work. 我试图通过在
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();
}
}
Declare a volatile boolean. 声明一个易失的布尔值。 Why volatile?
为什么易挥发? Because it needs to update across threads.
因为它需要跨线程更新。
private volatile boolean playing;
Include the boolean in the while clause. 在while子句中包含布尔值。
while(playing && nBytesRead != -1)
Make the boolean accessible from outside the playback thread. 使布尔值可从播放线程外部访问。
public void setPlaying(boolean) {
this.playing = playing;
}
When you want to turn off the sound, call setPlaying(false)
. 当您想要关闭声音时,请调用
setPlaying(false)
。 Don't forget to make the boolean true before the sound is started. 不要忘记在声音开始之前将布尔值设为true。
The only drawback here is that the sound may end with a click, since it will be instant. 唯一的缺点是声音可能会发出喀哒声,因为它会立即发出声音。 Adding a fade involves setting up and invoking a javax.sound.sampled.Control object (I've had dubious luck with these), or fiddling with the PCM data itself.
添加淡入淡出涉及设置并调用javax.sound.sampled.Control对象(我对它们有好运),或摆弄PCM数据本身。
At least with a SourceDataLine
, we have access to the bytes (in your abData
array). 至少使用
SourceDataLine
,我们可以访问字节(在您的abData
数组中)。 The data can be assembled into PCM according to your audio format, then multiplied by a fader value that goes from 1 to 0 over the course of something like 64 frames, dialing the PCM values down to 0 gradually, and then taking these new PCM values and converting them back to bytes and writing that. 可以根据您的音频格式将数据组合成PCM,然后将其乘以推子值(在诸如64帧之类的过程中,从1到0),逐渐将PCM值降低到0,然后取这些新PCM值并将其转换回字节并写入。 Yes, a lot of trouble just to get rid of a click.
是的,要摆脱点击会带来很多麻烦。 But worth it.
但很值得。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.