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). 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.
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(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)
. Don't forget to make the boolean true before the sound is started.
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.
At least with a SourceDataLine
, we have access to the bytes (in your abData
array). 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. Yes, a lot of trouble just to get rid of a click. But worth it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.