Allow Sounds to be stopped by interupting the Thread playing them.
This commit is contained in:
parent
573300ae49
commit
1b5eb872dd
@ -10,6 +10,7 @@ import de.teamteamteam.spacescooter.gui.InterfaceBar;
|
|||||||
import de.teamteamteam.spacescooter.gui.ScoreBar;
|
import de.teamteamteam.spacescooter.gui.ScoreBar;
|
||||||
import de.teamteamteam.spacescooter.gui.ShieldBar;
|
import de.teamteamteam.spacescooter.gui.ShieldBar;
|
||||||
import de.teamteamteam.spacescooter.level.Level;
|
import de.teamteamteam.spacescooter.level.Level;
|
||||||
|
import de.teamteamteam.spacescooter.sound.SoundSystem;
|
||||||
import de.teamteamteam.spacescooter.utility.CollisionHandler;
|
import de.teamteamteam.spacescooter.utility.CollisionHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -32,6 +33,11 @@ public class GameScreen extends Screen {
|
|||||||
*/
|
*/
|
||||||
private long gameClockTrigger;
|
private long gameClockTrigger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal Thread handle for the background music.
|
||||||
|
*/
|
||||||
|
private Thread backgroundMusic;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GameScreen Constructor.
|
* GameScreen Constructor.
|
||||||
* Takes the level as its second parameter.
|
* Takes the level as its second parameter.
|
||||||
@ -48,6 +54,8 @@ public class GameScreen extends Screen {
|
|||||||
new HealthBar(10, 5);
|
new HealthBar(10, 5);
|
||||||
new ShieldBar(10, 27);
|
new ShieldBar(10, 27);
|
||||||
new ScoreBar(575, 33);
|
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() {
|
public static Player getPlayer() {
|
||||||
return GameScreen.player;
|
return GameScreen.player;
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ import de.teamteamteam.spacescooter.brain.GameConfig;
|
|||||||
import de.teamteamteam.spacescooter.control.Keyboard;
|
import de.teamteamteam.spacescooter.control.Keyboard;
|
||||||
import de.teamteamteam.spacescooter.entity.Player;
|
import de.teamteamteam.spacescooter.entity.Player;
|
||||||
import de.teamteamteam.spacescooter.gui.Button;
|
import de.teamteamteam.spacescooter.gui.Button;
|
||||||
import de.teamteamteam.spacescooter.sound.SoundSystem;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This Screen show the games main menu.
|
* 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 = new Player(GameConfig.windowWidth/2-170, 209);
|
||||||
player.setCanMove(false);
|
player.setCanMove(false);
|
||||||
player.setCanShoot(false);
|
player.setCanShoot(false);
|
||||||
SoundSystem.playSound("music/ScooterFriendsTurbo8Bit.wav");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -262,7 +262,7 @@ public abstract class Screen {
|
|||||||
* When a Screens life ends, this method will take care of existing overlays
|
* When a Screens life ends, this method will take care of existing overlays
|
||||||
* and remove all references to existing entities.
|
* and remove all references to existing entities.
|
||||||
*/
|
*/
|
||||||
private void cleanup() {
|
protected void cleanup() {
|
||||||
if(this.overlay != null) {
|
if(this.overlay != null) {
|
||||||
this.overlay.cleanup();
|
this.overlay.cleanup();
|
||||||
}
|
}
|
||||||
|
@ -97,35 +97,56 @@ public class SoundSystem {
|
|||||||
* Create a SourceDataLine and play the BufferedInputStream into it.
|
* Create a SourceDataLine and play the BufferedInputStream into it.
|
||||||
* Uses the internal audioPlayerRunnable since this operation is blocking.
|
* 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;
|
final URL fSoundURL = soundURL;
|
||||||
Thread soundThread = new Thread(new Runnable() {
|
Thread soundThread = new Thread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
|
AudioInputStream sound = null;
|
||||||
|
SourceDataLine sourceDataLine = null;
|
||||||
try {
|
try {
|
||||||
AudioInputStream sound = SoundSystem.getAudioInputStreamByURL(fSoundURL);
|
sound = SoundSystem.getAudioInputStreamByURL(fSoundURL);
|
||||||
sound.reset();
|
sound.reset();
|
||||||
SourceDataLine sourceDataLine = AudioSystem.getSourceDataLine(sound.getFormat());
|
sourceDataLine = AudioSystem.getSourceDataLine(sound.getFormat());
|
||||||
sourceDataLine.open(sound.getFormat());
|
sourceDataLine.open(sound.getFormat());
|
||||||
sourceDataLine.start();
|
sourceDataLine.start();
|
||||||
sound.reset();
|
sound.reset();
|
||||||
int chunksize = 16384*4;
|
int maxChunkSize = 4*4096;
|
||||||
byte[] b = new byte[chunksize];
|
byte[] b = new byte[maxChunkSize];
|
||||||
while (sound.available() > 0) {
|
int soundCapacity;
|
||||||
sound.read(b, 0, chunksize);
|
while ((soundCapacity = sound.available()) > 0) {
|
||||||
sourceDataLine.write(b, 0, chunksize);
|
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.drain();
|
||||||
sourceDataLine.close();
|
|
||||||
sound.close();
|
|
||||||
} catch (javax.sound.sampled.LineUnavailableException lue) {
|
} catch (javax.sound.sampled.LineUnavailableException lue) {
|
||||||
System.err.println("Could not play sound: " + fSoundURL);
|
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) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
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.setName("Sound: " + soundURL.toString());
|
||||||
soundThread.start();
|
soundThread.start();
|
||||||
|
return soundThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -151,10 +172,9 @@ public class SoundSystem {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Play a sound by passing a relative path to this method.
|
* 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) {
|
public static Thread playSound(String filename) {
|
||||||
SoundSystem.playFromAudioInputStream(Loader.getSoundURLByFilename(filename));
|
return SoundSystem.playFromAudioInputStream(Loader.getSoundURLByFilename(filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user