convert game

This commit is contained in:
yugecin 2017-01-19 19:23:31 +01:00
parent 4b2f29df98
commit a3df6e12d6
13 changed files with 497 additions and 423 deletions

View File

@ -89,7 +89,7 @@ public class Opsu extends StateBasedGame {
//addState(new MainMenu(STATE_MAINMENU)); //addState(new MainMenu(STATE_MAINMENU));
//addState(new ButtonMenu(STATE_BUTTONMENU)); //addState(new ButtonMenu(STATE_BUTTONMENU));
//addState(new SongMenu(STATE_SONGMENU)); //addState(new SongMenu(STATE_SONGMENU));
addState(new Game(STATE_GAME)); //addState(new Game(STATE_GAME));
addState(new GamePauseMenu(STATE_GAMEPAUSEMENU)); addState(new GamePauseMenu(STATE_GAMEPAUSEMENU));
//addState(new GameRanking(STATE_GAMERANKING)); //addState(new GameRanking(STATE_GAMERANKING));
//addState(new OptionsMenu(STATE_OPTIONSMENU)); //addState(new OptionsMenu(STATE_OPTIONSMENU));

View File

@ -64,10 +64,9 @@ public class Circle extends GameObject {
/** /**
* Initializes the Circle data type with map modifiers, images, and dimensions. * Initializes the Circle data type with map modifiers, images, and dimensions.
* @param container the game container
* @param circleDiameter the circle diameter * @param circleDiameter the circle diameter
*/ */
public static void init(GameContainer container, float circleDiameter) { public static void init(float circleDiameter) {
diameter = circleDiameter * HitObject.getXMultiplier(); // convert from Osupixels (640x480) diameter = circleDiameter * HitObject.getXMultiplier(); // convert from Osupixels (640x480)
int diameterInt = (int) diameter; int diameterInt = (int) diameter;
GameImage.HITCIRCLE.setImage(GameImage.HITCIRCLE.getImage().getScaledCopy(diameterInt, diameterInt)); GameImage.HITCIRCLE.setImage(GameImage.HITCIRCLE.getImage().getScaledCopy(diameterInt, diameterInt));

View File

@ -37,6 +37,7 @@ import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics; import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image; import org.newdawn.slick.Image;
import yugecin.opsudance.Dancer; import yugecin.opsudance.Dancer;
import yugecin.opsudance.core.DisplayContainer;
/** /**
* Data type representing a slider object. * Data type representing a slider object.
@ -127,13 +128,12 @@ public class Slider extends GameObject {
/** /**
* Initializes the Slider data type with images and dimensions. * Initializes the Slider data type with images and dimensions.
* @param container the game container
* @param circleDiameter the circle diameter * @param circleDiameter the circle diameter
* @param beatmap the associated beatmap * @param beatmap the associated beatmap
*/ */
public static void init(GameContainer container, float circleDiameter, Beatmap beatmap) { public static void init(DisplayContainer displayContainer, float circleDiameter, Beatmap beatmap) {
containerWidth = container.getWidth(); containerWidth = displayContainer.width;
containerHeight = container.getHeight(); containerHeight = displayContainer.height;
diameter = circleDiameter * HitObject.getXMultiplier(); // convert from Osupixels (640x480) diameter = circleDiameter * HitObject.getXMultiplier(); // convert from Osupixels (640x480)
int diameterInt = (int) diameter; int diameterInt = (int) diameter;

View File

@ -35,6 +35,7 @@ import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer; import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics; import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image; import org.newdawn.slick.Image;
import yugecin.opsudance.core.DisplayContainer;
/** /**
* Data type representing a spinner object. * Data type representing a spinner object.
@ -109,12 +110,11 @@ public class Spinner extends GameObject {
/** /**
* Initializes the Spinner data type with images and dimensions. * Initializes the Spinner data type with images and dimensions.
* @param container the game container
* @param difficulty the map's overall difficulty value * @param difficulty the map's overall difficulty value
*/ */
public static void init(GameContainer container, float difficulty) { public static void init(DisplayContainer displayContainer, float difficulty) {
width = container.getWidth(); width = displayContainer.width;
height = container.getHeight(); height = displayContainer.height;
overallDifficulty = difficulty; overallDifficulty = difficulty;
} }

View File

@ -18,11 +18,9 @@
package itdelatrisu.opsu.states; package itdelatrisu.opsu.states;
import itdelatrisu.opsu.ErrorHandler;
import itdelatrisu.opsu.GameData; import itdelatrisu.opsu.GameData;
import itdelatrisu.opsu.GameImage; import itdelatrisu.opsu.GameImage;
import itdelatrisu.opsu.GameMod; import itdelatrisu.opsu.GameMod;
import itdelatrisu.opsu.Opsu;
import itdelatrisu.opsu.Options; import itdelatrisu.opsu.Options;
import itdelatrisu.opsu.ScoreData; import itdelatrisu.opsu.ScoreData;
import itdelatrisu.opsu.Utils; import itdelatrisu.opsu.Utils;
@ -59,26 +57,28 @@ import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display; import org.lwjgl.opengl.Display;
import org.newdawn.slick.Animation; import org.newdawn.slick.Animation;
import org.newdawn.slick.Color; import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics; import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image; import org.newdawn.slick.Image;
import org.newdawn.slick.Input; import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException; import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.BasicGameState; import org.newdawn.slick.util.Log;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.state.transition.DelayedFadeOutTransition;
import org.newdawn.slick.state.transition.EasedFadeOutTransition;
import org.newdawn.slick.state.transition.EmptyTransition;
import org.newdawn.slick.state.transition.FadeInTransition;
import yugecin.opsudance.*; import yugecin.opsudance.*;
import yugecin.opsudance.core.DisplayContainer;
import yugecin.opsudance.core.inject.InstanceContainer;
import yugecin.opsudance.core.state.ComplexOpsuState;
import yugecin.opsudance.events.BubbleNotificationEvent;
import yugecin.opsudance.objects.curves.FakeCombinedCurve; import yugecin.opsudance.objects.curves.FakeCombinedCurve;
import yugecin.opsudance.sbv2.MoveStoryboard; import yugecin.opsudance.sbv2.MoveStoryboard;
import yugecin.opsudance.ui.SBOverlay; import yugecin.opsudance.ui.OptionsOverlay;
import yugecin.opsudance.ui.StoryboardOverlay;
/** /**
* "Game" state. * "Game" state.
*/ */
public class Game extends BasicGameState { public class Game extends ComplexOpsuState {
private final InstanceContainer instanceContainer;
public static boolean isInGame; // TODO delete this when #79 is fixed public static boolean isInGame; // TODO delete this when #79 is fixed
/** Game restart states. */ /** Game restart states. */
public enum Restart { public enum Restart {
@ -307,31 +307,61 @@ public class Game extends BasicGameState {
MUSICBAR_HOVER = new Color(12, 9, 10, 0.35f), MUSICBAR_HOVER = new Color(12, 9, 10, 0.35f),
MUSICBAR_FILL = new Color(255, 255, 255, 0.75f); MUSICBAR_FILL = new Color(255, 255, 255, 0.75f);
// game-related variables
private GameContainer container;
private StateBasedGame game;
private Input input;
private final int state;
private final Cursor mirrorCursor; private final Cursor mirrorCursor;
private MoveStoryboard msb; private final MoveStoryboard moveStoryboardOverlay;
private SBOverlay sbOverlay; private final StoryboardOverlay storyboardOverlay;
private final OptionsOverlay optionsOverlay;
private FakeCombinedCurve knorkesliders; private FakeCombinedCurve knorkesliders;
private boolean skippedToCheckpoint; private boolean skippedToCheckpoint;
public Game(int state) { public Game(DisplayContainer displayContainer, InstanceContainer instanceContainer) {
this.state = state; super(displayContainer);
this.instanceContainer = instanceContainer;
mirrorCursor = new Cursor(true); mirrorCursor = new Cursor(true);
this.moveStoryboardOverlay = new MoveStoryboard(displayContainer);
this.optionsOverlay = new OptionsOverlay(displayContainer, OptionsMenu.storyboardOptions, 0);
this.storyboardOverlay = new StoryboardOverlay(displayContainer, moveStoryboardOverlay, optionsOverlay, this);
storyboardOverlay.show();
moveStoryboardOverlay.show();
optionsOverlay.setListener(storyboardOverlay);
} }
public void loadCheckpoint(int checkpoint) { @Override
public void revalidate() {
// create offscreen graphics
try { try {
offscreen = new Image(displayContainer.width, displayContainer.height);
gOffscreen = offscreen.getGraphics();
gOffscreen.setBackground(Color.black);
} catch (SlickException e) {
Log.error("could not create offscreen graphics", e);
displayContainer.eventBus.post(new BubbleNotificationEvent("Exception while creating offscreen graphics. See logfile for details.", BubbleNotificationEvent.COMMONCOLOR_RED));
}
// initialize music position bar location
musicBarX = displayContainer.width * 0.01f;
musicBarY = displayContainer.height * 0.05f;
musicBarWidth = Math.max(displayContainer.width * 0.005f, 7);
musicBarHeight = displayContainer.height * 0.9f;
// initialize scoreboard star stream
scoreboardStarStream = new StarStream(0, displayContainer.height * 2f / 3f, displayContainer.width / 4, 0, 0);
scoreboardStarStream.setPositionSpread(displayContainer.height / 20f);
scoreboardStarStream.setDirectionSpread(10f);
scoreboardStarStream.setDurationSpread(700, 100);
// create the associated GameData object
data = new GameData(displayContainer.width, displayContainer.height);
}
public void loadCheckpoint(int checkpoint) {
restart = Restart.MANUAL; restart = Restart.MANUAL;
checkpointLoaded = true; checkpointLoaded = true;
skippedToCheckpoint = true; skippedToCheckpoint = true;
enter(container, game); enter();
if (isLeadIn()) { if (isLeadIn()) {
leadInTime = 0; leadInTime = 0;
epiImgTime = 0; epiImgTime = 0;
@ -357,51 +387,15 @@ public class Game extends BasicGameState {
spliceSliderCurve(-1, -1); spliceSliderCurve(-1, -1);
} }
Dancer.instance.setObjectIndex(objectIndex); Dancer.instance.setObjectIndex(objectIndex);
sbOverlay.updateIndex(objectIndex); storyboardOverlay.updateIndex(objectIndex);
lastReplayTime = beatmap.objects[objectIndex].getTime(); lastReplayTime = beatmap.objects[objectIndex].getTime();
} catch (SlickException e) {
e.printStackTrace();
}
} }
@Override @Override
public void init(GameContainer container, StateBasedGame game) public void render(Graphics g) {
throws SlickException { int width = displayContainer.width;
this.msb = new MoveStoryboard(container); int height = displayContainer.height;
this.sbOverlay = new SBOverlay(this, msb, container);
this.container = container;
this.game = game;
input = container.getInput();
int width = container.getWidth();
int height = container.getHeight();
// create offscreen graphics
offscreen = new Image(width, height);
gOffscreen = offscreen.getGraphics();
gOffscreen.setBackground(Color.black);
// initialize music position bar location
musicBarX = width * 0.01f;
musicBarY = height * 0.05f;
musicBarWidth = Math.max(width * 0.005f, 7);
musicBarHeight = height * 0.9f;
// initialize scoreboard star stream
scoreboardStarStream = new StarStream(0, height * 2f / 3f, width / 4, 0, 0);
scoreboardStarStream.setPositionSpread(height / 20f);
scoreboardStarStream.setDirectionSpread(10f);
scoreboardStarStream.setDurationSpread(700, 100);
// create the associated GameData object
data = new GameData(width, height);
}
@Override
public void render(GameContainer container, StateBasedGame game, Graphics g)
throws SlickException {
int width = container.getWidth();
int height = container.getHeight();
int trackPosition = MusicController.getPosition(); int trackPosition = MusicController.getPosition();
if (isLeadIn()) { if (isLeadIn()) {
trackPosition -= leadInTime - currentMapMusicOffset - Options.getMusicOffset(); trackPosition -= leadInTime - currentMapMusicOffset - Options.getMusicOffset();
@ -475,7 +469,7 @@ public class Game extends BasicGameState {
} }
} }
float[] sbPosition = sbOverlay.getPoint(trackPosition); float[] sbPosition = moveStoryboardOverlay.getPoint(trackPosition);
if (sbPosition != null) { if (sbPosition != null) {
autoPoint.x = sbPosition[0]; autoPoint.x = sbPosition[0];
autoPoint.y = sbPosition[1]; autoPoint.y = sbPosition[1];
@ -510,8 +504,8 @@ public class Game extends BasicGameState {
mouseX = replayX; mouseX = replayX;
mouseY = replayY; mouseY = replayY;
} else { } else {
mouseX = input.getMouseX(); mouseX = displayContainer.mouseX;
mouseY = input.getMouseY(); mouseY = displayContainer.mouseY;
} }
int alphaRadius = flashlightRadius * 256 / 215; int alphaRadius = flashlightRadius * 256 / 215;
int alphaX = mouseX - alphaRadius / 2; int alphaX = mouseX - alphaRadius / 2;
@ -686,7 +680,7 @@ public class Game extends BasicGameState {
float animation = AnimationEquation.IN_OUT_QUAD.calc( float animation = AnimationEquation.IN_OUT_QUAD.calc(
Utils.clamp((trackPosition - lastRankUpdateTime) / SCOREBOARD_ANIMATION_TIME, 0f, 1f) Utils.clamp((trackPosition - lastRankUpdateTime) / SCOREBOARD_ANIMATION_TIME, 0f, 1f)
); );
int scoreboardPosition = 2 * container.getHeight() / 3; int scoreboardPosition = 2 * displayContainer.height / 3;
// draw star stream behind the scores // draw star stream behind the scores
scoreboardStarStream.draw(); scoreboardStarStream.draw();
@ -727,8 +721,7 @@ public class Game extends BasicGameState {
// draw music position bar (for replay seeking) // draw music position bar (for replay seeking)
if (isReplay && Options.isReplaySeekingEnabled()) { if (isReplay && Options.isReplaySeekingEnabled()) {
int mouseX = input.getMouseX(), mouseY = input.getMouseY(); g.setColor((musicPositionBarContains(displayContainer.mouseX, displayContainer.mouseY)) ? MUSICBAR_HOVER : MUSICBAR_NORMAL);
g.setColor((musicPositionBarContains(mouseX, mouseY)) ? MUSICBAR_HOVER : MUSICBAR_NORMAL);
g.fillRoundRect(musicBarX, musicBarY, musicBarWidth, musicBarHeight, 4); g.fillRoundRect(musicBarX, musicBarY, musicBarWidth, musicBarHeight, 4);
if (!isLeadIn()) { if (!isLeadIn()) {
g.setColor(MUSICBAR_FILL); g.setColor(MUSICBAR_FILL);
@ -770,24 +763,27 @@ public class Game extends BasicGameState {
else else
UI.draw(g); UI.draw(g);
sbOverlay.render(container, g);
if (!Options.isHideWM()) { if (!Options.isHideWM()) {
Fonts.SMALL.drawString(0.3f, 0.3f, "opsu!dance " + Updater.get().getCurrentVersion() + " by robin_be | https://github.com/yugecin/opsu-dance"); Fonts.SMALL.drawString(0.3f, 0.3f, "opsu!dance " + Updater.get().getCurrentVersion() + " by robin_be | https://github.com/yugecin/opsu-dance");
} }
super.render(g);
} }
@Override @Override
public void update(GameContainer container, StateBasedGame game, int delta) public void preRenderUpdate() {
throws SlickException { super.preRenderUpdate();
int delta = displayContainer.renderDelta;
UI.update(delta); UI.update(delta);
Pippi.update(delta); Pippi.update(delta);
if (epiImgTime > 0) { if (epiImgTime > 0) {
epiImgTime -= delta; epiImgTime -= delta;
} }
yugecin.opsudance.spinners.Spinner.update(delta); yugecin.opsudance.spinners.Spinner.update(delta);
int mouseX = input.getMouseX(), mouseY = input.getMouseY(); int mouseX = displayContainer.mouseX;
sbOverlay.update(delta, mouseX, mouseY); int mouseY = displayContainer.mouseY;
skipButton.hoverUpdate(delta, mouseX, mouseY); skipButton.hoverUpdate(delta, mouseX, mouseY);
if (isReplay || GameMod.AUTO.isActive()) if (isReplay || GameMod.AUTO.isActive())
playbackSpeed.getButton().hoverUpdate(delta, mouseX, mouseY); playbackSpeed.getButton().hoverUpdate(delta, mouseX, mouseY);
@ -805,8 +801,8 @@ public class Game extends BasicGameState {
} }
// focus lost: go back to pause screen // focus lost: go back to pause screen
else if (!container.hasFocus()) { else if (!Display.isActive()) {
game.enterState(Opsu.STATE_GAMEPAUSEMENU); // TODO d displayContainer.switchState(GamePauseMenu.class);
pausePulse = 0f; pausePulse = 0f;
} }
@ -918,10 +914,13 @@ public class Game extends BasicGameState {
// game finished: change state after timer expires // game finished: change state after timer expires
if (gameFinished && !gameFinishedTimer.update(delta)) { if (gameFinished && !gameFinishedTimer.update(delta)) {
if (checkpointLoaded) // if checkpoint used, skip ranking screen if (checkpointLoaded) {
game.closeRequested(); // if checkpoint used, skip ranking screen
else // go to ranking screen onCloseRequest();
game.enterState(Opsu.STATE_GAMERANKING, new EasedFadeOutTransition(), new FadeInTransition()); } else {
// go to ranking screen
displayContainer.switchState(GameRanking.class);
}
} }
} }
@ -949,7 +948,7 @@ public class Game extends BasicGameState {
// save score and replay // save score and replay
if (!checkpointLoaded) { if (!checkpointLoaded) {
boolean unranked = (GameMod.AUTO.isActive() || GameMod.RELAX.isActive() || GameMod.AUTOPILOT.isActive()); boolean unranked = (GameMod.AUTO.isActive() || GameMod.RELAX.isActive() || GameMod.AUTOPILOT.isActive());
((GameRanking) game.getState(Opsu.STATE_GAMERANKING)).setGameData(data); instanceContainer.provide(GameRanking.class).setGameData(data);
if (isReplay) if (isReplay)
data.setReplay(replay); data.setReplay(replay);
else if (replayFrames != null) { else if (replayFrames != null) {
@ -1027,14 +1026,15 @@ public class Game extends BasicGameState {
} }
// pause game if focus lost // pause game if focus lost
if (!container.hasFocus() && !GameMod.AUTO.isActive() && !isReplay) { if (!Display.isActive() && !GameMod.AUTO.isActive() && !isReplay) {
if (pauseTime < 0) { if (pauseTime < 0) {
pausedMousePosition = new Vec2f(mouseX, mouseY); pausedMousePosition = new Vec2f(mouseX, mouseY);
pausePulse = 0f; pausePulse = 0f;
} }
if (MusicController.isPlaying() || isLeadIn()) if (MusicController.isPlaying() || isLeadIn()) {
pauseTime = trackPosition; pauseTime = trackPosition;
game.enterState(Opsu.STATE_GAMEPAUSEMENU, new EmptyTransition(), new FadeInTransition()); }
// TODO d displayContainer.switchState(GamePauseMenu.class);
} }
// drain health // drain health
@ -1058,13 +1058,10 @@ public class Game extends BasicGameState {
failTrackTime = MusicController.getPosition(); failTrackTime = MusicController.getPosition();
MusicController.fadeOut(MUSIC_FADEOUT_TIME); MusicController.fadeOut(MUSIC_FADEOUT_TIME);
MusicController.pitchFadeOut(MUSIC_FADEOUT_TIME); MusicController.pitchFadeOut(MUSIC_FADEOUT_TIME);
rotations = new IdentityHashMap<GameObject, Float>(); rotations = new IdentityHashMap<>();
SoundController.playSound(SoundEffect.FAIL); SoundController.playSound(SoundEffect.FAIL);
// fade to pause menu // TODO d displayContainer.switchState(GamePauseMenu.class, FadeOutTransitionState.class, MUSIC_FADEOUT_TIME - LOSE_FADEOUT_TIME, FadeInTransitionState.class, 300);
game.enterState(Opsu.STATE_GAMEPAUSEMENU,
new DelayedFadeOutTransition(Color.black, MUSIC_FADEOUT_TIME, MUSIC_FADEOUT_TIME - LOSE_FADEOUT_TIME),
new FadeInTransition());
} }
} }
} }
@ -1088,7 +1085,7 @@ public class Game extends BasicGameState {
if (gameObjects[objectIndex].update(overlap, delta, mouseX, mouseY, keyPressed, trackPosition)) { if (gameObjects[objectIndex].update(overlap, delta, mouseX, mouseY, keyPressed, trackPosition)) {
skippedObject = true; skippedObject = true;
objectIndex++; // done, so increment object index objectIndex++; // done, so increment object index
sbOverlay.updateIndex(objectIndex); storyboardOverlay.updateIndex(objectIndex);
if (objectIndex >= mirrorTo) { if (objectIndex >= mirrorTo) {
Options.setMirror(false); Options.setMirror(false);
} }
@ -1099,20 +1096,25 @@ public class Game extends BasicGameState {
} }
@Override @Override
public int getID() { return state; } public boolean onCloseRequest() {
instanceContainer.provide(SongMenu.class).resetGameDataOnLoad();
displayContainer.switchState(SongMenu.class);
return false;
}
@Override @Override
public void keyPressed(int key, char c) { public boolean keyPressed(int key, char c) {
if (gameFinished) if (super.keyPressed(key, c)) {
return; return true;
}
if (sbOverlay.keyPressed(key, c)) { if (gameFinished) {
return; return true;
} }
int trackPosition = MusicController.getPosition(); int trackPosition = MusicController.getPosition();
int mouseX = input.getMouseX(); int mouseX = displayContainer.mouseX;
int mouseY = input.getMouseY(); int mouseY = displayContainer.mouseY;
// game keys // game keys
if (!Keyboard.isRepeatEvent()) { if (!Keyboard.isRepeatEvent()) {
@ -1129,7 +1131,7 @@ public class Game extends BasicGameState {
case Input.KEY_ESCAPE: case Input.KEY_ESCAPE:
// "auto" mod or watching replay: go back to song menu // "auto" mod or watching replay: go back to song menu
if (GameMod.AUTO.isActive() || isReplay) { if (GameMod.AUTO.isActive() || isReplay) {
game.closeRequested(); onCloseRequest();
break; break;
} }
@ -1138,9 +1140,10 @@ public class Game extends BasicGameState {
pausedMousePosition = new Vec2f(mouseX, mouseY); pausedMousePosition = new Vec2f(mouseX, mouseY);
pausePulse = 0f; pausePulse = 0f;
} }
if (MusicController.isPlaying() || isLeadIn()) if (MusicController.isPlaying() || isLeadIn()) {
pauseTime = trackPosition; pauseTime = trackPosition;
game.enterState(Opsu.STATE_GAMEPAUSEMENU, new EmptyTransition(), new FadeInTransition()); }
// TODO d displayContainer.switchStateNow(GamePauseMenu.class);
break; break;
case Input.KEY_SPACE: case Input.KEY_SPACE:
// skip intro // skip intro
@ -1148,23 +1151,21 @@ public class Game extends BasicGameState {
break; break;
case Input.KEY_R: case Input.KEY_R:
// restart // restart
if (input.isKeyDown(Input.KEY_RCONTROL) || input.isKeyDown(Input.KEY_LCONTROL)) { if (displayContainer.input.isKeyDown(Input.KEY_RCONTROL) || displayContainer.input.isKeyDown(Input.KEY_LCONTROL)) {
try { if (trackPosition < beatmap.objects[0].getTime()) {
if (trackPosition < beatmap.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;
enter(container, game);
skipIntro();
} catch (SlickException e) {
ErrorHandler.error("Failed to restart game.", e, false);
} }
restart = Restart.MANUAL;
enter();
skipIntro();
} }
break; break;
case Input.KEY_S: case Input.KEY_S:
// save checkpoint // save checkpoint
if (input.isKeyDown(Input.KEY_RCONTROL) || input.isKeyDown(Input.KEY_LCONTROL)) { if (displayContainer.input.isKeyDown(Input.KEY_RCONTROL) || displayContainer.input.isKeyDown(Input.KEY_LCONTROL)) {
if (isLeadIn()) if (isLeadIn()) {
break; break;
}
int position = (pauseTime > -1) ? pauseTime : trackPosition; int position = (pauseTime > -1) ? pauseTime : trackPosition;
if (Options.setCheckpoint(position / 1000)) { if (Options.setCheckpoint(position / 1000)) {
@ -1175,7 +1176,7 @@ public class Game extends BasicGameState {
break; break;
case Input.KEY_L: case Input.KEY_L:
// load checkpoint // load checkpoint
if (input.isKeyDown(Input.KEY_RCONTROL) || input.isKeyDown(Input.KEY_LCONTROL)) { if (displayContainer.input.isKeyDown(Input.KEY_RCONTROL) || displayContainer.input.isKeyDown(Input.KEY_LCONTROL)) {
int checkpoint = Options.getCheckpoint(); int checkpoint = Options.getCheckpoint();
if (checkpoint == 0 || checkpoint > beatmap.endTime) if (checkpoint == 0 || checkpoint > beatmap.endTime)
break; // invalid checkpoint break; // invalid checkpoint
@ -1197,16 +1198,6 @@ public class Game extends BasicGameState {
case Input.KEY_DOWN: case Input.KEY_DOWN:
UI.changeVolume(-1); UI.changeVolume(-1);
break; break;
case Input.KEY_F7:
// TODO d
//Options.setNextFPS(container);
break;
case Input.KEY_F10:
Options.toggleMouseDisabled();
break;
case Input.KEY_F12:
Utils.takeScreenShot();
break;
case Input.KEY_TAB: case Input.KEY_TAB:
if (!Options.isHideUI()) { if (!Options.isHideUI()) {
scoreboardVisible = !scoreboardVisible; scoreboardVisible = !scoreboardVisible;
@ -1243,29 +1234,33 @@ public class Game extends BasicGameState {
currentMapMusicOffset -= 5; currentMapMusicOffset -= 5;
UI.sendBarNotification("Current map offset: " + currentMapMusicOffset); UI.sendBarNotification("Current map offset: " + currentMapMusicOffset);
} }
return true;
} }
@Override @Override
public void mouseDragged(int oldx, int oldy, int newx, int newy) { public boolean mouseDragged(int oldx, int oldy, int newx, int newy) {
if (sbOverlay.mouseDragged(oldx, oldy, newx, newy)) { if (super.mouseDragged(oldx, oldy, newx, newy)) {
//noinspection UnnecessaryReturnStatement return true;
return;
} }
return true;
} }
@Override @Override
public void mousePressed(int button, int x, int y) { public boolean mousePressed(int button, int x, int y) {
if (gameFinished) if (super.mousePressed(button, x, y)) {
return; return true;
}
if (sbOverlay.mousePressed(button, x, y)) { if (gameFinished) {
return; return true;
} }
// watching replay // watching replay
if (isReplay || GameMod.AUTO.isActive()) { if (isReplay || GameMod.AUTO.isActive()) {
if (button == Input.MOUSE_MIDDLE_BUTTON) if (button == Input.MOUSE_MIDDLE_BUTTON) {
return; return true;
}
// skip button // skip button
if (skipButton.contains(x, y)) if (skipButton.contains(x, y))
@ -1284,11 +1279,12 @@ public class Game extends BasicGameState {
MusicController.setPosition((int) pos); MusicController.setPosition((int) pos);
isSeeking = true; isSeeking = true;
} }
return; return true;
} }
if (Options.isMouseDisabled()) if (Options.isMouseDisabled()) {
return; return true;
}
// mouse wheel: pause the game // mouse wheel: pause the game
if (button == Input.MOUSE_MIDDLE_BUTTON && !Options.isMouseWheelDisabled()) { if (button == Input.MOUSE_MIDDLE_BUTTON && !Options.isMouseWheelDisabled()) {
@ -1297,10 +1293,11 @@ public class Game extends BasicGameState {
pausedMousePosition = new Vec2f(x, y); pausedMousePosition = new Vec2f(x, y);
pausePulse = 0f; pausePulse = 0f;
} }
if (MusicController.isPlaying() || isLeadIn()) if (MusicController.isPlaying() || isLeadIn()) {
pauseTime = trackPosition; pauseTime = trackPosition;
game.enterState(Opsu.STATE_GAMEPAUSEMENU, new EmptyTransition(), new FadeInTransition()); }
return; // TODO d displayContainer.switchStateNow(GamePauseMenu.class);
return true;
} }
// game keys // game keys
@ -1311,6 +1308,8 @@ public class Game extends BasicGameState {
keys = ReplayFrame.KEY_M2; keys = ReplayFrame.KEY_M2;
if (keys != ReplayFrame.KEY_NONE) if (keys != ReplayFrame.KEY_NONE)
gameKeyPressed(keys, x, y, MusicController.getPosition()); gameKeyPressed(keys, x, y, MusicController.getPosition());
return true;
} }
/** /**
@ -1353,19 +1352,22 @@ public class Game extends BasicGameState {
} }
@Override @Override
public void mouseReleased(int button, int x, int y) { public boolean mouseReleased(int button, int x, int y) {
if (gameFinished) if (super.mouseReleased(button, x, y)) {
return; return true;
if (sbOverlay.mouseReleased(button, x, y)) {
return;
} }
if (Options.isMouseDisabled()) if (gameFinished) {
return; return true;
}
if (button == Input.MOUSE_MIDDLE_BUTTON) if (Options.isMouseDisabled()) {
return; return true;
}
if (button == Input.MOUSE_MIDDLE_BUTTON) {
return true;
}
int keys = ReplayFrame.KEY_NONE; int keys = ReplayFrame.KEY_NONE;
if (button == Input.MOUSE_LEFT_BUTTON) if (button == Input.MOUSE_LEFT_BUTTON)
@ -1374,12 +1376,19 @@ public class Game extends BasicGameState {
keys = ReplayFrame.KEY_M2; keys = ReplayFrame.KEY_M2;
if (keys != ReplayFrame.KEY_NONE) if (keys != ReplayFrame.KEY_NONE)
gameKeyReleased(keys, x, y, MusicController.getPosition()); gameKeyReleased(keys, x, y, MusicController.getPosition());
return true;
} }
@Override @Override
public void keyReleased(int key, char c) { public boolean keyReleased(int key, char c) {
if (gameFinished) if (super.keyReleased(key, c)) {
return; return true;
}
if (gameFinished) {
return true;
}
int keys = ReplayFrame.KEY_NONE; int keys = ReplayFrame.KEY_NONE;
if (key == Options.getGameKeyLeft()) if (key == Options.getGameKeyLeft())
@ -1387,7 +1396,9 @@ public class Game extends BasicGameState {
else if (key == Options.getGameKeyRight()) else if (key == Options.getGameKeyRight())
keys = ReplayFrame.KEY_K2; keys = ReplayFrame.KEY_K2;
if (keys != ReplayFrame.KEY_NONE) if (keys != ReplayFrame.KEY_NONE)
gameKeyReleased(keys, input.getMouseX(), input.getMouseY(), MusicController.getPosition()); gameKeyReleased(keys, displayContainer.input.getMouseX(), displayContainer.input.getMouseY(), MusicController.getPosition());
return true;
} }
/** /**
@ -1405,26 +1416,41 @@ public class Game extends BasicGameState {
} }
@Override @Override
public void mouseWheelMoved(int newValue) { public boolean mouseWheelMoved(int newValue) {
if (sbOverlay.mouseWheelMoved(newValue)) { if (super.mouseWheelMoved(newValue)) {
return; return true;
}
if (Options.isMouseWheelDisabled()) {
return true;
} }
if (Options.isMouseWheelDisabled())
return;
UI.changeVolume((newValue < 0) ? -1 : 1); UI.changeVolume((newValue < 0) ? -1 : 1);
return true;
} }
@Override @Override
public void enter(GameContainer container, StateBasedGame game) public void enter() {
throws SlickException { super.enter();
overlays.clear();
if (Options.isEnableSB()) {
overlays.add(optionsOverlay);
overlays.add(moveStoryboardOverlay);
overlays.add(storyboardOverlay);
storyboardOverlay.onEnter();
optionsOverlay.revalidate();
}
isInGame = true; isInGame = true;
if (!skippedToCheckpoint) { if (!skippedToCheckpoint) {
UI.enter(); UI.enter();
} }
if (beatmap == null || beatmap.objects == null) if (beatmap == null || beatmap.objects == null) {
throw new RuntimeException("Running game with no beatmap loaded."); displayContainer.eventBus.post(new BubbleNotificationEvent("Game was running without a beatmap", BubbleNotificationEvent.COMMONCOLOR_RED));
displayContainer.switchStateInstantly(SongMenu.class);
}
Dancer.instance.reset(); Dancer.instance.reset();
MoverDirection.reset(beatmap.beatmapID); MoverDirection.reset(beatmap.beatmapID);
@ -1451,10 +1477,10 @@ public class Game extends BasicGameState {
epiImgTime = Options.getEpilepsyWarningLength(); epiImgTime = Options.getEpilepsyWarningLength();
if (epiImgTime > 0) { if (epiImgTime > 0) {
epiImg = GameImage.EPILEPSY_WARNING.getImage(); epiImg = GameImage.EPILEPSY_WARNING.getImage();
float desWidth = container.getWidth() / 2; float desWidth = displayContainer.width / 2;
epiImg = epiImg.getScaledCopy(desWidth / epiImg.getWidth()); epiImg = epiImg.getScaledCopy(desWidth / epiImg.getWidth());
epiImgX = (container.getWidth() - epiImg.getWidth()) / 2; epiImgX = (displayContainer.width - epiImg.getWidth()) / 2;
epiImgY = (container.getHeight() - epiImg.getHeight()) / 2; epiImgY = (displayContainer.height - epiImg.getHeight()) / 2;
} }
// load mods // load mods
@ -1522,9 +1548,9 @@ public class Game extends BasicGameState {
else if (hitObject.isSpinner()) else if (hitObject.isSpinner())
gameObjects[i] = new Spinner(hitObject, this, data); gameObjects[i] = new Spinner(hitObject, this, data);
} catch (Exception e) { } catch (Exception e) {
// try to handle the error gracefully: substitute in a dummy GameObject String message = String.format("Failed to create %s at index %d:\n%s", hitObject.getTypeName(), i, hitObject.toString());
ErrorHandler.error(String.format("Failed to create %s at index %d:\n%s", Log.error(message, e);
hitObject.getTypeName(), i, hitObject.toString()), e, true); displayContainer.eventBus.post(new BubbleNotificationEvent(message, BubbleNotificationEvent.COMMONCOLOR_RED));
gameObjects[i] = new DummyObject(hitObject); gameObjects[i] = new DummyObject(hitObject);
} }
} }
@ -1550,8 +1576,8 @@ public class Game extends BasicGameState {
// load replay frames // load replay frames
if (isReplay) { if (isReplay) {
// load initial data // load initial data
replayX = container.getWidth() / 2; replayX = displayContainer.width / 2;
replayY = container.getHeight() / 2; replayY = displayContainer.height / 2;
replayKeyPressed = false; replayKeyPressed = false;
replaySkipTime = -1; replaySkipTime = -1;
for (replayIndex = 0; replayIndex < replay.frames.length; replayIndex++) { for (replayIndex = 0; replayIndex < replay.frames.length; replayIndex++) {
@ -1572,8 +1598,8 @@ public class Game extends BasicGameState {
else { else {
lastKeysPressed = ReplayFrame.KEY_NONE; lastKeysPressed = ReplayFrame.KEY_NONE;
replaySkipTime = -1; replaySkipTime = -1;
replayFrames = new LinkedList<ReplayFrame>(); replayFrames = new LinkedList<>();
replayFrames.add(new ReplayFrame(0, 0, input.getMouseX(), input.getMouseY(), 0)); replayFrames.add(new ReplayFrame(0, 0, displayContainer.mouseX, displayContainer.mouseY, 0));
} }
for (int i = 0; i < gameObjects.length; i++) { for (int i = 0; i < gameObjects.length; i++) {
@ -1635,10 +1661,10 @@ public class Game extends BasicGameState {
slidercurveTo = 0; slidercurveTo = 0;
Dancer.instance.setGameObjects(gameObjects); Dancer.instance.setGameObjects(gameObjects);
sbOverlay.setGameObjects(gameObjects); storyboardOverlay.setGameObjects(gameObjects);
if (!skippedToCheckpoint) { if (!skippedToCheckpoint) {
sbOverlay.enter(); storyboardOverlay.onEnter();
sbOverlay.updateIndex(0); storyboardOverlay.updateIndex(0);
} }
Pippi.reset(); Pippi.reset();
@ -1652,15 +1678,23 @@ public class Game extends BasicGameState {
} }
@Override @Override
public void leave(GameContainer container, StateBasedGame game) public void leave() {
throws SlickException { super.leave();
MusicController.pause();
MusicController.setPitch(1f);
MusicController.resume();
if (Options.isEnableSB()) {
storyboardOverlay.onLeave();
}
isInGame = false; isInGame = false;
// container.setMouseGrabbed(false); // container.setMouseGrabbed(false);
skippedToCheckpoint = false; skippedToCheckpoint = false;
knorkesliders = null; knorkesliders = null;
sbOverlay.leave();
Dancer.instance.setGameObjects(null); Dancer.instance.setGameObjects(null);
Cursor.lastObjColor = Color.white; Cursor.lastObjColor = Color.white;
@ -1726,7 +1760,7 @@ public class Game extends BasicGameState {
trackPosition = failTrackTime + (int) (System.currentTimeMillis() - failTime); trackPosition = failTrackTime + (int) (System.currentTimeMillis() - failTime);
// get hit objects in reverse order, or else overlapping objects are unreadable // get hit objects in reverse order, or else overlapping objects are unreadable
Stack<Integer> stack = new Stack<Integer>(); Stack<Integer> stack = new Stack<>();
for (int index = objectIndex; index < gameObjects.length && beatmap.objects[index].getTime() < trackPosition + approachTime; index++) { for (int index = objectIndex; index < gameObjects.length && beatmap.objects[index].getTime() < trackPosition + approachTime; index++) {
stack.add(index); stack.add(index);
@ -1739,7 +1773,7 @@ public class Game extends BasicGameState {
} }
if (lastObjectIndex != -1 && !beatmap.objects[index].isNewCombo()) { if (lastObjectIndex != -1 && !beatmap.objects[index].isNewCombo()) {
// calculate points // calculate points
final int followPointInterval = container.getHeight() / 14; final int followPointInterval = displayContainer.height / 14;
int lastObjectEndTime = gameObjects[lastObjectIndex].getEndTime() + 1; int lastObjectEndTime = gameObjects[lastObjectIndex].getEndTime() + 1;
int objectStartTime = beatmap.objects[index].getTime(); int objectStartTime = beatmap.objects[index].getTime();
Vec2f startPoint = gameObjects[lastObjectIndex].getPointAt(lastObjectEndTime); Vec2f startPoint = gameObjects[lastObjectIndex].getPointAt(lastObjectEndTime);
@ -1828,7 +1862,7 @@ public class Game extends BasicGameState {
g.pushTransform(); g.pushTransform();
// translate and rotate the object // translate and rotate the object
g.translate(0, dt * dt * container.getHeight()); g.translate(0, dt * dt * displayContainer.height);
Vec2f rotationCenter = gameObj.getPointAt((beatmap.objects[idx].getTime() + beatmap.objects[idx].getEndTime()) / 2); Vec2f rotationCenter = gameObj.getPointAt((beatmap.objects[idx].getTime() + beatmap.objects[idx].getEndTime()) / 2);
g.rotate(rotationCenter.x, rotationCenter.y, rotSpeed * dt); g.rotate(rotationCenter.x, rotationCenter.y, rotSpeed * dt);
gameObj.draw(g, trackPosition, false); gameObj.draw(g, trackPosition, false);
@ -1847,7 +1881,7 @@ public class Game extends BasicGameState {
currentMapMusicOffset = 0; currentMapMusicOffset = 0;
} }
this.beatmap = beatmap; this.beatmap = beatmap;
Display.setTitle(String.format("%s - %s", game.getTitle(), beatmap.toString())); Display.setTitle(String.format("opsu!dance - %s", beatmap.toString()));
if (beatmap.breaks == null) if (beatmap.breaks == null)
BeatmapDB.load(beatmap, BeatmapDB.LOAD_ARRAY); BeatmapDB.load(beatmap, BeatmapDB.LOAD_ARRAY);
BeatmapParser.parseHitObjects(beatmap); BeatmapParser.parseHitObjects(beatmap);
@ -1879,7 +1913,7 @@ public class Game extends BasicGameState {
lastReplayTime = 0; lastReplayTime = 0;
autoMousePosition = new Vec2f(); autoMousePosition = new Vec2f();
autoMousePressed = false; autoMousePressed = false;
flashlightRadius = container.getHeight() * 2 / 3; flashlightRadius = displayContainer.height * 2 / 3;
scoreboardStarStream.clear(); scoreboardStarStream.clear();
gameFinished = false; gameFinished = false;
gameFinishedTimer.setTime(0); gameFinishedTimer.setTime(0);
@ -1917,9 +1951,6 @@ public class Game extends BasicGameState {
* Loads all game images. * Loads all game images.
*/ */
private void loadImages() { private void loadImages() {
int width = container.getWidth();
int height = container.getHeight();
// set images // set images
File parent = beatmap.getFile().getParentFile(); File parent = beatmap.getFile().getParentFile();
for (GameImage img : GameImage.values()) { for (GameImage img : GameImage.values()) {
@ -1932,17 +1963,17 @@ public class Game extends BasicGameState {
// skip button // skip button
if (GameImage.SKIP.getImages() != null) { if (GameImage.SKIP.getImages() != null) {
Animation skip = GameImage.SKIP.getAnimation(120); Animation skip = GameImage.SKIP.getAnimation(120);
skipButton = new MenuButton(skip, width - skip.getWidth() / 2f, height - (skip.getHeight() / 2f)); skipButton = new MenuButton(skip, displayContainer.width - skip.getWidth() / 2f, displayContainer.height - (skip.getHeight() / 2f));
} else { } else {
Image skip = GameImage.SKIP.getImage(); Image skip = GameImage.SKIP.getImage();
skipButton = new MenuButton(skip, width - skip.getWidth() / 2f, height - (skip.getHeight() / 2f)); skipButton = new MenuButton(skip, displayContainer.width - skip.getWidth() / 2f, displayContainer.height - (skip.getHeight() / 2f));
} }
skipButton.setHoverAnimationDuration(350); skipButton.setHoverAnimationDuration(350);
skipButton.setHoverAnimationEquation(AnimationEquation.IN_OUT_BACK); skipButton.setHoverAnimationEquation(AnimationEquation.IN_OUT_BACK);
skipButton.setHoverExpand(1.1f, MenuButton.Expand.UP_LEFT); skipButton.setHoverExpand(1.1f, MenuButton.Expand.UP_LEFT);
// load other images... // load other images...
((GamePauseMenu) game.getState(Opsu.STATE_GAMEPAUSEMENU)).loadImages(); // TODO d instanceContainer.provide(GamePauseMenu.class).loadImages();
data.loadImages(); data.loadImages();
} }
@ -1974,10 +2005,10 @@ public class Game extends BasicGameState {
HitObject.setStackOffset(diameter * STACK_OFFSET_MODIFIER); HitObject.setStackOffset(diameter * STACK_OFFSET_MODIFIER);
// initialize objects // initialize objects
Circle.init(container, diameter); Circle.init(diameter);
Slider.init(container, diameter, beatmap); Slider.init(displayContainer, diameter, beatmap);
Spinner.init(container, overallDifficulty); Spinner.init(displayContainer, overallDifficulty);
Curve.init(container.getWidth(), container.getHeight(), diameter, (Options.isBeatmapSkinIgnored()) ? Curve.init(displayContainer.width, displayContainer.height, diameter, (Options.isBeatmapSkinIgnored()) ?
Options.getSkin().getSliderBorderColor() : beatmap.getSliderBorderColor()); Options.getSkin().getSliderBorderColor() : beatmap.getSliderBorderColor());
// approachRate (hit object approach time) // approachRate (hit object approach time)
@ -2096,7 +2127,7 @@ public class Game extends BasicGameState {
this.replay = null; this.replay = null;
} else { } else {
if (replay.frames == null) { if (replay.frames == null) {
ErrorHandler.error("Attempting to set a replay with no frames.", null, false); displayContainer.eventBus.post(new BubbleNotificationEvent("Attempting to set a replay with no frames.", BubbleNotificationEvent.COLOR_ORANGE));
return; return;
} }
this.isReplay = true; this.isReplay = true;
@ -2191,30 +2222,29 @@ public class Game extends BasicGameState {
if (!GameMod.FLASHLIGHT.isActive()) if (!GameMod.FLASHLIGHT.isActive())
return; return;
int width = container.getWidth(), height = container.getHeight();
boolean firstObject = (objectIndex == 0 && trackPosition < beatmap.objects[0].getTime()); boolean firstObject = (objectIndex == 0 && trackPosition < beatmap.objects[0].getTime());
if (isLeadIn()) { if (isLeadIn()) {
// lead-in: expand area // lead-in: expand area
float progress = Math.max((float) (leadInTime - beatmap.audioLeadIn) / approachTime, 0f); float progress = Math.max((float) (leadInTime - beatmap.audioLeadIn) / approachTime, 0f);
flashlightRadius = width - (int) ((width - (height * 2 / 3)) * progress); flashlightRadius = displayContainer.width - (int) ((displayContainer.width - (displayContainer.height * 2 / 3)) * progress);
} else if (firstObject) { } else if (firstObject) {
// before first object: shrink area // before first object: shrink area
int timeDiff = beatmap.objects[0].getTime() - trackPosition; int timeDiff = beatmap.objects[0].getTime() - trackPosition;
flashlightRadius = width; flashlightRadius = displayContainer.width;
if (timeDiff < approachTime) { if (timeDiff < approachTime) {
float progress = (float) timeDiff / approachTime; float progress = (float) timeDiff / approachTime;
flashlightRadius -= (width - (height * 2 / 3)) * (1 - progress); flashlightRadius -= (displayContainer.width - (displayContainer.height * 2 / 3)) * (1 - progress);
} }
} else { } else {
// gameplay: size based on combo // gameplay: size based on combo
int targetRadius; int targetRadius;
int combo = data.getComboStreak(); int combo = data.getComboStreak();
if (combo < 100) if (combo < 100)
targetRadius = height * 2 / 3; targetRadius = displayContainer.height * 2 / 3;
else if (combo < 200) else if (combo < 200)
targetRadius = height / 2; targetRadius = displayContainer.height / 2;
else else
targetRadius = height / 3; targetRadius = displayContainer.height / 3;
if (beatmap.breaks != null && breakIndex < beatmap.breaks.size() && breakTime > 0) { if (beatmap.breaks != null && breakIndex < beatmap.breaks.size() && breakTime > 0) {
// breaks: expand at beginning, shrink at end // breaks: expand at beginning, shrink at end
flashlightRadius = targetRadius; flashlightRadius = targetRadius;
@ -2226,11 +2256,11 @@ public class Game extends BasicGameState {
progress = (float) (trackPosition - breakTime) / approachTime; progress = (float) (trackPosition - breakTime) / approachTime;
else if (endTime - trackPosition < approachTime) else if (endTime - trackPosition < approachTime)
progress = (float) (endTime - trackPosition) / approachTime; progress = (float) (endTime - trackPosition) / approachTime;
flashlightRadius += (width - flashlightRadius) * progress; flashlightRadius += (displayContainer.width - flashlightRadius) * progress;
} }
} else if (flashlightRadius != targetRadius) { } else if (flashlightRadius != targetRadius) {
// radius size change // radius size change
float radiusDiff = height * delta / 2000f; float radiusDiff = displayContainer.height * delta / 2000f;
if (flashlightRadius > targetRadius) { if (flashlightRadius > targetRadius) {
flashlightRadius -= radiusDiff; flashlightRadius -= radiusDiff;
if (flashlightRadius < targetRadius) if (flashlightRadius < targetRadius)

View File

@ -133,4 +133,63 @@ public class OptionsMenu {
}) })
}; };
public static final OptionTab[] storyboardOptions = new OptionsOverlay.OptionTab[]{
new OptionTab("Gameplay", new GameOption[] {
GameOption.BACKGROUND_DIM,
GameOption.DANCE_REMOVE_BG,
GameOption.SNAKING_SLIDERS,
GameOption.SHRINKING_SLIDERS,
GameOption.SHOW_HIT_LIGHTING,
GameOption.SHOW_HIT_ANIMATIONS,
GameOption.SHOW_COMBO_BURSTS,
GameOption.SHOW_PERFECT_HIT,
GameOption.SHOW_FOLLOW_POINTS,
}),
new OptionTab("Input", new GameOption[] {
GameOption.CURSOR_SIZE,
GameOption.NEW_CURSOR,
GameOption.DISABLE_CURSOR
}),
new OptionTab("Dance", new GameOption[] {
GameOption.DANCE_MOVER,
GameOption.DANCE_EXGON_DELAY,
GameOption.DANCE_QUAD_BEZ_AGGRESSIVENESS,
GameOption.DANCE_QUAD_BEZ_SLIDER_AGGRESSIVENESS_FACTOR,
GameOption.DANCE_QUAD_BEZ_USE_CUBIC_ON_SLIDERS,
GameOption.DANCE_QUAD_BEZ_CUBIC_AGGRESSIVENESS_FACTOR,
GameOption.DANCE_MOVER_DIRECTION,
GameOption.DANCE_SLIDER_MOVER_TYPE,
GameOption.DANCE_SPINNER,
GameOption.DANCE_SPINNER_DELAY,
GameOption.DANCE_LAZY_SLIDERS,
GameOption.DANCE_CIRCLE_STREAMS,
GameOption.DANCE_ONLY_CIRCLE_STACKS,
GameOption.DANCE_CIRLCE_IN_SLOW_SLIDERS,
GameOption.DANCE_CIRLCE_IN_LAZY_SLIDERS,
GameOption.DANCE_MIRROR,
}),
new OptionTab("Dance display", new GameOption[] {
GameOption.DANCE_DRAW_APPROACH,
GameOption.DANCE_OBJECT_COLOR_OVERRIDE,
GameOption.DANCE_OBJECT_COLOR_OVERRIDE_MIRRORED,
GameOption.DANCE_RGB_OBJECT_INC,
GameOption.DANCE_CURSOR_COLOR_OVERRIDE,
GameOption.DANCE_CURSOR_MIRROR_COLOR_OVERRIDE,
GameOption.DANCE_CURSOR_ONLY_COLOR_TRAIL,
GameOption.DANCE_RGB_CURSOR_INC,
GameOption.DANCE_CURSOR_TRAIL_OVERRIDE,
GameOption.DANCE_HIDE_OBJECTS,
GameOption.DANCE_HIDE_UI,
GameOption.DANCE_HIDE_WATERMARK,
}),
new OptionTab ("Pippi", new GameOption[] {
GameOption.PIPPI_ENABLE,
GameOption.PIPPI_RADIUS_PERCENT,
GameOption.PIPPI_ANGLE_INC_MUL,
GameOption.PIPPI_ANGLE_INC_MUL_SLIDER,
GameOption.PIPPI_SLIDER_FOLLOW_EXPAND,
GameOption.PIPPI_PREVENT_WOBBLY_STREAMS,
})
};
} }

View File

@ -326,7 +326,7 @@ public class SongMenu extends ComplexOpsuState {
public SongMenu(final DisplayContainer displayContainer, InstanceContainer instanceContainer) { public SongMenu(final DisplayContainer displayContainer, InstanceContainer instanceContainer) {
super(displayContainer); super(displayContainer);
this.instanceContainer = instanceContainer; this.instanceContainer = instanceContainer;
optionsOverlay = new OptionsOverlay(this, displayContainer, OptionsMenu.normalOptions, 0); optionsOverlay = new OptionsOverlay(displayContainer, OptionsMenu.normalOptions, 0);
overlays.add(optionsOverlay); overlays.add(optionsOverlay);
} }
@ -1794,6 +1794,6 @@ public class SongMenu extends ComplexOpsuState {
gameState.loadBeatmap(beatmap); gameState.loadBeatmap(beatmap);
gameState.setRestart(Game.Restart.NEW); gameState.setRestart(Game.Restart.NEW);
gameState.setReplay(null); gameState.setReplay(null);
// TODO d displayContainer.switchState(Game.class); displayContainer.switchState(Game.class);
} }
} }

View File

@ -334,7 +334,13 @@ public class DisplayContainer implements ErrorDumpable, KeyListener, MouseListen
} }
public void switchStateNow(Class<? extends OpsuState> newState) { public void switchStateNow(Class<? extends OpsuState> newState) {
switchState(newState, EmptyTransitionState.class, 0, EmptyTransitionState.class, 0); switchState(newState, EmptyTransitionState.class, 0, FadeInTransitionState.class, 300);
}
public void switchStateInstantly(Class<? extends OpsuState> newState) {
state.leave();
state = instanceContainer.provide(newState);
state.enter();
} }
public void switchState(Class<? extends OpsuState> newState, Class<? extends TransitionState> outTransition, int outTime, Class<? extends TransitionState> inTransition, int inTime) { public void switchState(Class<? extends OpsuState> newState, Class<? extends TransitionState> outTransition, int outTime, Class<? extends TransitionState> inTransition, int inTime) {

View File

@ -57,6 +57,8 @@ public class OpsuDanceInjector extends Injector {
bind(ButtonMenu.class).asEagerSingleton(); bind(ButtonMenu.class).asEagerSingleton();
bind(SongMenu.class).asEagerSingleton(); bind(SongMenu.class).asEagerSingleton();
bind(DownloadsMenu.class).asEagerSingleton(); bind(DownloadsMenu.class).asEagerSingleton();
bind(GameRanking.class).asEagerSingleton();
bind(Game.class).asEagerSingleton();
} }
} }

View File

@ -26,8 +26,13 @@ public abstract class OverlayOpsuState implements OpsuState {
protected boolean active; protected boolean active;
protected boolean acceptInput; protected boolean acceptInput;
public abstract void hide(); public void hide() {
public abstract void show(); acceptInput = active = false;
}
public void show() {
acceptInput = active = true;
}
@Override @Override
public final void update() { public final void update() {

View File

@ -25,6 +25,8 @@ import itdelatrisu.opsu.ui.animations.AnimationEquation;
import org.newdawn.slick.Color; import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer; import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics; import org.newdawn.slick.Graphics;
import yugecin.opsudance.core.DisplayContainer;
import yugecin.opsudance.core.state.OverlayOpsuState;
import yugecin.opsudance.sbv2.movers.CubicStoryboardMover; import yugecin.opsudance.sbv2.movers.CubicStoryboardMover;
import yugecin.opsudance.sbv2.movers.LinearStoryboardMover; import yugecin.opsudance.sbv2.movers.LinearStoryboardMover;
import yugecin.opsudance.sbv2.movers.QuadraticStoryboardMover; import yugecin.opsudance.sbv2.movers.QuadraticStoryboardMover;
@ -34,20 +36,20 @@ import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
public class MoveStoryboard { public class MoveStoryboard extends OverlayOpsuState{
private final SimpleButton btnAddLinear; private final DisplayContainer displayContainer;
private final SimpleButton btnAddQuadratic;
private final SimpleButton btnAddCubic;
private final SimpleButton btnAnimLin; private SimpleButton btnAddLinear;
private final SimpleButton btnAnimMid; private SimpleButton btnAddQuadratic;
private final SimpleButton btnAnimCub; private SimpleButton btnAddCubic;
private SimpleButton btnAnimLin;
private SimpleButton btnAnimMid;
private SimpleButton btnAnimCub;
private final StoryboardMove dummyMove; private final StoryboardMove dummyMove;
private int width;
private StoryboardMove[] moves; private StoryboardMove[] moves;
private GameObject[] gameObjects; private GameObject[] gameObjects;
@ -55,14 +57,8 @@ public class MoveStoryboard {
private int trackPosition; private int trackPosition;
public MoveStoryboard(GameContainer container) { public MoveStoryboard(DisplayContainer displayContainer) {
this.width = container.getWidth(); this.displayContainer = displayContainer;
btnAddLinear = new SimpleButton(width - 205, 50, 200, 25, Fonts.SMALL, "add linear", Colors.BLUE_BUTTON, Colors.WHITE_FADE, Colors.WHITE_FADE, Colors.ORANGE_BUTTON);
btnAddQuadratic = new SimpleButton(width - 205, 80, 200, 25, Fonts.SMALL, "add quadratic", Colors.BLUE_BUTTON, Colors.WHITE_FADE, Colors.WHITE_FADE, Colors.ORANGE_BUTTON);
btnAddCubic = new SimpleButton(width - 205, 110, 200, 25, Fonts.SMALL, "add cubic", Colors.BLUE_BUTTON, Colors.WHITE_FADE, Colors.WHITE_FADE, Colors.ORANGE_BUTTON);
btnAnimLin = new SimpleButton(width - 250, 50, 40, 25, Fonts.SMALL, "lin", Color.blue, Color.white, Color.white, Color.orange);
btnAnimMid = new SimpleButton(width - 250, 80, 40, 25, Fonts.SMALL, "mid", Color.blue, Color.white, Color.white, Color.orange);
btnAnimCub = new SimpleButton(width - 250, 110, 40, 25, Fonts.SMALL, "cub", Color.blue, Color.white, Color.white, Color.orange);
dummyMove = (StoryboardMove) Proxy.newProxyInstance(StoryboardMove.class.getClassLoader(), new Class<?>[]{StoryboardMove.class}, new InvocationHandler() { dummyMove = (StoryboardMove) Proxy.newProxyInstance(StoryboardMove.class.getClassLoader(), new Class<?>[]{StoryboardMove.class}, new InvocationHandler() {
@Override @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
@ -71,6 +67,16 @@ public class MoveStoryboard {
}); });
} }
@Override
public void revalidate() {
btnAddLinear = new SimpleButton(displayContainer.width - 205, 50, 200, 25, Fonts.SMALL, "add linear", Colors.BLUE_BUTTON, Colors.WHITE_FADE, Colors.WHITE_FADE, Colors.ORANGE_BUTTON);
btnAddQuadratic = new SimpleButton(displayContainer.width - 205, 80, 200, 25, Fonts.SMALL, "add quadratic", Colors.BLUE_BUTTON, Colors.WHITE_FADE, Colors.WHITE_FADE, Colors.ORANGE_BUTTON);
btnAddCubic = new SimpleButton(displayContainer.width - 205, 110, 200, 25, Fonts.SMALL, "add cubic", Colors.BLUE_BUTTON, Colors.WHITE_FADE, Colors.WHITE_FADE, Colors.ORANGE_BUTTON);
btnAnimLin = new SimpleButton(displayContainer.width - 250, 50, 40, 25, Fonts.SMALL, "lin", Color.blue, Color.white, Color.white, Color.orange);
btnAnimMid = new SimpleButton(displayContainer.width - 250, 80, 40, 25, Fonts.SMALL, "mid", Color.blue, Color.white, Color.white, Color.orange);
btnAnimCub = new SimpleButton(displayContainer.width - 250, 110, 40, 25, Fonts.SMALL, "cub", Color.blue, Color.white, Color.white, Color.orange);
}
/** /**
* Get the point at the current time * Get the point at the current time
* @param trackPosition current time in ms * @param trackPosition current time in ms
@ -88,7 +94,33 @@ public class MoveStoryboard {
return moves[objectIndex].getPointAt(t); return moves[objectIndex].getPointAt(t);
} }
public void render(Graphics g) { @Override
public void hide() {
}
@Override
public void show() {
}
@Override
protected void onPreRenderUpdate() {
int x = displayContainer.mouseX;
int y = displayContainer.mouseY;
btnAddLinear.update(x, y);
btnAddQuadratic.update(x, y);
btnAddCubic.update(x, y);
btnAnimLin.update(x, y);
btnAnimMid.update(x, y);
btnAnimCub.update(x, y);
if (moves[objectIndex] != null) {
moves[objectIndex].update(displayContainer.renderDelta, x, y);
}
}
@Override
protected void onRender(Graphics g) {
btnAddLinear.render(g); btnAddLinear.render(g);
btnAddQuadratic.render(g); btnAddQuadratic.render(g);
btnAddCubic.render(g); btnAddCubic.render(g);
@ -100,13 +132,31 @@ public class MoveStoryboard {
} }
} }
public void mousePressed(int x, int y) { @Override
protected boolean onKeyPressed(int key, char c) {
return false;
}
@Override
protected boolean onKeyReleased(int key, char c) {
return false;
}
@Override
protected boolean onMouseWheelMoved(int delta) {
return false;
}
@Override
protected boolean onMousePressed(int button, int x, int y) {
if (moves[objectIndex] != null) { if (moves[objectIndex] != null) {
moves[objectIndex].mousePressed(x, y); moves[objectIndex].mousePressed(x, y);
} }
return true;
} }
public void mouseReleased(int x, int y) { @Override
protected boolean onMouseReleased(int button, int x, int y) {
if (moves[objectIndex] != null) { if (moves[objectIndex] != null) {
moves[objectIndex].mouseReleased(x, y); moves[objectIndex].mouseReleased(x, y);
if (moves[objectIndex].getAmountOfMovers() == 0) { if (moves[objectIndex].getAmountOfMovers() == 0) {
@ -114,7 +164,7 @@ public class MoveStoryboard {
} }
} }
if (objectIndex == 0) { if (objectIndex == 0) {
return; return true;
} }
if (btnAddLinear.isHovered()) { if (btnAddLinear.isHovered()) {
getCurrentMoveOrCreateNew().add(new LinearStoryboardMover()); getCurrentMoveOrCreateNew().add(new LinearStoryboardMover());
@ -134,6 +184,12 @@ public class MoveStoryboard {
if (btnAnimCub.isHovered()) { if (btnAnimCub.isHovered()) {
getCurrentMoveOrDummy().setAnimationEquation(AnimationEquation.IN_OUT_EASE_MIDDLE); getCurrentMoveOrDummy().setAnimationEquation(AnimationEquation.IN_OUT_EASE_MIDDLE);
} }
return true;
}
@Override
protected boolean onMouseDragged(int oldx, int oldy, int newx, int newy) {
return false;
} }
private StoryboardMove getCurrentMoveOrCreateNew() { private StoryboardMove getCurrentMoveOrCreateNew() {
@ -142,7 +198,7 @@ public class MoveStoryboard {
return dummyMove; return dummyMove;
} }
if (moves[objectIndex] == null) { if (moves[objectIndex] == null) {
return moves[objectIndex] = new StoryboardMoveImpl(gameObjects[objectIndex - 1].end, gameObjects[objectIndex].start, width); return moves[objectIndex] = new StoryboardMoveImpl(gameObjects[objectIndex - 1].end, gameObjects[objectIndex].start, displayContainer.width);
} }
return moves[objectIndex]; return moves[objectIndex];
} }
@ -154,18 +210,6 @@ public class MoveStoryboard {
return moves[objectIndex]; return moves[objectIndex];
} }
public void update(int delta, int x, int y) {
btnAddLinear.update(x, y);
btnAddQuadratic.update(x, y);
btnAddCubic.update(x, y);
btnAnimLin.update(x, y);
btnAnimMid.update(x, y);
btnAnimCub.update(x, y);
if (moves[objectIndex] != null) {
moves[objectIndex].update(delta, x, y);
}
}
public void setGameObjects(GameObject[] gameObjects) { public void setGameObjects(GameObject[] gameObjects) {
this.gameObjects = gameObjects; this.gameObjects = gameObjects;
this.moves = new StoryboardMove[gameObjects.length]; this.moves = new StoryboardMove[gameObjects.length];

View File

@ -35,9 +35,10 @@ import yugecin.opsudance.core.state.OverlayOpsuState;
public class OptionsOverlay extends OverlayOpsuState { public class OptionsOverlay extends OverlayOpsuState {
private final ComplexOpsuState parent;
private final DisplayContainer displayContainer; private final DisplayContainer displayContainer;
private Listener listener;
private Image sliderBallImg; private Image sliderBallImg;
private Image checkOnImg; private Image checkOnImg;
private Image checkOffImg; private Image checkOffImg;
@ -81,8 +82,7 @@ public class OptionsOverlay extends OverlayOpsuState {
private int sliderSoundDelay; private int sliderSoundDelay;
public OptionsOverlay(ComplexOpsuState parent, DisplayContainer displayContainer, OptionTab[] tabs, int defaultSelectedTabIndex) { public OptionsOverlay(DisplayContainer displayContainer, OptionTab[] tabs, int defaultSelectedTabIndex) {
this.parent = parent;
this.displayContainer = displayContainer; this.displayContainer = displayContainer;
this.tabs = tabs; this.tabs = tabs;
@ -91,6 +91,10 @@ public class OptionsOverlay extends OverlayOpsuState {
listHoverIndex = -1; listHoverIndex = -1;
} }
public void setListener(Listener listener) {
this.listener = listener;
}
@Override @Override
public void revalidate() { public void revalidate() {
super.revalidate(); super.revalidate();
@ -399,7 +403,9 @@ public class OptionsOverlay extends OverlayOpsuState {
if (isListOptionOpen) { if (isListOptionOpen) {
if (y > optionStartY && listStartX <= x && x < listStartX + listWidth && listStartY <= y && y < listStartY + listHeight) { if (y > optionStartY && listStartX <= x && x < listStartX + listWidth && listStartY <= y && y < listStartY + listHeight) {
hoverOption.clickListItem(listHoverIndex); hoverOption.clickListItem(listHoverIndex);
// TODO d parent.onSaveOption(hoverOption); if (listener != null) {
listener.onSaveOption(hoverOption);
}
SoundController.playSound(SoundEffect.MENUCLICK); SoundController.playSound(SoundEffect.MENUCLICK);
} }
isListOptionOpen = false; isListOptionOpen = false;
@ -431,8 +437,8 @@ public class OptionsOverlay extends OverlayOpsuState {
@Override @Override
public boolean onMouseReleased(int button, int x, int y) { public boolean onMouseReleased(int button, int x, int y) {
selectedOption = null; selectedOption = null;
if (isAdjustingSlider) { if (isAdjustingSlider && listener != null) {
// TODO d parent.onSaveOption(hoverOption); listener.onSaveOption(hoverOption);
} }
isAdjustingSlider = false; isAdjustingSlider = false;
sliderOptionLength = 0; sliderOptionLength = 0;
@ -445,7 +451,9 @@ public class OptionsOverlay extends OverlayOpsuState {
if (hoverOption != null) { if (hoverOption != null) {
if (hoverOption.getType() == OptionType.BOOLEAN) { if (hoverOption.getType() == OptionType.BOOLEAN) {
hoverOption.click(); hoverOption.click();
// TODO d parent.onSaveOption(hoverOption); if (listener != null) {
listener.onSaveOption(hoverOption);
}
SoundController.playSound(SoundEffect.MENUHIT); SoundController.playSound(SoundEffect.MENUHIT);
return true; return true;
} else if (hoverOption == GameOption.KEY_LEFT) { } else if (hoverOption == GameOption.KEY_LEFT) {
@ -466,6 +474,11 @@ public class OptionsOverlay extends OverlayOpsuState {
tScrollOffset += Fonts.MEDIUM.getLineHeight() * 2; tScrollOffset += Fonts.MEDIUM.getLineHeight() * 2;
tScrollOffset += tab.options.length * optionHeight; tScrollOffset += tab.options.length * optionHeight;
} }
if (UI.getBackButton().contains(x, y) && listener != null) {
listener.onLeaveOptionsMenu();
}
return true; return true;
} }
@ -500,16 +513,19 @@ public class OptionsOverlay extends OverlayOpsuState {
return true; return true;
} }
switch (key) { if (key == Input.KEY_ESCAPE) {
case Input.KEY_ESCAPE:
if (isListOptionOpen) { if (isListOptionOpen) {
isListOptionOpen = false; isListOptionOpen = false;
listHoverIndex = -1; listHoverIndex = -1;
return true; return true;
} }
hide(); hide();
if (listener != null) {
listener.onLeaveOptionsMenu();
}
return true; return true;
} }
return false; return false;
} }
@ -570,9 +586,9 @@ public class OptionsOverlay extends OverlayOpsuState {
} }
public interface Parent { public interface Listener {
void onLeave(); void onLeaveOptionsMenu();
void onSaveOption(GameOption option); void onSaveOption(GameOption option);
} }

View File

@ -22,86 +22,27 @@ import itdelatrisu.opsu.Options.GameOption;
import itdelatrisu.opsu.audio.MusicController; import itdelatrisu.opsu.audio.MusicController;
import itdelatrisu.opsu.objects.GameObject; import itdelatrisu.opsu.objects.GameObject;
import itdelatrisu.opsu.states.Game; import itdelatrisu.opsu.states.Game;
import itdelatrisu.opsu.states.OptionsMenu;
import itdelatrisu.opsu.ui.Fonts; import itdelatrisu.opsu.ui.Fonts;
import org.newdawn.slick.Color; import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics; import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input; import org.newdawn.slick.Input;
import yugecin.opsudance.ObjectColorOverrides; import yugecin.opsudance.ObjectColorOverrides;
import yugecin.opsudance.core.DisplayContainer;
import yugecin.opsudance.core.state.OverlayOpsuState;
import yugecin.opsudance.sbv2.MoveStoryboard; import yugecin.opsudance.sbv2.MoveStoryboard;
import yugecin.opsudance.ui.OptionsOverlay.OptionTab; import yugecin.opsudance.ui.OptionsOverlay.OptionTab;
import java.util.*; import java.util.*;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public class SBOverlay implements OptionsOverlay.Parent { public class StoryboardOverlay extends OverlayOpsuState implements OptionsOverlay.Listener {
private static final OptionTab[] options = new OptionsOverlay.OptionTab[]{
new OptionTab("Gameplay", new GameOption[] {
GameOption.BACKGROUND_DIM,
GameOption.DANCE_REMOVE_BG,
GameOption.SNAKING_SLIDERS,
GameOption.SHRINKING_SLIDERS,
GameOption.SHOW_HIT_LIGHTING,
GameOption.SHOW_HIT_ANIMATIONS,
GameOption.SHOW_COMBO_BURSTS,
GameOption.SHOW_PERFECT_HIT,
GameOption.SHOW_FOLLOW_POINTS,
}),
new OptionTab("Input", new GameOption[] {
GameOption.CURSOR_SIZE,
GameOption.NEW_CURSOR,
GameOption.DISABLE_CURSOR
}),
new OptionTab("Dance", new GameOption[] {
GameOption.DANCE_MOVER,
GameOption.DANCE_EXGON_DELAY,
GameOption.DANCE_QUAD_BEZ_AGGRESSIVENESS,
GameOption.DANCE_QUAD_BEZ_SLIDER_AGGRESSIVENESS_FACTOR,
GameOption.DANCE_QUAD_BEZ_USE_CUBIC_ON_SLIDERS,
GameOption.DANCE_QUAD_BEZ_CUBIC_AGGRESSIVENESS_FACTOR,
GameOption.DANCE_MOVER_DIRECTION,
GameOption.DANCE_SLIDER_MOVER_TYPE,
GameOption.DANCE_SPINNER,
GameOption.DANCE_SPINNER_DELAY,
GameOption.DANCE_LAZY_SLIDERS,
GameOption.DANCE_CIRCLE_STREAMS,
GameOption.DANCE_ONLY_CIRCLE_STACKS,
GameOption.DANCE_CIRLCE_IN_SLOW_SLIDERS,
GameOption.DANCE_CIRLCE_IN_LAZY_SLIDERS,
GameOption.DANCE_MIRROR,
}),
new OptionTab("Dance display", new GameOption[] {
GameOption.DANCE_DRAW_APPROACH,
GameOption.DANCE_OBJECT_COLOR_OVERRIDE,
GameOption.DANCE_OBJECT_COLOR_OVERRIDE_MIRRORED,
GameOption.DANCE_RGB_OBJECT_INC,
GameOption.DANCE_CURSOR_COLOR_OVERRIDE,
GameOption.DANCE_CURSOR_MIRROR_COLOR_OVERRIDE,
GameOption.DANCE_CURSOR_ONLY_COLOR_TRAIL,
GameOption.DANCE_RGB_CURSOR_INC,
GameOption.DANCE_CURSOR_TRAIL_OVERRIDE,
GameOption.DANCE_HIDE_OBJECTS,
GameOption.DANCE_HIDE_UI,
GameOption.DANCE_HIDE_WATERMARK,
}),
new OptionTab ("Pippi", new GameOption[] {
GameOption.PIPPI_ENABLE,
GameOption.PIPPI_RADIUS_PERCENT,
GameOption.PIPPI_ANGLE_INC_MUL,
GameOption.PIPPI_ANGLE_INC_MUL_SLIDER,
GameOption.PIPPI_SLIDER_FOLLOW_EXPAND,
GameOption.PIPPI_PREVENT_WOBBLY_STREAMS,
})
};
private final static List<GameOption> optionList = new ArrayList<>(); private final static List<GameOption> optionList = new ArrayList<>();
private boolean hide; private final DisplayContainer displayContainer;
private boolean menu;
private int width; private boolean hide;
private int height;
private int speed; private int speed;
private GameObject[] gameObjects; private GameObject[] gameObjects;
@ -112,43 +53,42 @@ public class SBOverlay implements OptionsOverlay.Parent {
private final Game game; private final Game game;
private final MoveStoryboard msb; private final MoveStoryboard msb;
private OptionsOverlay overlay; private final OptionsOverlay optionsOverlay;
static { static {
for (OptionTab tab : options) { for (OptionTab tab : OptionsMenu.storyboardOptions) {
optionList.addAll(Arrays.asList(tab.options)); optionList.addAll(Arrays.asList(tab.options));
} }
} }
public SBOverlay(Game game, MoveStoryboard msb, GameContainer container) { public StoryboardOverlay(DisplayContainer displayContainer, MoveStoryboard msb, OptionsOverlay optionsOverlay, Game game) {
this.game = game; this.displayContainer = displayContainer;
this.msb = msb; this.msb = msb;
this.optionsOverlay = optionsOverlay;
this.game = game;
initialOptions = new HashMap<>(); initialOptions = new HashMap<>();
//overlay = new OptionsOverlay(this, options, 2, container);
this.width = container.getWidth();
this.height = container.getHeight();
speed = 10; speed = 10;
gameObjects = new GameObject[0]; gameObjects = new GameObject[0];
} }
public void render(GameContainer container, Graphics g) { @Override
public void onRender(Graphics g) {
if (!Options.isEnableSB() || hide) { if (!Options.isEnableSB() || hide) {
return; return;
} }
msb.render(g);
int lh = Fonts.SMALL.getLineHeight(); int lh = Fonts.SMALL.getLineHeight();
Fonts.SMALL.drawString(10, height - 50 + lh, "save position: ctrl+s, load position: ctrl+l", Color.cyan); Fonts.SMALL.drawString(10, displayContainer.height - 50 + lh, "save position: ctrl+s, load position: ctrl+l", Color.cyan);
Fonts.SMALL.drawString(10, height - 50, "speed: C " + (speed / 10f) + " V", Color.cyan); Fonts.SMALL.drawString(10, displayContainer.height - 50, "speed: C " + (speed / 10f) + " V", Color.cyan);
Fonts.SMALL.drawString(10, height - 50 - lh, "Menu: N", Color.cyan); Fonts.SMALL.drawString(10, displayContainer.height - 50 - lh, "Menu: N", Color.cyan);
Fonts.SMALL.drawString(10, height - 50 - lh * 2, "HIDE: H", Color.cyan); Fonts.SMALL.drawString(10, displayContainer.height - 50 - lh * 2, "HIDE: H", Color.cyan);
Fonts.SMALL.drawString(10, height - 50 - lh * 3, "obj: J " + index + " K", Color.cyan); Fonts.SMALL.drawString(10, displayContainer.height - 50 - lh * 3, "obj: J " + index + " K", Color.cyan);
g.setColor(Color.red); g.setColor(Color.red);
if (index < optionsMap.length && optionsMap[index] != null) { if (index < optionsMap.length && optionsMap[index] != null) {
int i = 0; int i = 0;
for (Object o : optionsMap[index].entrySet()) { for (Object o : optionsMap[index].entrySet()) {
Map.Entry<Options.GameOption, String> option = (Map.Entry<Options.GameOption, String>) o; Map.Entry<Options.GameOption, String> option = (Map.Entry<Options.GameOption, String>) o;
Fonts.SMALL.drawString(10, 50 + i * lh, option.getKey().getName(), Color.cyan); Fonts.SMALL.drawString(10, 50 + i * lh, option.getKey().getName(), Color.cyan);
Fonts.SMALL.drawString(width / 5, 50 + i * lh, option.getKey().getValueString(), Color.cyan); Fonts.SMALL.drawString(displayContainer.width / 5, 50 + i * lh, option.getKey().getValueString(), Color.cyan);
g.fillRect(0, 50 + i * lh + lh / 4, 10, 10); g.fillRect(0, 50 + i * lh + lh / 4, 10, 10);
i++; i++;
} }
@ -157,27 +97,16 @@ public class SBOverlay implements OptionsOverlay.Parent {
int start = gameObjects[0].getTime(); int start = gameObjects[0].getTime();
int end = gameObjects[gameObjects.length - 1].getEndTime(); int end = gameObjects[gameObjects.length - 1].getEndTime();
float curtime = (float) (MusicController.getPosition() - start) / (end - start); float curtime = (float) (MusicController.getPosition() - start) / (end - start);
g.fillRect(curtime * width, height - 10f, 10f, 10f); g.fillRect(curtime * displayContainer.width, displayContainer.height - 10f, 10f, 10f);
}
if (menu) {
//overlay.render(g, container.getInput().getMouseX(), container.getInput().getMouseY());
} }
} }
public void update(int delta, int mouseX, int mouseY) { @Override
if (Options.isEnableSB() && menu) { public void onPreRenderUpdate() {
//overlay.update(delta, mouseX, mouseY);
}
msb.update(delta, mouseX, mouseY);
} }
public boolean keyPressed(int key, char c) { @Override
if (!Options.isEnableSB()) { public boolean onKeyPressed(int key, char c) {
return false;
}
if (menu && overlay.keyPressed(key, c)) {
return true;
}
if (key == Input.KEY_C) { if (key == Input.KEY_C) {
if (speed > 0) { if (speed > 0) {
speed -= 1; speed -= 1;
@ -196,11 +125,9 @@ public class SBOverlay implements OptionsOverlay.Parent {
} else if (key == Input.KEY_H) { } else if (key == Input.KEY_H) {
hide = !hide; hide = !hide;
} else if (key == Input.KEY_N) { } else if (key == Input.KEY_N) {
menu = !menu; optionsOverlay.show();
if (menu && speed != 0) { if (speed != 0) {
MusicController.pause(); MusicController.pause();
} else if (!menu && speed != 0) {
MusicController.resume();
} }
} else if (key == Input.KEY_J && index > 0) { } else if (key == Input.KEY_J && index > 0) {
index--; index--;
@ -214,6 +141,11 @@ public class SBOverlay implements OptionsOverlay.Parent {
return false; return false;
} }
@Override
protected boolean onKeyReleased(int key, char c) {
return false;
}
private void goBackOneSBIndex() { private void goBackOneSBIndex() {
if (index + 1 < optionsMap.length) { if (index + 1 < optionsMap.length) {
// new options on previous index, so to revert then we have to reload them all to this point.. // new options on previous index, so to revert then we have to reload them all to this point..
@ -252,20 +184,13 @@ public class SBOverlay implements OptionsOverlay.Parent {
this.gameObjects = gameObjects; this.gameObjects = gameObjects;
} }
public boolean mousePressed(int button, int x, int y) { @Override
msb.mousePressed(x, y); public boolean onMousePressed(int button, int x, int y) {
if (!menu) {
return false;
}
overlay.mousePressed(button, x, y);
return true; return true;
} }
public boolean mouseDragged(int oldx, int oldy, int newx, int newy) { @Override
if (!menu) { public boolean onMouseDragged(int oldx, int oldy, int newx, int newy) {
return false;
}
overlay.mouseDragged(oldx, oldy, newx, newy);
return true; return true;
} }
@ -293,12 +218,8 @@ public class SBOverlay implements OptionsOverlay.Parent {
this.index--; this.index--;
} }
public boolean mouseReleased(int button, int x, int y) { @Override
if (menu) { public boolean onMouseReleased(int button, int x, int y) {
overlay.mouseReleased(button, x, y);
return true;
}
msb.mouseReleased(x, y);
if (x > 10 || index >= optionsMap.length || optionsMap[index] == null) { if (x > 10 || index >= optionsMap.length || optionsMap[index] == null) {
return false; return false;
} }
@ -318,15 +239,12 @@ public class SBOverlay implements OptionsOverlay.Parent {
return true; return true;
} }
public boolean mouseWheelMoved(int delta) { @Override
if (!menu) { public boolean onMouseWheelMoved(int delta) {
return false;
}
overlay.mouseWheelMoved(delta);
return true; return true;
} }
public void enter() { public void onEnter() {
// enter, save current settings // enter, save current settings
for (Options.GameOption o : optionList) { for (Options.GameOption o : optionList) {
initialOptions.put(o, o.write()); initialOptions.put(o, o.write());
@ -334,7 +252,7 @@ public class SBOverlay implements OptionsOverlay.Parent {
speed = 10; speed = 10;
} }
public void leave() { public void onLeave() {
// leave, revert the settings saved before entering // leave, revert the settings saved before entering
for (Options.GameOption o : optionList) { for (Options.GameOption o : optionList) {
if (initialOptions.containsKey(o)) { if (initialOptions.containsKey(o)) {
@ -358,13 +276,8 @@ public class SBOverlay implements OptionsOverlay.Parent {
} }
} }
public float[] getPoint(int trackPosition) {
return msb.getPoint(trackPosition);
}
@Override @Override
public void onLeave() { public void onLeaveOptionsMenu() {
menu = false;
if (speed != 0) { if (speed != 0) {
MusicController.resume(); MusicController.resume();
} }