Added a listener for the end of music tracks.
Fixes a bug during gameplay where if the music track ends before the last hit object is processed (esp. spinners), the game would hang. Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
parent
e93fe25834
commit
84e463e8fb
|
@ -33,6 +33,7 @@ import org.lwjgl.BufferUtils;
|
||||||
import org.lwjgl.openal.AL;
|
import org.lwjgl.openal.AL;
|
||||||
import org.lwjgl.openal.AL10;
|
import org.lwjgl.openal.AL10;
|
||||||
import org.newdawn.slick.Music;
|
import org.newdawn.slick.Music;
|
||||||
|
import org.newdawn.slick.MusicListener;
|
||||||
import org.newdawn.slick.SlickException;
|
import org.newdawn.slick.SlickException;
|
||||||
import org.newdawn.slick.openal.Audio;
|
import org.newdawn.slick.openal.Audio;
|
||||||
import org.newdawn.slick.openal.SoundStore;
|
import org.newdawn.slick.openal.SoundStore;
|
||||||
|
@ -53,6 +54,9 @@ public class MusicController {
|
||||||
/** Thread for loading tracks. */
|
/** Thread for loading tracks. */
|
||||||
private static Thread trackLoader;
|
private static Thread trackLoader;
|
||||||
|
|
||||||
|
/** Whether or not the current track has ended. */
|
||||||
|
private static boolean trackEnded;
|
||||||
|
|
||||||
/** Whether the theme song is currently playing. */
|
/** Whether the theme song is currently playing. */
|
||||||
private static boolean themePlaying = false;
|
private static boolean themePlaying = false;
|
||||||
|
|
||||||
|
@ -107,6 +111,13 @@ public class MusicController {
|
||||||
private static void loadTrack(File file, int previewTime, boolean loop) {
|
private static void loadTrack(File file, int previewTime, boolean loop) {
|
||||||
try { // create a new player
|
try { // create a new player
|
||||||
player = new Music(file.getPath());
|
player = new Music(file.getPath());
|
||||||
|
player.addListener(new MusicListener() {
|
||||||
|
@Override
|
||||||
|
public void musicEnded(Music music) { trackEnded = true; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void musicSwapped(Music music, Music newMusic) {}
|
||||||
|
});
|
||||||
playAt((previewTime > 0) ? previewTime : 0, loop);
|
playAt((previewTime > 0) ? previewTime : 0, loop);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
ErrorHandler.error(String.format("Could not play track '%s'.", file.getName()), e, false);
|
ErrorHandler.error(String.format("Could not play track '%s'.", file.getName()), e, false);
|
||||||
|
@ -120,6 +131,7 @@ public class MusicController {
|
||||||
if (trackExists()) {
|
if (trackExists()) {
|
||||||
setVolume(Options.getMusicVolume() * Options.getMasterVolume());
|
setVolume(Options.getMusicVolume() * Options.getMasterVolume());
|
||||||
player.setPosition(position / 1000f);
|
player.setPosition(position / 1000f);
|
||||||
|
trackEnded = false;
|
||||||
pauseTime = 0f;
|
pauseTime = 0f;
|
||||||
if (loop)
|
if (loop)
|
||||||
player.loop();
|
player.loop();
|
||||||
|
@ -263,6 +275,11 @@ public class MusicController {
|
||||||
SoundStore.get().setMusicVolume(volume);
|
SoundStore.get().setMusicVolume(volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not the current track has ended.
|
||||||
|
*/
|
||||||
|
public static boolean trackEnded() { return trackEnded; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plays the theme song.
|
* Plays the theme song.
|
||||||
*/
|
*/
|
||||||
|
@ -320,6 +337,7 @@ public class MusicController {
|
||||||
|
|
||||||
// reset state
|
// reset state
|
||||||
lastOsu = null;
|
lastOsu = null;
|
||||||
|
trackEnded = false;
|
||||||
themePlaying = false;
|
themePlaying = false;
|
||||||
pauseTime = 0f;
|
pauseTime = 0f;
|
||||||
trackDimmed = false;
|
trackDimmed = false;
|
||||||
|
|
|
@ -152,11 +152,9 @@ public class Spinner implements HitObject {
|
||||||
@Override
|
@Override
|
||||||
public boolean update(boolean overlap, int delta, int mouseX, int mouseY) {
|
public boolean update(boolean overlap, int delta, int mouseX, int mouseY) {
|
||||||
int trackPosition = MusicController.getPosition();
|
int trackPosition = MusicController.getPosition();
|
||||||
if (overlap)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// end of spinner
|
// end of spinner
|
||||||
if (trackPosition > hitObject.getEndTime()) {
|
if (overlap || trackPosition > hitObject.getEndTime()) {
|
||||||
hitResult();
|
hitResult();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -332,7 +332,7 @@ public class Game extends BasicGameState {
|
||||||
|
|
||||||
// draw hit objects in reverse order, or else overlapping objects are unreadable
|
// draw hit objects in reverse order, or else overlapping objects are unreadable
|
||||||
Stack<Integer> stack = new Stack<Integer>();
|
Stack<Integer> stack = new Stack<Integer>();
|
||||||
for (int i = objectIndex; i < osu.objects.length && osu.objects[i].getTime() < trackPosition + approachTime; i++)
|
for (int i = objectIndex; i < hitObjects.length && osu.objects[i].getTime() < trackPosition + approachTime; i++)
|
||||||
stack.add(i);
|
stack.add(i);
|
||||||
|
|
||||||
while (!stack.isEmpty())
|
while (!stack.isEmpty())
|
||||||
|
@ -417,7 +417,11 @@ public class Game extends BasicGameState {
|
||||||
data.updateDisplays(delta);
|
data.updateDisplays(delta);
|
||||||
|
|
||||||
// map complete!
|
// map complete!
|
||||||
if (objectIndex >= osu.objects.length) {
|
if (objectIndex >= hitObjects.length || (MusicController.trackEnded() && objectIndex > 0)) {
|
||||||
|
// track ended before last object was processed: force a hit result
|
||||||
|
if (MusicController.trackEnded() && objectIndex < hitObjects.length)
|
||||||
|
hitObjects[objectIndex].update(true, delta, mouseX, mouseY);
|
||||||
|
|
||||||
if (checkpointLoaded) // if checkpoint used, skip ranking screen
|
if (checkpointLoaded) // if checkpoint used, skip ranking screen
|
||||||
game.closeRequested();
|
game.closeRequested();
|
||||||
else { // go to ranking screen
|
else { // go to ranking screen
|
||||||
|
@ -501,9 +505,9 @@ public class Game extends BasicGameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
// update objects (loop in unlikely event of any skipped indexes)
|
// update objects (loop in unlikely event of any skipped indexes)
|
||||||
while (objectIndex < osu.objects.length && trackPosition > osu.objects[objectIndex].getTime()) {
|
while (objectIndex < hitObjects.length && trackPosition > osu.objects[objectIndex].getTime()) {
|
||||||
// check if we've already passed the next object's start time
|
// check if we've already passed the next object's start time
|
||||||
boolean overlap = (objectIndex + 1 < osu.objects.length &&
|
boolean overlap = (objectIndex + 1 < hitObjects.length &&
|
||||||
trackPosition > osu.objects[objectIndex + 1].getTime() - hitResultOffset[GameData.HIT_300]);
|
trackPosition > osu.objects[objectIndex + 1].getTime() - hitResultOffset[GameData.HIT_300]);
|
||||||
|
|
||||||
// update hit object and check completion status
|
// update hit object and check completion status
|
||||||
|
@ -594,7 +598,7 @@ public class Game extends BasicGameState {
|
||||||
|
|
||||||
// skip to checkpoint
|
// skip to checkpoint
|
||||||
MusicController.setPosition(checkpoint);
|
MusicController.setPosition(checkpoint);
|
||||||
while (objectIndex < osu.objects.length &&
|
while (objectIndex < hitObjects.length &&
|
||||||
osu.objects[objectIndex++].getTime() <= checkpoint)
|
osu.objects[objectIndex++].getTime() <= checkpoint)
|
||||||
;
|
;
|
||||||
objectIndex--;
|
objectIndex--;
|
||||||
|
@ -635,7 +639,7 @@ public class Game extends BasicGameState {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (objectIndex >= osu.objects.length) // nothing left to do here
|
if (objectIndex >= hitObjects.length) // nothing left to do here
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OsuHitObject hitObject = osu.objects[objectIndex];
|
OsuHitObject hitObject = osu.objects[objectIndex];
|
||||||
|
|
Loading…
Reference in New Issue
Block a user