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:
parent
2c2f28b441
commit
03be29307f
Binary file not shown.
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 6.8 KiB |
|
@ -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())
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user