Implemented dynamic main menu backgrounds.

- This can be switched off in the configuration file.
- Credits: https://osu.ppy.sh/forum/t/98954

Other changes:
- Removed OsuFile setters/getters from Game state, replaced with a 'getOsuFile()' method in MusicController (a more logical location).

Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
Jeffrey Han 2014-07-02 03:02:11 -04:00
parent bcd0c23961
commit 56123363b3
9 changed files with 65 additions and 24 deletions

View File

@ -18,7 +18,6 @@
package itdelatrisu.opsu; package itdelatrisu.opsu;
import itdelatrisu.opsu.states.Game;
import itdelatrisu.opsu.states.Options; import itdelatrisu.opsu.states.Options;
import java.util.HashMap; import java.util.HashMap;
@ -449,7 +448,7 @@ public class GameScore {
float circleDiameter = getScoreSymbolImage('0').getHeight() * 0.75f; float circleDiameter = getScoreSymbolImage('0').getHeight() * 0.75f;
g.drawOval(circleX, circleY, circleDiameter, circleDiameter); g.drawOval(circleX, circleY, circleDiameter, circleDiameter);
int firstObjectTime = Game.getOsuFile().objects[0].time; int firstObjectTime = MusicController.getOsuFile().objects[0].time;
int trackPosition = MusicController.getPosition(); int trackPosition = MusicController.getPosition();
if (trackPosition > firstObjectTime) { if (trackPosition > firstObjectTime) {
g.fillArc(circleX, circleY, circleDiameter, circleDiameter, g.fillArc(circleX, circleY, circleDiameter, circleDiameter,

View File

@ -162,6 +162,11 @@ public class MusicController {
return (player != null); return (player != null);
} }
/**
* Returns the OsuFile associated with the current track.
*/
public static OsuFile getOsuFile() { return lastOsu; }
/** /**
* Returns the name of the current track. * Returns the name of the current track.
*/ */

View File

@ -165,7 +165,7 @@ public class Opsu extends StateBasedGame {
if (id == STATE_GAME || id == STATE_GAMEPAUSEMENU || id == STATE_GAMERANKING) { if (id == STATE_GAME || id == STATE_GAMEPAUSEMENU || id == STATE_GAMERANKING) {
// start playing track at preview position // start playing track at preview position
MusicController.pause(); MusicController.pause();
MusicController.playAt(Game.getOsuFile().previewTime, true); MusicController.playAt(MusicController.getOsuFile().previewTime, true);
this.enterState(Opsu.STATE_SONGMENU, new FadeOutTransition(Color.black), new FadeInTransition(Color.black)); this.enterState(Opsu.STATE_SONGMENU, new FadeOutTransition(Color.black), new FadeInTransition(Color.black));
return false; return false;
} }

View File

@ -649,6 +649,9 @@ 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)
osu = MusicController.getOsuFile();
if (osu == null || osu.objects == null) if (osu == null || osu.objects == null)
throw new RuntimeException("Running game with no OsuFile loaded."); throw new RuntimeException("Running game with no OsuFile loaded.");
@ -810,12 +813,6 @@ public class Game extends BasicGameState {
public static void setRestart(byte restart) { Game.restart = restart; } public static void setRestart(byte restart) { Game.restart = restart; }
public static byte getRestart() { return Game.restart; } public static byte getRestart() { return Game.restart; }
/**
* Sets or returns the associated OsuFile.
*/
public static void setOsuFile(OsuFile osu) { Game.osu = osu; }
public static OsuFile getOsuFile() { return osu; }
/** /**
* Returns the associated GameScore object. * Returns the associated GameScore object.
*/ */

View File

@ -144,7 +144,7 @@ public class GamePauseMenu extends BasicGameState {
// '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 (Game.getRestart() == Game.RESTART_LOSE) { if (Game.getRestart() == Game.RESTART_LOSE) {
MusicController.stop(); MusicController.stop();
MusicController.playAt(Game.getOsuFile().previewTime, true); MusicController.playAt(MusicController.getOsuFile().previewTime, true);
SoundController.playSound(SoundController.SOUND_MENUBACK); SoundController.playSound(SoundController.SOUND_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
@ -174,7 +174,7 @@ public class GamePauseMenu extends BasicGameState {
unPause(Game.RESTART_MANUAL); unPause(Game.RESTART_MANUAL);
} else if (backButton.contains(x, y)) { } else if (backButton.contains(x, y)) {
MusicController.pause(); // lose state MusicController.pause(); // lose state
MusicController.playAt(Game.getOsuFile().previewTime, true); MusicController.playAt(MusicController.getOsuFile().previewTime, true);
SoundController.playSound(SoundController.SOUND_MENUBACK); SoundController.playSound(SoundController.SOUND_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));
} }

View File

@ -97,7 +97,7 @@ public class GameRanking extends BasicGameState {
int width = container.getWidth(); int width = container.getWidth();
int height = container.getHeight(); int height = container.getHeight();
OsuFile osu = Game.getOsuFile(); OsuFile osu = MusicController.getOsuFile();
// background // background
if (!osu.drawBG(width, height, 0.7f)) if (!osu.drawBG(width, height, 0.7f))
@ -147,7 +147,7 @@ public class GameRanking extends BasicGameState {
switch (key) { switch (key) {
case Input.KEY_ESCAPE: case Input.KEY_ESCAPE:
MusicController.pause(); MusicController.pause();
MusicController.playAt(Game.getOsuFile().previewTime, true); MusicController.playAt(MusicController.getOsuFile().previewTime, true);
SoundController.playSound(SoundController.SOUND_MENUBACK); SoundController.playSound(SoundController.SOUND_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));
break; break;
@ -164,7 +164,7 @@ public class GameRanking extends BasicGameState {
return; return;
if (retryButton.contains(x, y)) { if (retryButton.contains(x, y)) {
OsuFile osu = Game.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.setRestart(Game.RESTART_MANUAL); Game.setRestart(Game.RESTART_MANUAL);
SoundController.playSound(SoundController.SOUND_MENUHIT); SoundController.playSound(SoundController.SOUND_MENUHIT);
@ -174,7 +174,7 @@ public class GameRanking extends BasicGameState {
game.enterState(Opsu.STATE_MAINMENU, new FadeOutTransition(Color.black), new FadeInTransition(Color.black)); game.enterState(Opsu.STATE_MAINMENU, new FadeOutTransition(Color.black), new FadeInTransition(Color.black));
} else if (Utils.getBackButton().contains(x, y)) { } else if (Utils.getBackButton().contains(x, y)) {
MusicController.pause(); MusicController.pause();
MusicController.playAt(Game.getOsuFile().previewTime, true); MusicController.playAt(MusicController.getOsuFile().previewTime, true);
SoundController.playSound(SoundController.SOUND_MENUBACK); SoundController.playSound(SoundController.SOUND_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));
} }

View File

@ -21,6 +21,7 @@ package itdelatrisu.opsu.states;
import itdelatrisu.opsu.GUIMenuButton; import itdelatrisu.opsu.GUIMenuButton;
import itdelatrisu.opsu.MusicController; import itdelatrisu.opsu.MusicController;
import itdelatrisu.opsu.Opsu; import itdelatrisu.opsu.Opsu;
import itdelatrisu.opsu.OsuFile;
import itdelatrisu.opsu.OsuGroupNode; import itdelatrisu.opsu.OsuGroupNode;
import itdelatrisu.opsu.SoundController; import itdelatrisu.opsu.SoundController;
import itdelatrisu.opsu.Utils; import itdelatrisu.opsu.Utils;
@ -94,6 +95,11 @@ public class MainMenu extends BasicGameState {
*/ */
private Image backgroundImage; private Image backgroundImage;
/**
* Alpha level for fade-in effect for dynamic backgrounds.
*/
private float dynamicBackgroundAlpha = 0f;
// game-related variables // game-related variables
private StateBasedGame game; private StateBasedGame game;
private int state; private int state;
@ -151,14 +157,18 @@ public class MainMenu extends BasicGameState {
@Override @Override
public void render(GameContainer container, StateBasedGame game, Graphics g) public void render(GameContainer container, StateBasedGame game, Graphics g)
throws SlickException { throws SlickException {
if (backgroundImage != null) int width = container.getWidth();
int height = container.getHeight();
// draw background
OsuFile osu = MusicController.getOsuFile();
if (Options.isDynamicBackgroundEnabled() &&
osu != null && osu.drawBG(width, height, dynamicBackgroundAlpha))
;
else if (backgroundImage != null)
backgroundImage.draw(); backgroundImage.draw();
else else
g.setBackground(Utils.COLOR_BLUE_BACKGROUND); g.setBackground(Utils.COLOR_BLUE_BACKGROUND);
g.setFont(Utils.FONT_MEDIUM);
int width = container.getWidth();
int height = container.getHeight();
// draw buttons // draw buttons
if (logoTimer > 0) { if (logoTimer > 0) {
@ -182,6 +192,7 @@ public class MainMenu extends BasicGameState {
148f * MusicController.getPosition() / MusicController.getTrackLength(), 5, 4); 148f * MusicController.getPosition() / MusicController.getTrackLength(), 5, 4);
// draw text // draw text
g.setFont(Utils.FONT_MEDIUM);
int lineHeight = Utils.FONT_MEDIUM.getLineHeight(); int lineHeight = Utils.FONT_MEDIUM.getLineHeight();
g.drawString(String.format("Loaded %d songs and %d beatmaps.", g.drawString(String.format("Loaded %d songs and %d beatmaps.",
Opsu.groups.size(), Opsu.groups.getMapCount()), 25, 25); Opsu.groups.size(), Opsu.groups.getMapCount()), 25, 25);
@ -207,10 +218,18 @@ public class MainMenu extends BasicGameState {
Utils.drawFPS(); Utils.drawFPS();
Utils.drawCursor(); Utils.drawCursor();
} }
@Override @Override
public void update(GameContainer container, StateBasedGame game, int delta) public void update(GameContainer container, StateBasedGame game, int delta)
throws SlickException { throws SlickException {
// dynamic backgrounds
if (Options.isDynamicBackgroundEnabled() && dynamicBackgroundAlpha < 0.9f) {
dynamicBackgroundAlpha += delta / 1000f;
if (dynamicBackgroundAlpha > 0.9f)
dynamicBackgroundAlpha = 0.9f;
}
// buttons
if (logoClicked) { if (logoClicked) {
if (logoTimer == 0) { // shifting to left if (logoTimer == 0) { // shifting to left
if (logo.getX() > container.getWidth() / 3.3f) if (logo.getX() > container.getWidth() / 3.3f)
@ -275,10 +294,12 @@ public class MainMenu extends BasicGameState {
OsuGroupNode node = menu.setFocus(Opsu.groups.getRandomNode(), -1, true); OsuGroupNode node = menu.setFocus(Opsu.groups.getRandomNode(), -1, true);
if (node != null) if (node != null)
previous.add(node.index); previous.add(node.index);
dynamicBackgroundAlpha = 0f;
} else if (musicPrevious.contains(x, y)) { } else if (musicPrevious.contains(x, y)) {
if (!previous.isEmpty()) { if (!previous.isEmpty()) {
SongMenu menu = (SongMenu) game.getState(Opsu.STATE_SONGMENU); SongMenu menu = (SongMenu) game.getState(Opsu.STATE_SONGMENU);
menu.setFocus(Opsu.groups.getBaseNode(previous.pop()), -1, true); menu.setFocus(Opsu.groups.getBaseNode(previous.pop()), -1, true);
dynamicBackgroundAlpha = 0f;
} else } else
MusicController.setPosition(0); MusicController.setPosition(0);
} }

View File

@ -209,6 +209,11 @@ public class Options extends BasicGameState {
*/ */
private static boolean newCursor = true; private static boolean newCursor = true;
/**
* Whether or not dynamic backgrounds are enabled.
*/
private static boolean dynamicBackground = true;
/** /**
* Game option coordinate modifiers (for drawing). * Game option coordinate modifiers (for drawing).
*/ */
@ -612,6 +617,12 @@ public class Options extends BasicGameState {
*/ */
public static boolean isNewCursorEnabled() { return newCursor; } public static boolean isNewCursorEnabled() { return newCursor; }
/**
* Returns whether or not the main menu background should be the current track image.
* @return true if enabled
*/
public static boolean isDynamicBackgroundEnabled() { return dynamicBackground; }
/** /**
* Returns the current beatmap directory. * Returns the current beatmap directory.
* If invalid, this will attempt to search for the directory, * If invalid, this will attempt to search for the directory,
@ -718,14 +729,19 @@ public class Options extends BasicGameState {
case "ComboBurst": case "ComboBurst":
showComboBursts = Boolean.parseBoolean(value); showComboBursts = Boolean.parseBoolean(value);
break; break;
// custom entries
case "Port": case "Port":
i = Integer.parseInt(value); i = Integer.parseInt(value);
if (i > 0 && i <= 65535) if (i > 0 && i <= 65535)
port = i; port = i;
break; break;
case "NewCursor": // custom case "NewCursor":
newCursor = Boolean.parseBoolean(value); newCursor = Boolean.parseBoolean(value);
break; break;
case "DynamicBackground":
dynamicBackground = Boolean.parseBoolean(value);
break;
} }
} }
} catch (IOException e) { } catch (IOException e) {
@ -777,9 +793,13 @@ public class Options extends BasicGameState {
writer.newLine(); writer.newLine();
writer.write(String.format("ComboBurst = %b", showComboBursts)); writer.write(String.format("ComboBurst = %b", showComboBursts));
writer.newLine(); writer.newLine();
// custom entries
writer.write(String.format("Port = %d", port)); writer.write(String.format("Port = %d", port));
writer.newLine(); writer.newLine();
writer.write(String.format("NewCursor = %b", newCursor)); // custom writer.write(String.format("NewCursor = %b", newCursor));
writer.newLine();
writer.write(String.format("DynamicBackground = %b", dynamicBackground));
writer.newLine(); writer.newLine();
writer.close(); writer.close();
} catch (IOException e) { } catch (IOException e) {

View File

@ -602,7 +602,6 @@ 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);
SoundController.setSampleSet(osu.sampleSet); SoundController.setSampleSet(osu.sampleSet);
Game.setOsuFile(osu);
Game.setRestart(Game.RESTART_NEW); 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));
} }