Added scrolling animation to "random" song selection.
Involves temporarily changing the kinetic scrolling speed, so it's a little messy... Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
parent
14496050ea
commit
eb331360b9
|
@ -262,6 +262,9 @@ public class SongMenu extends BasicGameState {
|
||||||
/** The star stream. */
|
/** The star stream. */
|
||||||
private StarStream starStream;
|
private StarStream starStream;
|
||||||
|
|
||||||
|
/** Whether the menu is currently scrolling to the focus node (blocks other actions). */
|
||||||
|
private boolean isScrollingToFocus = false;
|
||||||
|
|
||||||
// game-related variables
|
// game-related variables
|
||||||
private GameContainer container;
|
private GameContainer container;
|
||||||
private StateBasedGame game;
|
private StateBasedGame game;
|
||||||
|
@ -679,15 +682,25 @@ public class SongMenu extends BasicGameState {
|
||||||
searchTransitionTimer = SEARCH_TRANSITION_TIME;
|
searchTransitionTimer = SEARCH_TRANSITION_TIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scores
|
// scores
|
||||||
if (focusScores != null) {
|
if (focusScores != null) {
|
||||||
startScorePos.setMinMax(0, (focusScores.length - MAX_SCORE_BUTTONS) * ScoreData.getButtonOffset());
|
startScorePos.setMinMax(0, (focusScores.length - MAX_SCORE_BUTTONS) * ScoreData.getButtonOffset());
|
||||||
startScorePos.update(delta);
|
startScorePos.update(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
// mouse hover
|
// scrolling
|
||||||
songScrolling.update(delta);
|
songScrolling.update(delta);
|
||||||
|
if (isScrollingToFocus) {
|
||||||
|
float distanceDiff = Math.abs(songScrolling.getPosition() - songScrolling.getTargetPosition());
|
||||||
|
if (distanceDiff <= buttonOffset / 8f) { // close enough, stop blocking input
|
||||||
|
songScrolling.scrollToPosition(songScrolling.getTargetPosition());
|
||||||
|
songScrolling.setSpeedMultiplier(1f);
|
||||||
|
isScrollingToFocus = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
updateDrawnSongPosition();
|
updateDrawnSongPosition();
|
||||||
|
|
||||||
|
// mouse hover
|
||||||
boolean isHover = false;
|
boolean isHover = false;
|
||||||
if (mouseY > headerY && mouseY < footerY) {
|
if (mouseY > headerY && mouseY < footerY) {
|
||||||
BeatmapSetNode node = startNode;
|
BeatmapSetNode node = startNode;
|
||||||
|
@ -733,12 +746,18 @@ public class SongMenu extends BasicGameState {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mousePressed(int button, int x, int y) {
|
public void mousePressed(int button, int x, int y) {
|
||||||
|
if (isScrollingToFocus)
|
||||||
|
return;
|
||||||
|
|
||||||
songScrolling.pressed();
|
songScrolling.pressed();
|
||||||
startScorePos.pressed();
|
startScorePos.pressed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseReleased(int button, int x, int y) {
|
public void mouseReleased(int button, int x, int y) {
|
||||||
|
if (isScrollingToFocus)
|
||||||
|
return;
|
||||||
|
|
||||||
songScrolling.released();
|
songScrolling.released();
|
||||||
startScorePos.released();
|
startScorePos.released();
|
||||||
}
|
}
|
||||||
|
@ -750,7 +769,7 @@ public class SongMenu extends BasicGameState {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// block input
|
// block input
|
||||||
if (reloadThread != null || beatmapMenuTimer > -1)
|
if (isInputBlocked())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// back
|
// back
|
||||||
|
@ -869,7 +888,7 @@ public class SongMenu extends BasicGameState {
|
||||||
@Override
|
@Override
|
||||||
public void keyPressed(int key, char c) {
|
public void keyPressed(int key, char c) {
|
||||||
// block input
|
// block input
|
||||||
if ((reloadThread != null && !(key == Input.KEY_ESCAPE || key == Input.KEY_F12)) || beatmapMenuTimer > -1)
|
if ((reloadThread != null && !(key == Input.KEY_ESCAPE || key == Input.KEY_F12)) || beatmapMenuTimer > -1 || isScrollingToFocus)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (key) {
|
switch (key) {
|
||||||
|
@ -1022,7 +1041,7 @@ public class SongMenu extends BasicGameState {
|
||||||
@Override
|
@Override
|
||||||
public void mouseDragged(int oldx, int oldy, int newx, int newy) {
|
public void mouseDragged(int oldx, int oldy, int newx, int newy) {
|
||||||
// block input
|
// block input
|
||||||
if (reloadThread != null || beatmapMenuTimer > -1)
|
if (isInputBlocked())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int diff = newy - oldy;
|
int diff = newy - oldy;
|
||||||
|
@ -1056,7 +1075,7 @@ public class SongMenu extends BasicGameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
// block input
|
// block input
|
||||||
if (reloadThread != null || beatmapMenuTimer > -1)
|
if (isInputBlocked())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int shift = (newValue < 0) ? 1 : -1;
|
int shift = (newValue < 0) ? 1 : -1;
|
||||||
|
@ -1082,7 +1101,9 @@ public class SongMenu extends BasicGameState {
|
||||||
selectOptionsButton.resetHover();
|
selectOptionsButton.resetHover();
|
||||||
hoverOffset.setTime(0);
|
hoverOffset.setTime(0);
|
||||||
hoverIndex = null;
|
hoverIndex = null;
|
||||||
|
isScrollingToFocus = false;
|
||||||
songScrolling.released();
|
songScrolling.released();
|
||||||
|
songScrolling.setSpeedMultiplier(1f);
|
||||||
startScorePos.setPosition(0);
|
startScorePos.setPosition(0);
|
||||||
beatmapMenuTimer = -1;
|
beatmapMenuTimer = -1;
|
||||||
searchTransitionTimer = SEARCH_TRANSITION_TIME;
|
searchTransitionTimer = SEARCH_TRANSITION_TIME;
|
||||||
|
@ -1333,10 +1354,9 @@ public class SongMenu extends BasicGameState {
|
||||||
startScorePos.setPosition(0);
|
startScorePos.setPosition(0);
|
||||||
|
|
||||||
if (oldFocus != null && oldFocus.getBeatmapSet() != node.getBeatmapSet()) {
|
if (oldFocus != null && oldFocus.getBeatmapSet() != node.getBeatmapSet()) {
|
||||||
// Close previous node
|
// close previous node
|
||||||
if (node.index > oldFocus.index) {
|
if (node.index > oldFocus.index) {
|
||||||
float offset = (oldFocus.getBeatmapSet().size() - 1) * buttonOffset;
|
float offset = (oldFocus.getBeatmapSet().size() - 1) * buttonOffset;
|
||||||
//updateSongPos(-offset);
|
|
||||||
songScrolling.addOffset(-offset);
|
songScrolling.addOffset(-offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1354,8 +1374,15 @@ public class SongMenu extends BasicGameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
// change the focus node
|
// change the focus node
|
||||||
if (changeStartNode || (startNode.index == 0 && startNode.beatmapIndex == -1 && startNode.prev == null))
|
if (changeStartNode || (startNode.index == 0 && startNode.beatmapIndex == -1 && startNode.prev == null)) {
|
||||||
songScrolling.setPosition((node.index - 1) * buttonOffset);
|
if (startNode == null || game.getCurrentStateID() != Opsu.STATE_SONGMENU)
|
||||||
|
songScrolling.setPosition((node.index - 1) * buttonOffset);
|
||||||
|
else {
|
||||||
|
isScrollingToFocus = true;
|
||||||
|
songScrolling.setSpeedMultiplier(2f);
|
||||||
|
songScrolling.released();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
updateDrawnSongPosition();
|
updateDrawnSongPosition();
|
||||||
|
|
||||||
|
@ -1519,6 +1546,14 @@ public class SongMenu extends BasicGameState {
|
||||||
reloadThread.start();
|
reloadThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether a delayed/animated event is currently blocking user input.
|
||||||
|
* @return true if blocking input
|
||||||
|
*/
|
||||||
|
private boolean isInputBlocked() {
|
||||||
|
return (reloadThread != null || beatmapMenuTimer > -1 || isScrollingToFocus);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates all star ratings for a beatmap set.
|
* Calculates all star ratings for a beatmap set.
|
||||||
* @param beatmapSet the set of beatmaps
|
* @param beatmapSet the set of beatmaps
|
||||||
|
|
|
@ -28,7 +28,7 @@ public class KineticScrolling {
|
||||||
/** The moving averaging constant. */
|
/** The moving averaging constant. */
|
||||||
private static final float AVG_CONST = 0.2f, ONE_MINUS_AVG_CONST = 1 - AVG_CONST;
|
private static final float AVG_CONST = 0.2f, ONE_MINUS_AVG_CONST = 1 - AVG_CONST;
|
||||||
|
|
||||||
/** The constant used to determine how fast the target position will be reach. */
|
/** The constant used to determine how fast the target position will be reached. */
|
||||||
private static final int TIME_CONST = 200;
|
private static final int TIME_CONST = 200;
|
||||||
|
|
||||||
/** The constant used to determine how much of the velocity will be used to launch to the target. */
|
/** The constant used to determine how much of the velocity will be used to launch to the target. */
|
||||||
|
@ -58,12 +58,21 @@ public class KineticScrolling {
|
||||||
/** The moving average of the velocity. */
|
/** The moving average of the velocity. */
|
||||||
private float avgVelocity;
|
private float avgVelocity;
|
||||||
|
|
||||||
|
/** The speed multiplier (divides {@link #TIME_CONST}). */
|
||||||
|
private float speedMultiplier = 1f;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current Position.
|
* Returns the current position.
|
||||||
* @return the position
|
* @return the position
|
||||||
*/
|
*/
|
||||||
public float getPosition() { return position; }
|
public float getPosition() { return position; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the target position.
|
||||||
|
* @return the target position
|
||||||
|
*/
|
||||||
|
public float getTargetPosition() { return target; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the scrolling.
|
* Updates the scrolling.
|
||||||
* @param delta the elapsed time since the last update
|
* @param delta the elapsed time since the last update
|
||||||
|
@ -71,7 +80,7 @@ public class KineticScrolling {
|
||||||
public void update(float delta) {
|
public void update(float delta) {
|
||||||
if (!pressed) {
|
if (!pressed) {
|
||||||
totalDelta += delta;
|
totalDelta += delta;
|
||||||
position = target + (float) (-amplitude * Math.exp(-totalDelta / TIME_CONST));
|
position = target + (float) (-amplitude * Math.exp(-totalDelta / (TIME_CONST / speedMultiplier)));
|
||||||
} else {
|
} else {
|
||||||
avgVelocity = (ONE_MINUS_AVG_CONST * avgVelocity + AVG_CONST * (deltaPosition * 1000f / delta));
|
avgVelocity = (ONE_MINUS_AVG_CONST * avgVelocity + AVG_CONST * (deltaPosition * 1000f / delta));
|
||||||
|
|
||||||
|
@ -165,4 +174,15 @@ public class KineticScrolling {
|
||||||
this.min = min;
|
this.min = min;
|
||||||
this.max = max;
|
this.max = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the multiplier for how fast the target position will be reached.
|
||||||
|
* @param multiplier the speed multiplier (e.g. 1f = normal speed, 2f = reaches in half the time)
|
||||||
|
* @throws IllegalArgumentException if the multiplier is negative or zero
|
||||||
|
*/
|
||||||
|
public void setSpeedMultiplier(float multiplier) {
|
||||||
|
if (multiplier <= 0f)
|
||||||
|
throw new IllegalArgumentException("Speed multiplier must be above zero.");
|
||||||
|
this.speedMultiplier = multiplier;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user