Minor updates and code improvements.

- MusicController.getPosition() now returns time even when track is paused. (e.g. song progress bar in main menu won't reset when paused)
- Force unpause track when entering the song menu.
- Rewrote Game.RESTART_* constants as enums.
- Cleaned up logo play/exit button scaling.
- MainMenu.previous is now non-static.

Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
Jeffrey Han 2015-01-15 00:56:30 -05:00
parent 03095733df
commit b856e2924c
7 changed files with 70 additions and 44 deletions

View File

@ -257,9 +257,18 @@ public enum GameImage {
return img.getScaledCopy((h / 1.2f) / img.getHeight()); return img.getScaledCopy((h / 1.2f) / img.getHeight());
} }
}, },
// TODO: scale MENU_PLAY and MENU_EXIT MENU_PlAY ("menu-play.png", false) {
MENU_PlAY ("menu-play.png", false), @Override
MENU_EXIT ("menu-exit.png", false), protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy(MENU_LOGO.getImage().getWidth() * 0.83f / img.getWidth());
}
},
MENU_EXIT ("menu-exit.png", false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy(MENU_LOGO.getImage().getWidth() * 0.66f / img.getWidth());
}
},
MENU_BUTTON_MID ("button-middle.png", false) { MENU_BUTTON_MID ("button-middle.png", false) {
@Override @Override
protected Image process_sub(Image img, int w, int h) { protected Image process_sub(Image img, int w, int h) {

View File

@ -66,6 +66,11 @@ public class MusicController {
*/ */
private static boolean themePlaying = false; private static boolean themePlaying = false;
/**
* Track pause time.
*/
private static float pauseTime = 0f;
// This class should not be instantiated. // This class should not be instantiated.
private MusicController() {} private MusicController() {}
@ -141,6 +146,7 @@ public class MusicController {
player.loop(); player.loop();
else else
player.play(); player.play();
pauseTime = 0f;
} }
} }
@ -205,12 +211,21 @@ public class MusicController {
return (trackExists() && player.playing()); return (trackExists() && player.playing());
} }
/**
* Returns true if the current track is paused.
*/
public static boolean isPaused() {
return (trackExists() && pauseTime > 0f);
}
/** /**
* Pauses the current track. * Pauses the current track.
*/ */
public static void pause() { public static void pause() {
if (isPlaying()) if (isPlaying()) {
pauseTime = player.getPosition();
player.pause(); player.pause();
}
} }
/** /**
@ -218,6 +233,7 @@ public class MusicController {
*/ */
public static void resume() { public static void resume() {
if (trackExists()) { if (trackExists()) {
pauseTime = 0f;
player.resume(); player.resume();
player.setVolume(1.0f); player.setVolume(1.0f);
} }
@ -241,11 +257,13 @@ public class MusicController {
/** /**
* Returns the position in the current track, in ms. * Returns the position in the current track, in ms.
* If no track is playing, 0 will be returned. * If no track is loaded, 0 will be returned.
*/ */
public static int getPosition() { public static int getPosition() {
if (isPlaying()) if (isPlaying())
return Math.max((int) (player.getPosition() * 1000 + Options.getMusicOffset()), 0); return Math.max((int) (player.getPosition() * 1000 + Options.getMusicOffset()), 0);
else if (isPaused())
return Math.max((int) (pauseTime * 1000 + Options.getMusicOffset()), 0);
else else
return 0; return 0;
} }

View File

@ -61,11 +61,12 @@ public class Game extends BasicGameState {
/** /**
* Game restart states. * Game restart states.
*/ */
public static final byte public enum Restart {
RESTART_FALSE = 0, FALSE, // no restart
RESTART_NEW = 1, // first time loading song NEW, // first time loading song
RESTART_MANUAL = 2, // retry MANUAL, // retry
RESTART_LOSE = 3; // health is zero: no-continue/force restart LOSE; // health is zero: no-continue/force restart
}
/** /**
* Minimum time before start of song, in milliseconds, to process skip-related actions. * Minimum time before start of song, in milliseconds, to process skip-related actions.
@ -120,7 +121,7 @@ public class Game extends BasicGameState {
/** /**
* Current restart state. * Current restart state.
*/ */
private byte restart; private Restart restart;
/** /**
* Current break index in breaks ArrayList. * Current break index in breaks ArrayList.
@ -570,7 +571,7 @@ public class Game extends BasicGameState {
} }
// game over, force a restart // game over, force a restart
restart = RESTART_LOSE; restart = Restart.LOSE;
game.enterState(Opsu.STATE_GAMEPAUSEMENU); game.enterState(Opsu.STATE_GAMEPAUSEMENU);
} }
@ -638,7 +639,7 @@ public class Game extends BasicGameState {
try { try {
if (trackPosition < osu.objects[0].getTime()) if (trackPosition < osu.objects[0].getTime())
retries--; // don't count this retry (cancel out later increment) retries--; // don't count this retry (cancel out later increment)
restart = RESTART_MANUAL; restart = Restart.MANUAL;
enter(container, game); enter(container, game);
skipIntro(); skipIntro();
} catch (SlickException e) { } catch (SlickException e) {
@ -664,7 +665,7 @@ public class Game extends BasicGameState {
if (checkpoint == 0 || checkpoint > osu.endTime) if (checkpoint == 0 || checkpoint > osu.endTime)
break; // invalid checkpoint break; // invalid checkpoint
try { try {
restart = RESTART_MANUAL; restart = Restart.MANUAL;
enter(container, game); enter(container, game);
checkpointLoaded = true; checkpointLoaded = true;
if (isLeadIn()) { if (isLeadIn()) {
@ -740,7 +741,7 @@ public class Game extends BasicGameState {
@Override @Override
public void enter(GameContainer container, StateBasedGame game) public void enter(GameContainer container, StateBasedGame game)
throws SlickException { throws SlickException {
if (restart == RESTART_NEW) if (restart == Restart.NEW)
osu = MusicController.getOsuFile(); osu = MusicController.getOsuFile();
if (osu == null || osu.objects == null) if (osu == null || osu.objects == null)
@ -750,9 +751,9 @@ public class Game extends BasicGameState {
// container.setMouseGrabbed(true); // container.setMouseGrabbed(true);
// restart the game // restart the game
if (restart != RESTART_FALSE) { if (restart != Restart.FALSE) {
// new game // new game
if (restart == RESTART_NEW) { if (restart == Restart.NEW) {
loadImages(); loadImages();
setMapModifiers(); setMapModifiers();
retries = 0; retries = 0;
@ -816,7 +817,7 @@ public class Game extends BasicGameState {
} }
leadInTime = osu.audioLeadIn + approachTime; leadInTime = osu.audioLeadIn + approachTime;
restart = RESTART_FALSE; restart = Restart.FALSE;
} }
skipButton.setScale(1f); skipButton.setScale(1f);
@ -944,8 +945,8 @@ public class Game extends BasicGameState {
/** /**
* Sets/returns whether entering the state will restart it. * Sets/returns whether entering the state will restart it.
*/ */
public void setRestart(byte restart) { this.restart = restart; } public void setRestart(Restart restart) { this.restart = restart; }
public byte getRestart() { return restart; } public Restart getRestart() { return restart; }
/** /**
* Returns whether or not the track is in the lead-in time state. * Returns whether or not the track is in the lead-in time state.

View File

@ -85,13 +85,13 @@ public class GamePauseMenu extends BasicGameState {
public void render(GameContainer container, StateBasedGame game, Graphics g) public void render(GameContainer container, StateBasedGame game, Graphics g)
throws SlickException { throws SlickException {
// background // background
if (gameState.getRestart() != Game.RESTART_LOSE) if (gameState.getRestart() != Game.Restart.LOSE)
GameImage.PAUSE_OVERLAY.getImage().draw(); GameImage.PAUSE_OVERLAY.getImage().draw();
else else
GameImage.FAIL_BACKGROUND.getImage().draw(); GameImage.FAIL_BACKGROUND.getImage().draw();
// draw buttons // draw buttons
if (gameState.getRestart() != Game.RESTART_LOSE) if (gameState.getRestart() != Game.Restart.LOSE)
continueButton.draw(); continueButton.draw();
retryButton.draw(); retryButton.draw();
backButton.draw(); backButton.draw();
@ -126,21 +126,21 @@ public class GamePauseMenu extends BasicGameState {
switch (key) { switch (key) {
case Input.KEY_ESCAPE: case Input.KEY_ESCAPE:
// 'esc' will normally unpause, but will return to song menu if health is zero // 'esc' will normally unpause, but will return to song menu if health is zero
if (gameState.getRestart() == Game.RESTART_LOSE) { if (gameState.getRestart() == Game.Restart.LOSE) {
MusicController.stop(); MusicController.stop();
MusicController.playAt(MusicController.getOsuFile().previewTime, true); MusicController.playAt(MusicController.getOsuFile().previewTime, true);
SoundController.playSound(SoundEffect.MENUBACK); SoundController.playSound(SoundEffect.MENUBACK);
game.enterState(Opsu.STATE_SONGMENU, new FadeOutTransition(Color.black), new FadeInTransition(Color.black)); game.enterState(Opsu.STATE_SONGMENU, new FadeOutTransition(Color.black), new FadeInTransition(Color.black));
} else { } else {
SoundController.playSound(SoundEffect.MENUBACK); SoundController.playSound(SoundEffect.MENUBACK);
gameState.setRestart(Game.RESTART_FALSE); gameState.setRestart(Game.Restart.FALSE);
game.enterState(Opsu.STATE_GAME); game.enterState(Opsu.STATE_GAME);
} }
break; break;
case Input.KEY_R: case Input.KEY_R:
// restart // restart
if (input.isKeyDown(Input.KEY_RCONTROL) || input.isKeyDown(Input.KEY_LCONTROL)) { if (input.isKeyDown(Input.KEY_RCONTROL) || input.isKeyDown(Input.KEY_LCONTROL)) {
gameState.setRestart(Game.RESTART_MANUAL); gameState.setRestart(Game.Restart.MANUAL);
game.enterState(Opsu.STATE_GAME); game.enterState(Opsu.STATE_GAME);
} }
break; break;
@ -155,7 +155,7 @@ public class GamePauseMenu extends BasicGameState {
if (button == Input.MOUSE_MIDDLE_BUTTON) if (button == Input.MOUSE_MIDDLE_BUTTON)
return; return;
boolean loseState = (gameState.getRestart() == Game.RESTART_LOSE); boolean loseState = (gameState.getRestart() == Game.Restart.LOSE);
// if music faded out (i.e. health is zero), don't process any actions before FADEOUT_TIME // if music faded out (i.e. health is zero), don't process any actions before FADEOUT_TIME
if (loseState && System.currentTimeMillis() - pauseStartTime < FADEOUT_TIME) if (loseState && System.currentTimeMillis() - pauseStartTime < FADEOUT_TIME)
@ -163,11 +163,11 @@ public class GamePauseMenu extends BasicGameState {
if (continueButton.contains(x, y) && !loseState) { if (continueButton.contains(x, y) && !loseState) {
SoundController.playSound(SoundEffect.MENUBACK); SoundController.playSound(SoundEffect.MENUBACK);
gameState.setRestart(Game.RESTART_FALSE); gameState.setRestart(Game.Restart.FALSE);
game.enterState(Opsu.STATE_GAME); game.enterState(Opsu.STATE_GAME);
} else if (retryButton.contains(x, y)) { } else if (retryButton.contains(x, y)) {
SoundController.playSound(SoundEffect.MENUHIT); SoundController.playSound(SoundEffect.MENUHIT);
gameState.setRestart(Game.RESTART_MANUAL); gameState.setRestart(Game.Restart.MANUAL);
game.enterState(Opsu.STATE_GAME); game.enterState(Opsu.STATE_GAME);
} else if (backButton.contains(x, y)) { } else if (backButton.contains(x, y)) {
MusicController.pause(); // lose state MusicController.pause(); // lose state
@ -181,7 +181,7 @@ public class GamePauseMenu extends BasicGameState {
public void enter(GameContainer container, StateBasedGame game) public void enter(GameContainer container, StateBasedGame game)
throws SlickException { throws SlickException {
pauseStartTime = System.currentTimeMillis(); pauseStartTime = System.currentTimeMillis();
if (gameState.getRestart() == Game.RESTART_LOSE) { if (gameState.getRestart() == Game.Restart.LOSE) {
MusicController.fadeOut(FADEOUT_TIME); MusicController.fadeOut(FADEOUT_TIME);
SoundController.playSound(SoundEffect.FAIL); SoundController.playSound(SoundEffect.FAIL);
} else } else

View File

@ -168,7 +168,7 @@ public class GameRanking extends BasicGameState {
if (retryButton.contains(x, y)) { if (retryButton.contains(x, y)) {
OsuFile osu = MusicController.getOsuFile(); OsuFile osu = MusicController.getOsuFile();
Display.setTitle(String.format("%s - %s", game.getTitle(), osu.toString())); Display.setTitle(String.format("%s - %s", game.getTitle(), osu.toString()));
((Game) game.getState(Opsu.STATE_GAME)).setRestart(Game.RESTART_MANUAL); ((Game) game.getState(Opsu.STATE_GAME)).setRestart(Game.Restart.MANUAL);
SoundController.playSound(SoundEffect.MENUHIT); SoundController.playSound(SoundEffect.MENUHIT);
game.enterState(Opsu.STATE_GAME, new FadeOutTransition(Color.black), new FadeInTransition(Color.black)); game.enterState(Opsu.STATE_GAME, new FadeOutTransition(Color.black), new FadeInTransition(Color.black));
} else if (exitButton.contains(x, y)) { } else if (exitButton.contains(x, y)) {

View File

@ -91,7 +91,7 @@ public class MainMenu extends BasicGameState {
/** /**
* Indexes of previous songs. * Indexes of previous songs.
*/ */
private static Stack<Integer> previous; private Stack<Integer> previous;
/** /**
* Main menu background image (optional). * Main menu background image (optional).
@ -132,24 +132,18 @@ public class MainMenu extends BasicGameState {
int height = container.getHeight(); int height = container.getHeight();
// initialize buttons // initialize buttons
// TODO: clean this up, scale in GameImage.process_sub() Image logoImg = GameImage.MENU_LOGO.getImage();
Image logoImg = new Image("logo.png");
float buttonScale = (height / 1.2f) / logoImg.getHeight();
Image logoImgScaled = GameImage.MENU_LOGO.getImage();
logo = new MenuButton(logoImgScaled, width / 2f, height / 2f);
logo.setHoverScale(1.05f);
Image playImg = GameImage.MENU_PlAY.getImage(); Image playImg = GameImage.MENU_PlAY.getImage();
Image exitImg = GameImage.MENU_EXIT.getImage(); Image exitImg = GameImage.MENU_EXIT.getImage();
playImg = playImg.getScaledCopy((logoImg.getWidth() * 0.83f) / playImg.getWidth());
exitImg = exitImg.getScaledCopy((logoImg.getWidth() * 0.66f) / exitImg.getWidth());
float exitOffset = (playImg.getWidth() - exitImg.getWidth()) / 3f; float exitOffset = (playImg.getWidth() - exitImg.getWidth()) / 3f;
playButton = new MenuButton(playImg.getScaledCopy(buttonScale), logo = new MenuButton(logoImg, width / 2f, height / 2f);
width * 0.75f, (height / 2) - (logoImgScaled.getHeight() / 5f) playButton = new MenuButton(playImg,
width * 0.75f, (height / 2) - (logoImg.getHeight() / 5f)
); );
exitButton = new MenuButton(exitImg.getScaledCopy(buttonScale), exitButton = new MenuButton(exitImg,
width * 0.75f - exitOffset, (height / 2) + (exitImg.getHeight() / 2f) width * 0.75f - exitOffset, (height / 2) + (exitImg.getHeight() / 2f)
); );
logo.setHoverScale(1.05f);
playButton.setHoverScale(1.05f); playButton.setHoverScale(1.05f);
exitButton.setHoverScale(1.05f); exitButton.setHoverScale(1.05f);

View File

@ -582,6 +582,10 @@ public class SongMenu extends BasicGameState {
if (MusicController.isThemePlaying() && focusNode != null) if (MusicController.isThemePlaying() && focusNode != null)
MusicController.play(focusNode.osuFiles.get(focusNode.osuFileIndex), true); MusicController.play(focusNode.osuFiles.get(focusNode.osuFileIndex), true);
// unpause track
else if (MusicController.isPaused())
MusicController.resume();
// destroy skin images, if any // destroy skin images, if any
GameImage.destroySkinImages(); GameImage.destroySkinImages();
} }
@ -712,7 +716,7 @@ public class SongMenu extends BasicGameState {
Display.setTitle(String.format("%s - %s", game.getTitle(), osu.toString())); Display.setTitle(String.format("%s - %s", game.getTitle(), osu.toString()));
OsuParser.parseHitObjects(osu); OsuParser.parseHitObjects(osu);
HitSound.setSampleSet(osu.sampleSet); HitSound.setSampleSet(osu.sampleSet);
((Game) game.getState(Opsu.STATE_GAME)).setRestart(Game.RESTART_NEW); ((Game) game.getState(Opsu.STATE_GAME)).setRestart(Game.Restart.NEW);
game.enterState(Opsu.STATE_GAME, new FadeOutTransition(Color.black), new FadeInTransition(Color.black)); game.enterState(Opsu.STATE_GAME, new FadeOutTransition(Color.black), new FadeInTransition(Color.black));
} }
} }