Misc. bug fixes and improvements.

- Fixed Game not loading OsuFile for maps in a song group. (blame: 5612336)
- Implemented rotations for reverse arrows, and added a new one by Alic1a.
- "Auto" mod: pausing no longer requires click to unpause, and mod images are permanently drawn.
- Program now loads from Main Menu instead of Options (unnecessary complications for the sake of a transition).

Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
Jeffrey Han 2014-07-02 23:38:30 -04:00
parent 2c2f28b441
commit 03be29307f
8 changed files with 75 additions and 50 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@ -68,9 +68,9 @@ public class MusicController {
*/ */
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public static void play(final OsuFile osu, final boolean loop) { public static void play(final OsuFile osu, final boolean loop) {
if (lastOsu == null || !osu.audioFilename.equals(lastOsu.audioFilename)) { boolean play = (lastOsu == null || !osu.audioFilename.equals(lastOsu.audioFilename));
lastOsu = osu; lastOsu = osu;
if (play) {
// TODO: properly interrupt instead of using deprecated conversion.stop(); // TODO: properly interrupt instead of using deprecated conversion.stop();
// interrupt the conversion // interrupt the conversion
if (isConverting()) if (isConverting())

View File

@ -61,13 +61,13 @@ public class Opsu extends StateBasedGame {
* Game states. * Game states.
*/ */
public static final int public static final int
STATE_OPTIONS = 1, STATE_MAINMENU = 1,
STATE_MAINMENU = 2, STATE_MAINMENUEXIT = 2,
STATE_MAINMENUEXIT = 3, STATE_SONGMENU = 3,
STATE_SONGMENU = 4, STATE_GAME = 4,
STATE_GAME = 5, STATE_GAMEPAUSEMENU = 5,
STATE_GAMEPAUSEMENU = 6, STATE_GAMERANKING = 6,
STATE_GAMERANKING = 7; STATE_OPTIONS = 7;
/** /**
* Used to restrict the program to a single instance. * Used to restrict the program to a single instance.
@ -80,13 +80,13 @@ public class Opsu extends StateBasedGame {
@Override @Override
public void initStatesList(GameContainer container) throws SlickException { public void initStatesList(GameContainer container) throws SlickException {
addState(new Options(STATE_OPTIONS));
addState(new MainMenu(STATE_MAINMENU)); addState(new MainMenu(STATE_MAINMENU));
addState(new MainMenuExit(STATE_MAINMENUEXIT)); addState(new MainMenuExit(STATE_MAINMENUEXIT));
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 Options(STATE_OPTIONS));
} }
public static void main(String[] args) { public static void main(String[] args) {

View File

@ -151,12 +151,17 @@ public class Slider {
*/ */
private float[] curveX, curveY; private float[] curveX, curveY;
/**
* The angles of the first and last control points.
*/
private float startAngle, endAngle;
/** /**
* Constructor. * Constructor.
*/ */
public Bezier(float length) { public Bezier() {
this.order = hitObject.sliderX.length + 1; this.order = hitObject.sliderX.length + 1;
this.step = 5 / length; this.step = 5 / hitObject.pixelLength;
// calculate curve points for drawing // calculate curve points for drawing
int N = (int) (1 / step); int N = (int) (1 / step);
@ -168,6 +173,16 @@ public class Slider {
curveX[i] = c[0]; curveX[i] = c[0];
curveY[i] = c[1]; curveY[i] = c[1];
} }
// calculate angles (if needed)
if (hitObject.repeat > 1) {
float[] c1 = pointAt(0f);
float[] c2 = pointAt(0.01f);
startAngle = (float) (Math.atan2(c2[1] - c1[1], c2[0] - c1[0]) * 180 / Math.PI);
c1 = pointAt(1f);
c2 = pointAt(0.99f);
endAngle = (float) (Math.atan2(c2[1] - c1[1], c2[0] - c1[0]) * 180 / Math.PI);
}
} }
/** /**
@ -176,21 +191,31 @@ public class Slider {
private float getX(int i) { private float getX(int i) {
return (i == 0) ? hitObject.x : hitObject.sliderX[i - 1]; return (i == 0) ? hitObject.x : hitObject.sliderX[i - 1];
} }
/** /**
* Returns the y coordinate of the control point at index i. * Returns the y coordinate of the control point at index i.
*/ */
private float getY(int i) { private float getY(int i) {
return (i == 0) ? hitObject.y : hitObject.sliderY[i - 1]; return (i == 0) ? hitObject.y : hitObject.sliderY[i - 1];
} }
/**
* Returns the angle of the first control point.
*/
private float getStartAngle() { return startAngle; }
/**
* Returns the angle of the last control point.
*/
private float getEndAngle() { return endAngle; }
/** /**
* Calculates the factorial of a number. * Calculates the factorial of a number.
*/ */
private long factorial(int n) { private long factorial(int n) {
return (n <= 1 || n > 20) ? 1 : n * factorial(n - 1); return (n <= 1 || n > 20) ? 1 : n * factorial(n - 1);
} }
/** /**
* Calculates the Bernstein polynomial. * Calculates the Bernstein polynomial.
* @param i the index * @param i the index
@ -201,7 +226,7 @@ public class Slider {
return factorial(n) / (factorial(i) * factorial(n-i)) * return factorial(n) / (factorial(i) * factorial(n-i)) *
Math.pow(t, i) * Math.pow(1-t, n-i); Math.pow(t, i) * Math.pow(1-t, n-i);
} }
/** /**
* Returns the point on the Bezier curve at a value t. * Returns the point on the Bezier curve at a value t.
* For curves of order greater than 4, points will be generated along * For curves of order greater than 4, points will be generated along
@ -284,7 +309,7 @@ public class Slider {
this.color = color; this.color = color;
this.comboEnd = comboEnd; this.comboEnd = comboEnd;
this.bezier = new Bezier(hitObject.pixelLength); this.bezier = new Bezier();
// calculate slider time and ticks upon first update call // calculate slider time and ticks upon first update call
} }
@ -327,10 +352,13 @@ public class Slider {
// repeats // repeats
if (hitObject.repeat - 1 > currentRepeats) { if (hitObject.repeat - 1 > currentRepeats) {
if (currentRepeats % 2 == 0) // last circle if (currentRepeats % 2 == 0) { // last circle
reverseArrow.setRotation(bezier.getEndAngle());
reverseArrow.drawCentered(hitObject.sliderX[lastIndex], hitObject.sliderY[lastIndex]); reverseArrow.drawCentered(hitObject.sliderX[lastIndex], hitObject.sliderY[lastIndex]);
else // first circle } else { // first circle
reverseArrow.setRotation(bezier.getStartAngle());
reverseArrow.drawCentered(hitObject.x, hitObject.y); reverseArrow.drawCentered(hitObject.x, hitObject.y);
}
} }
if (timeDiff >= 0) { if (timeDiff >= 0) {

View File

@ -322,23 +322,22 @@ public class Game extends BasicGameState {
// game elements // game elements
score.drawGameElements(g, mapLength, false, objectIndex == 0); score.drawGameElements(g, mapLength, false, objectIndex == 0);
// first object... // skip beginning
if (objectIndex == 0) { if (objectIndex == 0 &&
// skip beginning osu.objects[0].time - skipOffsetTime > 5000 &&
if (osu.objects[objectIndex].time - skipOffsetTime > 5000 && trackPosition < osu.objects[0].time - skipOffsetTime)
trackPosition < osu.objects[objectIndex].time - skipOffsetTime) skipButton.draw();
skipButton.draw();
// mod icons
// mod icons if ((objectIndex == 0 && trackPosition < osu.objects[0].time) ||
if (trackPosition < osu.objects[objectIndex].time) { Options.isModActive(Options.MOD_AUTO)) {
for (int i = Options.MOD_MAX - 1; i >= 0; i--) { for (int i = Options.MOD_MAX - 1; i >= 0; i--) {
if (Options.isModActive(i)) { if (Options.isModActive(i)) {
Image modImage = Options.getModImage(i); Image modImage = Options.getModImage(i);
modImage.draw( modImage.draw(
(width * 0.85f) + ((i - (Options.MOD_MAX / 2)) * modImage.getWidth() / 3f), (width * 0.85f) + ((i - (Options.MOD_MAX / 2)) * modImage.getWidth() / 3f),
height / 10f height / 10f
); );
}
} }
} }
} }
@ -570,7 +569,9 @@ public class Game extends BasicGameState {
case Input.KEY_ESCAPE: case Input.KEY_ESCAPE:
// pause game // pause game
int trackPosition = MusicController.getPosition(); int trackPosition = MusicController.getPosition();
if (pauseTime < 0 && breakTime <= 0 && trackPosition >= osu.objects[0].time) { if (pauseTime < 0 && breakTime <= 0 &&
trackPosition >= osu.objects[0].time &&
!Options.isModActive(Options.MOD_AUTO)) {
pausedMouseX = input.getMouseX(); pausedMouseX = input.getMouseX();
pausedMouseY = input.getMouseY(); pausedMouseY = input.getMouseY();
pausePulse = 0f; pausePulse = 0f;

View File

@ -111,6 +111,8 @@ public class MainMenu extends BasicGameState {
@Override @Override
public void init(GameContainer container, StateBasedGame game) public void init(GameContainer container, StateBasedGame game)
throws SlickException { throws SlickException {
Utils.init(container, game);
this.game = game; this.game = game;
osuStartTime = System.currentTimeMillis(); osuStartTime = System.currentTimeMillis();

View File

@ -315,7 +315,6 @@ public class Options extends BasicGameState {
private Input input; private Input input;
private Graphics g; private Graphics g;
private int state; private int state;
private boolean init = false;
public Options(int state) { public Options(int state) {
this.state = state; this.state = state;
@ -329,8 +328,6 @@ public class Options extends BasicGameState {
this.input = container.getInput(); this.input = container.getInput();
this.g = container.getGraphics(); this.g = container.getGraphics();
Utils.init(container, game);
int width = container.getWidth(); int width = container.getWidth();
int height = container.getHeight(); int height = container.getHeight();
@ -376,16 +373,11 @@ public class Options extends BasicGameState {
); );
for (int i = 0; i < modButtons.length; i++) for (int i = 0; i < modButtons.length; i++)
modButtons[i].getImage().setAlpha(0.5f); modButtons[i].getImage().setAlpha(0.5f);
game.enterState(Opsu.STATE_MAINMENU, new EmptyTransition(), new FadeInTransition(Color.black));
} }
@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 (!init)
return;
g.setBackground(Utils.COLOR_BLACK_ALPHA); g.setBackground(Utils.COLOR_BLACK_ALPHA);
g.setColor(Color.white); g.setColor(Color.white);
@ -449,7 +441,7 @@ public class Options extends BasicGameState {
@Override @Override
public void update(GameContainer container, StateBasedGame game, int delta) public void update(GameContainer container, StateBasedGame game, int delta)
throws SlickException { throws SlickException {
init = true; // empty
} }
@Override @Override

View File

@ -363,6 +363,7 @@ public class SongMenu extends BasicGameState {
if (sortTabs[i].contains(x, y)) { if (sortTabs[i].contains(x, y)) {
if (i != currentSort) { if (i != currentSort) {
currentSort = i; currentSort = i;
SoundController.playSound(SoundController.SOUND_MENUCLICK);
OsuGroupNode oldFocusBase = Opsu.groups.getBaseNode(focusNode.index); OsuGroupNode oldFocusBase = Opsu.groups.getBaseNode(focusNode.index);
int oldFocusFileIndex = focusNode.osuFileIndex; int oldFocusFileIndex = focusNode.osuFileIndex;
focusNode = null; focusNode = null;
@ -395,7 +396,7 @@ public class SongMenu extends BasicGameState {
} else if (node.osuFileIndex == focusNode.osuFileIndex) { } else if (node.osuFileIndex == focusNode.osuFileIndex) {
// if already focused, load the beatmap // if already focused, load the beatmap
startGame(focusNode.osuFiles.get(focusNode.osuFileIndex)); startGame();
} else { } else {
// focus the node // focus the node
@ -443,7 +444,7 @@ public class SongMenu extends BasicGameState {
break; break;
case Input.KEY_ENTER: case Input.KEY_ENTER:
if (focusNode != null) if (focusNode != null)
startGame(focusNode.osuFiles.get(focusNode.osuFileIndex)); startGame();
break; break;
case Input.KEY_DOWN: case Input.KEY_DOWN:
changeIndex(1); changeIndex(1);
@ -595,11 +596,12 @@ public class SongMenu extends BasicGameState {
* Starts the game. * Starts the game.
* @param osu the OsuFile to send to the game * @param osu the OsuFile to send to the game
*/ */
private void startGame(OsuFile osu) { private void startGame() {
if (MusicController.isConverting()) if (MusicController.isConverting())
return; return;
SoundController.playSound(SoundController.SOUND_MENUHIT); SoundController.playSound(SoundController.SOUND_MENUHIT);
OsuFile osu = MusicController.getOsuFile();
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);