Allow Sounds to be stopped by interupting the Thread playing them.

This commit is contained in:
Jan Philipp Timme 2014-11-29 17:09:38 +01:00
parent 573300ae49
commit 1b5eb872dd
4 changed files with 53 additions and 16 deletions

View File

@ -10,6 +10,7 @@ import de.teamteamteam.spacescooter.gui.InterfaceBar;
import de.teamteamteam.spacescooter.gui.ScoreBar;
import de.teamteamteam.spacescooter.gui.ShieldBar;
import de.teamteamteam.spacescooter.level.Level;
import de.teamteamteam.spacescooter.sound.SoundSystem;
import de.teamteamteam.spacescooter.utility.CollisionHandler;
/**
@ -32,6 +33,11 @@ public class GameScreen extends Screen {
*/
private long gameClockTrigger;
/**
* Internal Thread handle for the background music.
*/
private Thread backgroundMusic;
/**
* GameScreen Constructor.
* Takes the level as its second parameter.
@ -48,6 +54,8 @@ public class GameScreen extends Screen {
new HealthBar(10, 5);
new ShieldBar(10, 27);
new ScoreBar(575, 33);
this.backgroundMusic = SoundSystem.playSound("music/ScooterFriendsTurbo8Bit.wav");
}
@ -93,6 +101,17 @@ public class GameScreen extends Screen {
}
}
/**
* Cleanup method for the background music.
*/
@Override
public void cleanup() {
System.out.println("Interrupting Music");
this.backgroundMusic.interrupt();
super.cleanup();
}
public static Player getPlayer() {
return GameScreen.player;
}

View File

@ -10,7 +10,6 @@ import de.teamteamteam.spacescooter.brain.GameConfig;
import de.teamteamteam.spacescooter.control.Keyboard;
import de.teamteamteam.spacescooter.entity.Player;
import de.teamteamteam.spacescooter.gui.Button;
import de.teamteamteam.spacescooter.sound.SoundSystem;
/**
* This Screen show the games main menu.
@ -36,7 +35,6 @@ public class MainMenuScreen extends Screen {
player = new Player(GameConfig.windowWidth/2-170, 209);
player.setCanMove(false);
player.setCanShoot(false);
SoundSystem.playSound("music/ScooterFriendsTurbo8Bit.wav");
}
@Override

View File

@ -262,7 +262,7 @@ public abstract class Screen {
* When a Screens life ends, this method will take care of existing overlays
* and remove all references to existing entities.
*/
private void cleanup() {
protected void cleanup() {
if(this.overlay != null) {
this.overlay.cleanup();
}

View File

@ -97,35 +97,56 @@ public class SoundSystem {
* Create a SourceDataLine and play the BufferedInputStream into it.
* Uses the internal audioPlayerRunnable since this operation is blocking.
*/
public static void playFromAudioInputStream(URL soundURL) {
public static Thread playFromAudioInputStream(URL soundURL) {
final URL fSoundURL = soundURL;
Thread soundThread = new Thread(new Runnable() {
public void run() {
AudioInputStream sound = null;
SourceDataLine sourceDataLine = null;
try {
AudioInputStream sound = SoundSystem.getAudioInputStreamByURL(fSoundURL);
sound = SoundSystem.getAudioInputStreamByURL(fSoundURL);
sound.reset();
SourceDataLine sourceDataLine = AudioSystem.getSourceDataLine(sound.getFormat());
sourceDataLine = AudioSystem.getSourceDataLine(sound.getFormat());
sourceDataLine.open(sound.getFormat());
sourceDataLine.start();
sound.reset();
int chunksize = 16384*4;
byte[] b = new byte[chunksize];
while (sound.available() > 0) {
sound.read(b, 0, chunksize);
sourceDataLine.write(b, 0, chunksize);
int maxChunkSize = 4*4096;
byte[] b = new byte[maxChunkSize];
int soundCapacity;
while ((soundCapacity = sound.available()) > 0) {
if(Thread.interrupted()) throw new InterruptedException();
//Make sure we're only writing that many bytes, so we do NOT cause blocking!
//Otherwise, we are unable to interrupt this Thread properly and stop long sounds from playing!
int writeCapacity = sourceDataLine.available();
if(writeCapacity > soundCapacity) writeCapacity = soundCapacity;
if(writeCapacity > maxChunkSize) writeCapacity = maxChunkSize;
sound.read(b, 0, writeCapacity);
sourceDataLine.write(b, 0, writeCapacity);
}
sourceDataLine.drain();
sourceDataLine.close();
sound.close();
} catch (javax.sound.sampled.LineUnavailableException lue) {
System.err.println("Could not play sound: " + fSoundURL);
} catch (InterruptedException ie) {
//Nothing to do here, just falling into finally block, so we can
//close the sourceDataLine without draining it.
} catch (Exception e) {
e.printStackTrace();
} finally {
//Clean everything up properly.
if(sourceDataLine != null) sourceDataLine.close();
if(sound != null) {
try {
sound.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
});
soundThread.setName("Sound: " + soundURL.toString());
soundThread.start();
return soundThread;
}
/**
@ -151,10 +172,9 @@ public class SoundSystem {
/**
* Play a sound by passing a relative path to this method.
* TODO: Provide a method to stop existing sounds (aka BackgroundMusic!)
*/
public static void playSound(String filename) {
SoundSystem.playFromAudioInputStream(Loader.getSoundURLByFilename(filename));
public static Thread playSound(String filename) {
return SoundSystem.playFromAudioInputStream(Loader.getSoundURLByFilename(filename));
}
/**