Allow showing a replay after a game.

Added a pause-replay image by XinCrin, and deleted ranking-retry/ranking-exit images.

Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
Jeffrey Han 2015-03-11 15:53:19 -04:00
parent 7942522c9d
commit 37c0763f32
9 changed files with 84 additions and 56 deletions

BIN
res/pause-replay.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

View File

@ -349,7 +349,6 @@ public class GameData {
comboEnd = 0; comboEnd = 0;
comboBurstIndex = -1; comboBurstIndex = -1;
scoreData = null; scoreData = null;
replay = null;
} }
/** /**
@ -1229,13 +1228,13 @@ public class GameData {
/** /**
* Returns a Replay object encapsulating all game data. * Returns a Replay object encapsulating all game data.
* If a replay already exists, the existing object will be returned * If a replay already exists and frames is null, the existing object will
* (i.e. this will not overwrite existing data). * be returned.
* @param frames the replay frames * @param frames the replay frames
* @return the Replay object * @return the Replay object, or null if none exists and frames is null
*/ */
public Replay getReplay(ReplayFrame[] frames) { public Replay getReplay(ReplayFrame[] frames) {
if (replay != null) if (replay != null && frames == null)
return replay; return replay;
if (frames == null) if (frames == null)
@ -1261,6 +1260,7 @@ public class GameData {
replay.timestamp = new Date(); replay.timestamp = new Date();
replay.frames = frames; replay.frames = frames;
replay.seed = 0; // TODO replay.seed = 0; // TODO
replay.loaded = true;
return replay; return replay;
} }

View File

@ -87,6 +87,7 @@ public enum GameImage {
PAUSE_CONTINUE ("pause-continue", "png"), PAUSE_CONTINUE ("pause-continue", "png"),
PAUSE_RETRY ("pause-retry", "png"), PAUSE_RETRY ("pause-retry", "png"),
PAUSE_BACK ("pause-back", "png"), PAUSE_BACK ("pause-back", "png"),
PAUSE_REPLAY ("pause-replay", "png"),
PAUSE_OVERLAY ("pause-overlay", "png|jpg") { PAUSE_OVERLAY ("pause-overlay", "png|jpg") {
@Override @Override
protected Image process_sub(Image img, int w, int h) { protected Image process_sub(Image img, int w, int h) {
@ -414,8 +415,6 @@ public enum GameImage {
return MUSIC_PLAY.process_sub(img, w, h); return MUSIC_PLAY.process_sub(img, w, h);
} }
}, },
RANKING_RETRY ("ranking-retry", "png", false, false),
RANKING_EXIT ("ranking-back", "png", false, false),
DOWNLOADS ("downloads", "png", false, false) { DOWNLOADS ("downloads", "png", false, 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

@ -51,6 +51,9 @@ public class Replay {
/** The associated file. */ /** The associated file. */
private File file; private File file;
/** Whether or not the replay data has been loaded from the file. */
public boolean loaded = false;
/** The game mode. */ /** The game mode. */
public byte mode; public byte mode;
@ -116,11 +119,15 @@ public class Replay {
* Loads the replay data. * Loads the replay data.
*/ */
public void load() { public void load() {
if (loaded)
return;
try { try {
OsuReader reader = new OsuReader(file); OsuReader reader = new OsuReader(file);
loadHeader(reader); loadHeader(reader);
loadData(reader); loadData(reader);
reader.close(); reader.close();
loaded = true;
} catch (IOException e) { } catch (IOException e) {
ErrorHandler.error("Could not load replay data.", e, true); ErrorHandler.error("Could not load replay data.", e, true);
} }

View File

@ -74,6 +74,8 @@ public class Game extends BasicGameState {
NEW, NEW,
/** Manual retry. */ /** Manual retry. */
MANUAL, MANUAL,
/** Replay. */
REPLAY,
/** Health is zero: no-continue/force restart. */ /** Health is zero: no-continue/force restart. */
LOSE; LOSE;
} }
@ -844,10 +846,11 @@ public class Game extends BasicGameState {
loadImages(); loadImages();
setMapModifiers(); setMapModifiers();
retries = 0; retries = 0;
} else { } else if (restart == Restart.MANUAL) {
// retry // retry
retries++; retries++;
} } else if (restart == Restart.REPLAY)
retries = 0;
// reset game data // reset game data
resetGameData(); resetGameData();
@ -937,7 +940,7 @@ public class Game extends BasicGameState {
// sleep execution // sleep execution
try { try {
Thread.sleep(0, 512000); Thread.sleep(0, 256000);
} catch (InterruptedException e) {} } catch (InterruptedException e) {}
} }
} }
@ -1159,10 +1162,14 @@ public class Game extends BasicGameState {
} }
/** /**
* Sets a replay to view. * Sets a replay to view, or resets the replay if null.
* @param replay the replay * @param replay the replay
*/ */
public void setReplay(Replay replay) { public void setReplay(Replay replay) {
if (replay == null) {
this.isReplay = false;
this.replay = null;
} else {
if (replay.frames == null) { if (replay.frames == null) {
ErrorHandler.error("Invalid replay.", null, false); ErrorHandler.error("Invalid replay.", null, false);
return; return;
@ -1170,6 +1177,7 @@ public class Game extends BasicGameState {
this.isReplay = true; this.isReplay = true;
this.replay = replay; this.replay = replay;
} }
}
/** /**
* Adds a replay frame to the list. * Adds a replay frame to the list.

View File

@ -29,6 +29,7 @@ import itdelatrisu.opsu.Utils;
import itdelatrisu.opsu.audio.MusicController; import itdelatrisu.opsu.audio.MusicController;
import itdelatrisu.opsu.audio.SoundController; import itdelatrisu.opsu.audio.SoundController;
import itdelatrisu.opsu.audio.SoundEffect; import itdelatrisu.opsu.audio.SoundEffect;
import itdelatrisu.opsu.replay.Replay;
import org.lwjgl.opengl.Display; import org.lwjgl.opengl.Display;
import org.newdawn.slick.Color; import org.newdawn.slick.Color;
@ -46,7 +47,7 @@ import org.newdawn.slick.state.transition.FadeOutTransition;
* "Game Ranking" (score card) state. * "Game Ranking" (score card) state.
* <ul> * <ul>
* <li>[Retry] - restart game (return to game state) * <li>[Retry] - restart game (return to game state)
* <li>[Exit] - return to main menu state * <li>[Replay] - watch replay (return to game state)
* <li>[Back] - return to song menu state * <li>[Back] - return to song menu state
* </ul> * </ul>
*/ */
@ -54,8 +55,11 @@ public class GameRanking extends BasicGameState {
/** Associated GameData object. */ /** Associated GameData object. */
private GameData data; private GameData data;
/** "Retry" and "Exit" buttons. */ /** "Retry" and "Replay" buttons. */
private MenuButton retryButton, exitButton; private MenuButton retryButton, replayButton;
/** Button coordinates. */
private float retryY, replayY;
// game-related variables // game-related variables
private GameContainer container; private GameContainer container;
@ -78,18 +82,14 @@ public class GameRanking extends BasicGameState {
int height = container.getHeight(); int height = container.getHeight();
// buttons // buttons
Image retry = GameImage.RANKING_RETRY.getImage(); Image retry = GameImage.PAUSE_RETRY.getImage();
Image exit = GameImage.RANKING_EXIT.getImage(); Image replay = GameImage.PAUSE_REPLAY.getImage();
retryButton = new MenuButton(retry, replayY = (height * 0.985f) - replay.getHeight() / 2f;
width - (retry.getWidth() / 2f), retryY = replayY - (replay.getHeight() / 2f) - (retry.getHeight() / 1.975f);
(height * 0.97f) - (exit.getHeight() * 1.5f) retryButton = new MenuButton(retry, width - (retry.getWidth() / 2f), retryY);
); replayButton = new MenuButton(replay, width - (replay.getWidth() / 2f), replayY);
exitButton = new MenuButton(exit, retryButton.setHoverFade();
width - (exit.getWidth() / 2f), replayButton.setHoverFade();
(height * 0.97f) - (exit.getHeight() / 2f)
);
retryButton.setHoverFade(0.6f);
exitButton.setHoverFade(0.6f);
} }
@Override @Override
@ -108,10 +108,9 @@ public class GameRanking extends BasicGameState {
data.drawRankingElements(g, osu); data.drawRankingElements(g, osu);
// buttons // buttons
if (data.isGameplay()) { replayButton.draw();
if (data.isGameplay())
retryButton.draw(); retryButton.draw();
exitButton.draw();
}
UI.getBackButton().draw(); UI.getBackButton().draw();
UI.draw(g); UI.draw(g);
@ -122,10 +121,10 @@ public class GameRanking extends BasicGameState {
throws SlickException { throws SlickException {
UI.update(delta); UI.update(delta);
int mouseX = input.getMouseX(), mouseY = input.getMouseY(); int mouseX = input.getMouseX(), mouseY = input.getMouseY();
if (data.isGameplay()) { replayButton.hoverUpdate(delta, mouseX, mouseY);
if (data.isGameplay())
retryButton.hoverUpdate(delta, mouseX, mouseY); retryButton.hoverUpdate(delta, mouseX, mouseY);
exitButton.hoverUpdate(delta, mouseX, mouseY); else
} else
MusicController.loopTrackIfEnded(true); MusicController.loopTrackIfEnded(true);
UI.getBackButton().hoverUpdate(delta, mouseX, mouseY); UI.getBackButton().hoverUpdate(delta, mouseX, mouseY);
} }
@ -157,27 +156,38 @@ public class GameRanking extends BasicGameState {
if (button == Input.MOUSE_MIDDLE_BUTTON) if (button == Input.MOUSE_MIDDLE_BUTTON)
return; return;
if (data.isGameplay()) { // back to menu
if (retryButton.contains(x, y)) {
OsuFile osu = MusicController.getOsuFile();
Display.setTitle(String.format("%s - %s", game.getTitle(), osu.toString()));
((Game) game.getState(Opsu.STATE_GAME)).setRestart(Game.Restart.MANUAL);
SoundController.playSound(SoundEffect.MENUHIT);
game.enterState(Opsu.STATE_GAME, new FadeOutTransition(Color.black), new FadeInTransition(Color.black));
return;
} else if (exitButton.contains(x, y)) {
SoundController.playSound(SoundEffect.MENUBACK);
((MainMenu) game.getState(Opsu.STATE_MAINMENU)).reset();
((SongMenu) game.getState(Opsu.STATE_SONGMENU)).resetGameDataOnLoad();
UI.resetCursor();
game.enterState(Opsu.STATE_MAINMENU, new FadeOutTransition(Color.black), new FadeInTransition(Color.black));
return;
}
}
if (UI.getBackButton().contains(x, y)) { if (UI.getBackButton().contains(x, y)) {
returnToSongMenu(); returnToSongMenu();
return; return;
} }
// replay
boolean returnToGame = false;
if (replayButton.contains(x, y)) {
Replay r = data.getReplay(null);
if (r != null) {
r.load();
((Game) game.getState(Opsu.STATE_GAME)).setReplay(r);
((Game) game.getState(Opsu.STATE_GAME)).setRestart(Game.Restart.REPLAY);
returnToGame = true;
}
}
// retry
else if (data.isGameplay() && retryButton.contains(x, y)) {
((Game) game.getState(Opsu.STATE_GAME)).setReplay(null);
((Game) game.getState(Opsu.STATE_GAME)).setRestart(Game.Restart.MANUAL);
returnToGame = true;
}
if (returnToGame) {
OsuFile osu = MusicController.getOsuFile();
Display.setTitle(String.format("%s - %s", game.getTitle(), osu.toString()));
SoundController.playSound(SoundEffect.MENUHIT);
game.enterState(Opsu.STATE_GAME, new FadeOutTransition(Color.black), new FadeInTransition(Color.black));
return;
}
} }
@Override @Override
@ -188,11 +198,13 @@ public class GameRanking extends BasicGameState {
if (!data.isGameplay()) { if (!data.isGameplay()) {
if (!MusicController.isTrackDimmed()) if (!MusicController.isTrackDimmed())
MusicController.toggleTrackDimmed(0.5f); MusicController.toggleTrackDimmed(0.5f);
replayButton.setY(retryY);
} else { } else {
SoundController.playSound(SoundEffect.APPLAUSE); SoundController.playSound(SoundEffect.APPLAUSE);
retryButton.resetHover(); retryButton.resetHover();
exitButton.resetHover(); replayButton.setY(replayY);
} }
replayButton.resetHover();
} }
@Override @Override

View File

@ -1298,7 +1298,9 @@ public class SongMenu extends BasicGameState {
HitSound.setDefaultSampleSet(osu.sampleSet); HitSound.setDefaultSampleSet(osu.sampleSet);
MultiClip.destroyExtraClips(); MultiClip.destroyExtraClips();
((Game) game.getState(Opsu.STATE_GAME)).setRestart(Game.Restart.NEW); Game gameState = (Game) game.getState(Opsu.STATE_GAME);
gameState.setRestart(Game.Restart.NEW);
gameState.setReplay(null);
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));
} }
} }