Made sliders very slightly easier.

Sliders no longer need to be held to the end, but near it (within a 300-hit offset) for perfect hit.

Also made a slight improvement to SongMenu.setFocus().

Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
Jeffrey Han 2015-02-21 17:12:18 -05:00
parent 00b98e07d6
commit 163e72d423
2 changed files with 31 additions and 23 deletions

View File

@ -70,8 +70,8 @@ public class Slider implements HitObject {
/** The time duration of the slider including repeats, in milliseconds. */ /** The time duration of the slider including repeats, in milliseconds. */
private float sliderTimeTotal = 0f; private float sliderTimeTotal = 0f;
/** Whether or not the result of the initial hit circle has been processed. */ /** Whether or not the result of the initial/final hit circles have been processed. */
private boolean sliderClicked = false; private boolean sliderClickedInitial = false, sliderClickedFinal = false;
/** Whether or not to show the follow circle. */ /** Whether or not to show the follow circle. */
private boolean followCircleActive = false; private boolean followCircleActive = false;
@ -180,7 +180,7 @@ public class Slider implements HitObject {
// start circle // start circle
hitCircle.drawCentered(x, y, color); hitCircle.drawCentered(x, y, color);
hitCircleOverlay.drawCentered(x, y, Utils.COLOR_WHITE_FADE); hitCircleOverlay.drawCentered(x, y, Utils.COLOR_WHITE_FADE);
if (sliderClicked) if (sliderClickedInitial)
; // don't draw current combo number if already clicked ; // don't draw current combo number if already clicked
else else
data.drawSymbolNumber(hitObject.getComboNumber(), x, y, data.drawSymbolNumber(hitObject.getComboNumber(), x, y,
@ -266,7 +266,7 @@ public class Slider implements HitObject {
@Override @Override
public boolean mousePressed(int x, int y) { public boolean mousePressed(int x, int y) {
if (sliderClicked) // first circle already processed if (sliderClickedInitial) // first circle already processed
return false; return false;
double distance = Math.hypot(hitObject.getX() - x, hitObject.getY() - y); double distance = Math.hypot(hitObject.getX() - x, hitObject.getY() - y);
@ -286,7 +286,7 @@ public class Slider implements HitObject {
if (result > -1) { if (result > -1) {
data.addHitError(hitObject.getTime(), x,y,trackPosition - hitObject.getTime()); data.addHitError(hitObject.getTime(), x,y,trackPosition - hitObject.getTime());
sliderClicked = true; sliderClickedInitial = true;
data.sliderTickResult(hitObject.getTime(), result, data.sliderTickResult(hitObject.getTime(), result,
hitObject.getX(), hitObject.getY(), hitObject.getHitSoundType()); hitObject.getX(), hitObject.getY(), hitObject.getHitSoundType());
return true; return true;
@ -323,12 +323,12 @@ public class Slider implements HitObject {
int lastIndex = hitObject.getSliderX().length - 1; int lastIndex = hitObject.getSliderX().length - 1;
boolean isAutoMod = GameMod.AUTO.isActive(); boolean isAutoMod = GameMod.AUTO.isActive();
if (!sliderClicked) { if (!sliderClickedInitial) {
int time = hitObject.getTime(); int time = hitObject.getTime();
// start circle time passed // start circle time passed
if (trackPosition > time + hitResultOffset[GameData.HIT_50]) { if (trackPosition > time + hitResultOffset[GameData.HIT_50]) {
sliderClicked = true; sliderClickedInitial = true;
if (isAutoMod) { // "auto" mod: catch any missed notes due to lag if (isAutoMod) { // "auto" mod: catch any missed notes due to lag
ticksHit++; ticksHit++;
data.sliderTickResult(time, GameData.HIT_SLIDER30, data.sliderTickResult(time, GameData.HIT_SLIDER30,
@ -342,7 +342,7 @@ public class Slider implements HitObject {
else if (isAutoMod) { else if (isAutoMod) {
if (Math.abs(trackPosition - time) < hitResultOffset[GameData.HIT_300]) { if (Math.abs(trackPosition - time) < hitResultOffset[GameData.HIT_300]) {
ticksHit++; ticksHit++;
sliderClicked = true; sliderClickedInitial = true;
data.sliderTickResult(time, GameData.HIT_SLIDER30, data.sliderTickResult(time, GameData.HIT_SLIDER30,
hitObject.getX(), hitObject.getY(), hitSound); hitObject.getX(), hitObject.getY(), hitSound);
} }
@ -353,19 +353,23 @@ public class Slider implements HitObject {
if (overlap || trackPosition > hitObject.getTime() + sliderTimeTotal) { if (overlap || trackPosition > hitObject.getTime() + sliderTimeTotal) {
tickIntervals++; tickIntervals++;
// "auto" mod: send a perfect hit result
if (isAutoMod)
ticksHit++;
// check if cursor pressed and within end circle // check if cursor pressed and within end circle
else if (Utils.isGameKeyPressed()) { if (Utils.isGameKeyPressed()) {
float[] c = curve.pointAt(getT(trackPosition, false)); float[] c = curve.pointAt(getT(trackPosition, false));
double distance = Math.hypot(c[0] - mouseX, c[1] - mouseY); double distance = Math.hypot(c[0] - mouseX, c[1] - mouseY);
int followCircleRadius = GameImage.SLIDER_FOLLOWCIRCLE.getImage().getWidth() / 2; int followCircleRadius = GameImage.SLIDER_FOLLOWCIRCLE.getImage().getWidth() / 2;
if (distance < followCircleRadius) if (distance < followCircleRadius)
ticksHit++; sliderClickedFinal = true;
} }
// final circle hit
if (sliderClickedFinal)
ticksHit++;
// "auto" mod: always send a perfect hit result
if (isAutoMod)
ticksHit = tickIntervals;
// calculate and send slider result // calculate and send slider result
hitResult(); hitResult();
return true; return true;
@ -421,6 +425,10 @@ public class Slider implements HitObject {
data.sliderTickResult(trackPosition, GameData.HIT_SLIDER10, data.sliderTickResult(trackPosition, GameData.HIT_SLIDER10,
c[0], c[1], (byte) -1); c[0], c[1], (byte) -1);
} }
// held near end of slider
if (!sliderClickedFinal && trackPosition > hitObject.getTime() + sliderTimeTotal - hitResultOffset[GameData.HIT_300])
sliderClickedFinal = true;
} else { } else {
followCircleActive = false; followCircleActive = false;

View File

@ -1106,11 +1106,11 @@ public class SongMenu extends BasicGameState {
/** /**
* Sets a new focus node. * Sets a new focus node.
* @param node the base node; it will be expanded if it isn't already * @param node the base node; it will be expanded if it isn't already
* @param pos the OsuFile element to focus; if out of bounds, it will be randomly chosen * @param osuFileIndex the OsuFile element to focus; if out of bounds, it will be randomly chosen
* @param flag if true, startNode will be set to the first node in the group * @param changeStartNode if true, startNode will be set to the first node in the group
* @return the old focus node * @return the old focus node
*/ */
public OsuGroupNode setFocus(OsuGroupNode node, int pos, boolean flag) { public OsuGroupNode setFocus(OsuGroupNode node, int osuFileIndex, boolean changeStartNode) {
if (node == null) if (node == null)
return null; return null;
@ -1126,18 +1126,18 @@ public class SongMenu extends BasicGameState {
// if start node was previously expanded, move it // if start node was previously expanded, move it
if (startNode != null && startNode.index == expandedIndex) if (startNode != null && startNode.index == expandedIndex)
startNode = node; startNode = OsuGroupList.get().getBaseNode(startNode.index);
} }
// check pos bounds // check osuFileIndex bounds
int length = node.osuFiles.size(); int length = node.osuFiles.size();
if (pos < 0 || pos > length - 1) // set a random pos if (osuFileIndex < 0 || osuFileIndex > length - 1) // set a random index
pos = (int) (Math.random() * length); osuFileIndex = (int) (Math.random() * length);
// change the focus node // change the focus node
if (flag || (startNode.index == 0 && startNode.osuFileIndex == -1 && startNode.prev == null)) if (changeStartNode || (startNode.index == 0 && startNode.osuFileIndex == -1 && startNode.prev == null))
startNode = node; startNode = node;
focusNode = OsuGroupList.get().getNode(node, pos); focusNode = OsuGroupList.get().getNode(node, osuFileIndex);
OsuFile osu = focusNode.osuFiles.get(focusNode.osuFileIndex); OsuFile osu = focusNode.osuFiles.get(focusNode.osuFileIndex);
MusicController.play(osu, true); MusicController.play(osu, true);
Utils.loadGlyphs(osu); Utils.loadGlyphs(osu);