Follow-up to #211: fix slider hit results not appearing; code cleanup.

Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
Jeffrey Han 2016-12-19 16:33:20 -05:00
parent d111fc0efe
commit e161d0180e
5 changed files with 106 additions and 82 deletions

View File

@ -153,10 +153,10 @@ public class GameData {
HIT_SLIDER_REPEAT = 10, // not a hit result HIT_SLIDER_REPEAT = 10, // not a hit result
HIT_ANIMATION_RESULT = 11; // not a hit result HIT_ANIMATION_RESULT = 11; // not a hit result
/** Hit result-related images (indexed by HIT_* constants). */ /** Hit result-related images (indexed by HIT_* constants to HIT_MAX). */
private Image[] hitResults; private Image[] hitResults;
/** Counts of each hit result so far. */ /** Counts of each hit result so far (indexed by HIT_* constants to HIT_MAX). */
private int[] hitResultCount; private int[] hitResultCount;
/** Total objects including slider hits/ticks (for determining Full Combo status). */ /** Total objects including slider hits/ticks (for determining Full Combo status). */
@ -192,7 +192,7 @@ public class GameData {
/** Current x coordinate of the combo burst image (for sliding animation). */ /** Current x coordinate of the combo burst image (for sliding animation). */
private float comboBurstX; private float comboBurstX;
/** Time offsets for obtaining each hit result (indexed by HIT_* constants). */ /** Time offsets for obtaining each hit result (indexed by HIT_* constants to HIT_MAX). */
private int[] hitResultOffset; private int[] hitResultOffset;
/** List of hit result objects associated with hit objects. */ /** List of hit result objects associated with hit objects. */
@ -232,7 +232,7 @@ public class GameData {
private LinkedBlockingDeque<HitErrorInfo> hitErrorList; private LinkedBlockingDeque<HitErrorInfo> hitErrorList;
/** Hit object types, used for drawing results. */ /** Hit object types, used for drawing results. */
public enum HitObjectType { CIRCLE, SLIDERTICK, SLIDER_FIRST, SLIDER_CURVE, SLIDER_LAST, SPINNER } public enum HitObjectType { CIRCLE, SLIDERTICK, SLIDER_FIRST, SLIDER_LAST, SPINNER }
/** Hit result helper class. */ /** Hit result helper class. */
private class HitObjectResult { private class HitObjectResult {
@ -892,7 +892,7 @@ public class GameData {
lighting.drawCentered(hitResult.x, hitResult.y, hitResult.color); lighting.drawCentered(hitResult.x, hitResult.y, hitResult.color);
} }
// hit animations, only draw when the 'hidden' mod is not enabled // hit animations (only draw when the "Hidden" mod is not enabled)
if (!GameMod.HIDDEN.isActive()) { if (!GameMod.HIDDEN.isActive()) {
drawHitAnimations(hitResult, trackPosition); drawHitAnimations(hitResult, trackPosition);
} }
@ -900,8 +900,9 @@ public class GameData {
// hit result // hit result
if (!hitResult.hideResult && ( if (!hitResult.hideResult && (
hitResult.hitResultType == HitObjectType.CIRCLE || hitResult.hitResultType == HitObjectType.CIRCLE ||
hitResult.hitResultType == HitObjectType.SPINNER || hitResult.hitResultType == HitObjectType.SLIDER_FIRST ||
hitResult.curve != null)) { hitResult.hitResultType == HitObjectType.SLIDER_LAST ||
hitResult.hitResultType == HitObjectType.SPINNER)) {
float scaleProgress = AnimationEquation.IN_OUT_BOUNCE.calc( float scaleProgress = AnimationEquation.IN_OUT_BOUNCE.calc(
(float) Utils.clamp(trackPosition - hitResult.time, 0, HITCIRCLE_TEXT_BOUNCE_TIME) / HITCIRCLE_TEXT_BOUNCE_TIME); (float) Utils.clamp(trackPosition - hitResult.time, 0, HITCIRCLE_TEXT_BOUNCE_TIME) / HITCIRCLE_TEXT_BOUNCE_TIME);
float scale = 1f + (HITCIRCLE_TEXT_ANIM_SCALE - 1f) * scaleProgress; float scale = 1f + (HITCIRCLE_TEXT_ANIM_SCALE - 1f) * scaleProgress;
@ -923,43 +924,42 @@ public class GameData {
} }
/** /**
* Draw the hit animations: circles, reversearrows, slider curves fading out and/or expanding * Draw the hit animations:
* @param hitResult the hitresult which holds information about the kind of animation to draw * circles, reverse arrows, slider curves (fading out and/or expanding).
* @param hitResult the hit result
* @param trackPosition the current track position (in ms) * @param trackPosition the current track position (in ms)
*/ */
private void drawHitAnimations(HitObjectResult hitResult, int trackPosition) { private void drawHitAnimations(HitObjectResult hitResult, int trackPosition) {
if (hitResult.hitResultType == HitObjectType.SLIDER_CURVE && hitResult.curve != null) { // fade out slider curve
if (hitResult.result != HIT_SLIDER_REPEAT && hitResult.curve != null) {
float progress = AnimationEquation.OUT_CUBIC.calc( float progress = AnimationEquation.OUT_CUBIC.calc(
(float) Utils.clamp(trackPosition - hitResult.time, 0, HITCIRCLE_FADE_TIME) / HITCIRCLE_FADE_TIME); (float) Utils.clamp(trackPosition - hitResult.time, 0, HITCIRCLE_FADE_TIME) / HITCIRCLE_FADE_TIME);
float alpha = 1f - progress; float alpha = 1f - progress;
// slider curve
float oldWhiteAlpha = Colors.WHITE_FADE.a; float oldWhiteAlpha = Colors.WHITE_FADE.a;
float oldColorAlpha = hitResult.color.a; float oldColorAlpha = hitResult.color.a;
Colors.WHITE_FADE.a = alpha; Colors.WHITE_FADE.a = hitResult.color.a = alpha;
hitResult.color.a = alpha;
hitResult.curve.draw(hitResult.color); hitResult.curve.draw(hitResult.color);
Colors.WHITE_FADE.a = oldWhiteAlpha; Colors.WHITE_FADE.a = oldWhiteAlpha;
hitResult.color.a = oldColorAlpha; hitResult.color.a = oldColorAlpha;
return;
} }
// miss, don't draw an animation
if (hitResult.result == HIT_MISS) { if (hitResult.result == HIT_MISS) {
return; return;
} }
if (hitResult.hitResultType != HitObjectType.CIRCLE // not a circle?
&& hitResult.hitResultType != HitObjectType.SLIDER_FIRST if (hitResult.hitResultType != HitObjectType.CIRCLE &&
&& hitResult.hitResultType != HitObjectType.SLIDER_LAST) { hitResult.hitResultType != HitObjectType.SLIDER_FIRST &&
hitResult.hitResultType != HitObjectType.SLIDER_LAST) {
return; return;
} }
// circles // hit circles
float progress = AnimationEquation.OUT_CUBIC.calc( float progress = AnimationEquation.OUT_CUBIC.calc(
(float) Utils.clamp(trackPosition - hitResult.time, 0, HITCIRCLE_FADE_TIME) / HITCIRCLE_FADE_TIME); (float) Utils.clamp(trackPosition - hitResult.time, 0, HITCIRCLE_FADE_TIME) / HITCIRCLE_FADE_TIME);
float scale = (!hitResult.expand) ? 1f : 1f + (HITCIRCLE_ANIM_SCALE - 1f) * progress; float scale = (!hitResult.expand) ? 1f : 1f + (HITCIRCLE_ANIM_SCALE - 1f) * progress;
float alpha = 1f - progress; float alpha = 1f - progress;
if (hitResult.result == HIT_SLIDER_REPEAT) { if (hitResult.result == HIT_SLIDER_REPEAT) {
// repeats // repeats
Image scaledRepeat = GameImage.REVERSEARROW.getImage().getScaledCopy(scale); Image scaledRepeat = GameImage.REVERSEARROW.getImage().getScaledCopy(scale);
@ -973,7 +973,6 @@ public class GameData {
scaledRepeat.rotate(ang); scaledRepeat.rotate(ang);
scaledRepeat.drawCentered(hitResult.x, hitResult.y, hitResult.color); scaledRepeat.drawCentered(hitResult.x, hitResult.y, hitResult.color);
} }
// hit circles
Image scaledHitCircle = GameImage.HITCIRCLE.getImage().getScaledCopy(scale); Image scaledHitCircle = GameImage.HITCIRCLE.getImage().getScaledCopy(scale);
Image scaledHitCircleOverlay = GameImage.HITCIRCLE_OVERLAY.getImage().getScaledCopy(scale); Image scaledHitCircleOverlay = GameImage.HITCIRCLE_OVERLAY.getImage().getScaledCopy(scale);
scaledHitCircle.setAlpha(alpha); scaledHitCircle.setAlpha(alpha);
@ -1210,15 +1209,28 @@ public class GameData {
health = 0f; health = 0f;
} }
public void sendRepeatSliderResult(int time, float x, float y, Color color, Curve curve, HitObjectType type) { /**
* Handles a slider repeat result (animation only: arrow).
* @param time the repeat time
* @param x the x coordinate
* @param y the y coordinate
* @param color the arrow color
* @param curve the slider curve
* @param type the hit object type
*/
public void sendSliderRepeatResult(int time, float x, float y, Color color, Curve curve, HitObjectType type) {
hitResultList.add(new HitObjectResult(time, HIT_SLIDER_REPEAT, x, y, color, type, curve, true, true)); hitResultList.add(new HitObjectResult(time, HIT_SLIDER_REPEAT, x, y, color, type, curve, true, true));
} }
public void sendSliderCurveResult(int time, Color color, Curve curve) { /**
hitResultList.add(new HitObjectResult(time, HIT_SLIDER_REPEAT, 0f, 0f, color, HitObjectType.SLIDER_CURVE, curve, true, true)); * Handles a slider start result (animation only: initial circle).
} * @param time the hit time
* @param x the x coordinate
public void sendAnimationResult(int time, float x, float y, Color color, boolean expand) { * @param y the y coordinate
* @param color the slider color
* @param expand whether or not the hit result animation should expand
*/
public void sendSliderStartResult(int time, float x, float y, Color color, boolean expand) {
hitResultList.add(new HitObjectResult(time, HIT_ANIMATION_RESULT, x, y, color, HitObjectType.CIRCLE, null, expand, true)); hitResultList.add(new HitObjectResult(time, HIT_ANIMATION_RESULT, x, y, color, HitObjectType.CIRCLE, null, expand, true));
} }
@ -1231,7 +1243,7 @@ public class GameData {
* @param hitObject the hit object * @param hitObject the hit object
* @param repeat the current repeat number * @param repeat the current repeat number
*/ */
public void sliderTickResult(int time, int result, float x, float y, HitObject hitObject, int repeat) { public void sendSliderTickResult(int time, int result, float x, float y, HitObject hitObject, int repeat) {
int hitValue = 0; int hitValue = 0;
switch (result) { switch (result) {
case HIT_SLIDER30: case HIT_SLIDER30:
@ -1412,11 +1424,12 @@ public class GameData {
* @param curve the slider curve (or null if not applicable) * @param curve the slider curve (or null if not applicable)
* @param sliderHeldToEnd whether or not the slider was held to the end (if applicable) * @param sliderHeldToEnd whether or not the slider was held to the end (if applicable)
*/ */
public void hitResult(int time, int result, float x, float y, Color color, public void sendHitResult(
int time, int result, float x, float y, Color color,
boolean end, HitObject hitObject, HitObjectType hitResultType, boolean end, HitObject hitObject, HitObjectType hitResultType,
boolean expand, int repeat, Curve curve, boolean sliderHeldToEnd) { boolean expand, int repeat, Curve curve, boolean sliderHeldToEnd
int hitResult = handleHitResult(time, result, x, y, color, end, hitObject, ) {
hitResultType, repeat, (curve != null && !sliderHeldToEnd)); int hitResult = handleHitResult(time, result, x, y, color, end, hitObject, hitResultType, repeat, (curve != null && !sliderHeldToEnd));
if (hitResult == HIT_MISS && (GameMod.RELAX.isActive() || GameMod.AUTOPILOT.isActive())) if (hitResult == HIT_MISS && (GameMod.RELAX.isActive() || GameMod.AUTOPILOT.isActive()))
return; // "relax" and "autopilot" mods: hide misses return; // "relax" and "autopilot" mods: hide misses

View File

@ -63,6 +63,7 @@ import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.Display; import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import org.newdawn.slick.Animation; import org.newdawn.slick.Animation;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer; import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Input; import org.newdawn.slick.Input;
import org.newdawn.slick.state.StateBasedGame; import org.newdawn.slick.state.StateBasedGame;
@ -157,6 +158,14 @@ public class Utils {
anim.draw(x - (anim.getWidth() / 2f), y - (anim.getHeight() / 2f)); anim.draw(x - (anim.getWidth() / 2f), y - (anim.getHeight() / 2f));
} }
/**
* Returns the luminance of a color.
* @param c the color
*/
public static float getLuminance(Color c) {
return 0.299f*c.r + 0.587f*c.g + 0.114f*c.b;
}
/** /**
* Clamps a value between a lower and upper bound. * Clamps a value between a lower and upper bound.
* @param val the value to clamp * @param val the value to clamp

View File

@ -156,7 +156,7 @@ public class Circle implements GameObject {
if (result > -1) { if (result > -1) {
data.addHitError(hitObject.getTime(), x, y, timeDiff); data.addHitError(hitObject.getTime(), x, y, timeDiff);
data.hitResult(trackPosition, result, this.x, this.y, color, comboEnd, hitObject, HitObjectType.CIRCLE, true, 0, null, false); data.sendHitResult(trackPosition, result, this.x, this.y, color, comboEnd, hitObject, HitObjectType.CIRCLE, true, 0, null, false);
return true; return true;
} }
} }
@ -172,17 +172,17 @@ public class Circle implements GameObject {
if (trackPosition > time + hitResultOffset[GameData.HIT_50]) { if (trackPosition > time + hitResultOffset[GameData.HIT_50]) {
if (isAutoMod) // "auto" mod: catch any missed notes due to lag if (isAutoMod) // "auto" mod: catch any missed notes due to lag
data.hitResult(time, GameData.HIT_300, x, y, color, comboEnd, hitObject, HitObjectType.CIRCLE, true, 0, null, false); data.sendHitResult(time, GameData.HIT_300, x, y, color, comboEnd, hitObject, HitObjectType.CIRCLE, true, 0, null, false);
else // no more points can be scored, so send a miss else // no more points can be scored, so send a miss
data.hitResult(trackPosition, GameData.HIT_MISS, x, y, null, comboEnd, hitObject, HitObjectType.CIRCLE, true, 0, null, false); data.sendHitResult(trackPosition, GameData.HIT_MISS, x, y, null, comboEnd, hitObject, HitObjectType.CIRCLE, true, 0, null, false);
return true; return true;
} }
// "auto" mod: send a perfect hit result // "auto" mod: send a perfect hit result
else if (isAutoMod) { else if (isAutoMod) {
if (Math.abs(trackPosition - time) < hitResultOffset[GameData.HIT_300]) { if (Math.abs(trackPosition - time) < hitResultOffset[GameData.HIT_300]) {
data.hitResult(time, GameData.HIT_300, x, y, color, comboEnd, hitObject, HitObjectType.CIRCLE, true, 0, null, false); data.sendHitResult(time, GameData.HIT_300, x, y, color, comboEnd, hitObject, HitObjectType.CIRCLE, true, 0, null, false);
return true; return true;
} }
} }

View File

@ -180,7 +180,7 @@ public class Slider implements GameObject {
@Override @Override
public void draw(Graphics g, int trackPosition) { public void draw(Graphics g, int trackPosition) {
int timeDiff = hitObject.getTime() - trackPosition; int timeDiff = hitObject.getTime() - trackPosition;
final int repeats = hitObject.getRepeatCount(); final int repeatCount = hitObject.getRepeatCount();
final int approachTime = game.getApproachTime(); final int approachTime = game.getApproachTime();
final int fadeInTime = game.getFadeInTime(); final int fadeInTime = game.getFadeInTime();
float scale = timeDiff / (float) approachTime; float scale = timeDiff / (float) approachTime;
@ -198,7 +198,7 @@ public class Slider implements GameObject {
float oldWhiteFadeAlpha = Colors.WHITE_FADE.a; float oldWhiteFadeAlpha = Colors.WHITE_FADE.a;
float sliderAlpha = 1f; float sliderAlpha = 1f;
if (GameMod.HIDDEN.isActive() && trackPosition > hitObject.getTime()) { if (GameMod.HIDDEN.isActive() && trackPosition > hitObject.getTime()) {
// "hidden" mod: fade out sliders // "Hidden" mod: fade out sliders
Colors.WHITE_FADE.a = color.a = sliderAlpha = Colors.WHITE_FADE.a = color.a = sliderAlpha =
Math.max(0f, 1f - ((float) (trackPosition - hitObject.getTime()) / (getEndTime() - hitObject.getTime())) * 1.05f); Math.max(0f, 1f - ((float) (trackPosition - hitObject.getTime()) / (getEndTime() - hitObject.getTime())) * 1.05f);
} }
@ -206,8 +206,8 @@ public class Slider implements GameObject {
float curveInterval = Options.isSliderSnaking() ? alpha : 1f; float curveInterval = Options.isSliderSnaking() ? alpha : 1f;
curve.draw(color,curveInterval); curve.draw(color,curveInterval);
// end circle, only draw if ball still has to go there // end circle (only draw if ball still has to go there)
if (curveInterval == 1f && currentRepeats < repeats - (repeats % 2 == 0 ? 1 : 0)) { if (curveInterval == 1f && currentRepeats < repeatCount - (repeatCount % 2 == 0 ? 1 : 0)) {
Color circleColor = new Color(color); Color circleColor = new Color(color);
Color overlayColor = new Color(Colors.WHITE_FADE); Color overlayColor = new Color(Colors.WHITE_FADE);
if (currentRepeats == 0) { if (currentRepeats == 0) {
@ -233,7 +233,7 @@ public class Slider implements GameObject {
} }
// start circle, only draw if ball still has to go there // start circle, only draw if ball still has to go there
if (!sliderClickedInitial || currentRepeats < repeats - (repeats % 2 == 1 ? 1 : 0)) { if (!sliderClickedInitial || currentRepeats < repeatCount - (repeatCount % 2 == 1 ? 1 : 0)) {
hitCircle.drawCentered(x, y, firstCircleColor); hitCircle.drawCentered(x, y, firstCircleColor);
if (!overlayAboveNumber || sliderClickedInitial) if (!overlayAboveNumber || sliderClickedInitial)
hitCircleOverlay.drawCentered(x, y, startCircleOverlayColor); hitCircleOverlay.drawCentered(x, y, startCircleOverlayColor);
@ -269,11 +269,11 @@ public class Slider implements GameObject {
// repeats // repeats
if (curveInterval == 1.0f) { if (curveInterval == 1.0f) {
for (int tcurRepeat = currentRepeats; tcurRepeat <= currentRepeats + 1 && tcurRepeat < repeats - 1; tcurRepeat++) { for (int tcurRepeat = currentRepeats; tcurRepeat <= currentRepeats + 1 && tcurRepeat < repeatCount - 1; tcurRepeat++) {
Image arrow = GameImage.REVERSEARROW.getImage(); Image arrow = GameImage.REVERSEARROW.getImage();
// bouncing animation // bouncing animation
//arrow = arrow.getScaledCopy((float) (1 + 0.2d * ((trackPosition + sliderTime * tcurRepeat) % 292) / 292)); //arrow = arrow.getScaledCopy((float) (1 + 0.2d * ((trackPosition + sliderTime * tcurRepeat) % 292) / 292));
float colorLuminance = 0.299f*color.r + 0.587f*color.g + 0.114f*color.b; float colorLuminance = Utils.getLuminance(color);
Color arrowColor = colorLuminance < 0.8f ? Color.white : Color.black; Color arrowColor = colorLuminance < 0.8f ? Color.white : Color.black;
if (tcurRepeat == 0) { if (tcurRepeat == 0) {
arrow.setAlpha(Options.isSliderSnaking() ? decorationsAlpha : 1f); arrow.setAlpha(Options.isSliderSnaking() ? decorationsAlpha : 1f);
@ -469,19 +469,21 @@ public class Slider implements GameObject {
float cx, cy; float cx, cy;
HitObjectType type; HitObjectType type;
if (currentRepeats % 2 == 0) { // last circle if (currentRepeats % 2 == 0) {
// last circle
Vec2f lastPos = curve.pointAt(1); Vec2f lastPos = curve.pointAt(1);
cx = lastPos.x; cx = lastPos.x;
cy = lastPos.y; cy = lastPos.y;
type = HitObjectType.SLIDER_LAST; type = HitObjectType.SLIDER_LAST;
} else { // first circle } else {
// first circle
cx = x; cx = x;
cy = y; cy = y;
type = HitObjectType.SLIDER_FIRST; type = HitObjectType.SLIDER_FIRST;
} }
data.hitResult(hitObject.getTime() + (int) sliderTimeTotal, result, data.sendHitResult(hitObject.getTime() + (int) sliderTimeTotal, result,
cx, cy, color, comboEnd, hitObject, type, sliderHeldToEnd, cx, cy, color, comboEnd, hitObject, type, sliderHeldToEnd,
currentRepeats + 1, null, sliderHeldToEnd); currentRepeats + 1, curve, sliderHeldToEnd);
return result; return result;
} }
@ -500,17 +502,17 @@ public class Slider implements GameObject {
if (timeDiff < hitResultOffset[GameData.HIT_50]) { if (timeDiff < hitResultOffset[GameData.HIT_50]) {
result = GameData.HIT_SLIDER30; result = GameData.HIT_SLIDER30;
ticksHit++; ticksHit++;
data.sendAnimationResult(trackPosition, this.x, this.y, color, true); data.sendSliderStartResult(trackPosition, this.x, this.y, color, true);
} else if (timeDiff < hitResultOffset[GameData.HIT_MISS]) { } else if (timeDiff < hitResultOffset[GameData.HIT_MISS]) {
result = GameData.HIT_MISS; result = GameData.HIT_MISS;
data.sendAnimationResult(trackPosition, this.x, this.y, color, false); data.sendSliderStartResult(trackPosition, this.x, this.y, color, false);
} }
//else not a hit //else not a hit
if (result > -1) { if (result > -1) {
data.addHitError(hitObject.getTime(), x,y,trackPosition - hitObject.getTime()); data.addHitError(hitObject.getTime(), x,y,trackPosition - hitObject.getTime());
sliderClickedInitial = true; sliderClickedInitial = true;
data.sliderTickResult(hitObject.getTime(), result, this.x, this.y, hitObject, currentRepeats); data.sendSliderTickResult(hitObject.getTime(), result, this.x, this.y, hitObject, currentRepeats);
return true; return true;
} }
} }
@ -531,11 +533,11 @@ public class Slider implements GameObject {
sliderClickedInitial = 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, x, y, hitObject, currentRepeats); data.sendSliderTickResult(time, GameData.HIT_SLIDER30, x, y, hitObject, currentRepeats);
data.sendAnimationResult(time, x, y, color, true); data.sendSliderStartResult(time, x, y, color, true);
} else { } else {
data.sliderTickResult(time, GameData.HIT_MISS, x, y, hitObject, currentRepeats); data.sendSliderTickResult(time, GameData.HIT_MISS, x, y, hitObject, currentRepeats);
data.sendAnimationResult(trackPosition, x, y, color, false); data.sendSliderStartResult(trackPosition, x, y, color, false);
} }
} }
@ -544,8 +546,8 @@ public class Slider implements GameObject {
if (Math.abs(trackPosition - time) < hitResultOffset[GameData.HIT_300]) { if (Math.abs(trackPosition - time) < hitResultOffset[GameData.HIT_300]) {
ticksHit++; ticksHit++;
sliderClickedInitial = true; sliderClickedInitial = true;
data.sliderTickResult(time, GameData.HIT_SLIDER30, x, y, hitObject, currentRepeats); data.sendSliderTickResult(time, GameData.HIT_SLIDER30, x, y, hitObject, currentRepeats);
data.sendAnimationResult(time, x, y, color, true); data.sendSliderStartResult(time, x, y, color, true);
} }
} }
@ -578,8 +580,6 @@ public class Slider implements GameObject {
// calculate and send slider result // calculate and send slider result
hitResult(); hitResult();
// send 'curve fade out' hit result
data.sendSliderCurveResult(getEndTime(), color, curve);
return true; return true;
} }
@ -629,29 +629,31 @@ public class Slider implements GameObject {
HitObjectType type; HitObjectType type;
float posX, posY; float posX, posY;
if (currentRepeats % 2 > 0) { // last circle if (currentRepeats % 2 > 0) {
// last circle
type = HitObjectType.SLIDER_LAST; type = HitObjectType.SLIDER_LAST;
Vec2f endPos = curve.pointAt(1f); Vec2f endPos = curve.pointAt(1f);
posX = endPos.x; posX = endPos.x;
posY = endPos.y; posY = endPos.y;
} else { // first circle } else {
// first circle
type = HitObjectType.SLIDER_FIRST; type = HitObjectType.SLIDER_FIRST;
posX = this.x; posX = this.x;
posY = this.y; posY = this.y;
} }
data.sliderTickResult(trackPosition, GameData.HIT_SLIDER30, data.sendSliderTickResult(trackPosition, GameData.HIT_SLIDER30,
posX, posY, hitObject, currentRepeats); posX, posY, hitObject, currentRepeats);
// send hit result, to fade out reversearrow // fade out reverse arrow
float colorLuminance = 0.299f*color.r + 0.587f*color.g + 0.114f*color.b; float colorLuminance = Utils.getLuminance(color);
Color arrowColor = colorLuminance < 0.8f ? Color.white : Color.black; Color arrowColor = colorLuminance < 0.8f ? Color.white : Color.black;
data.sendRepeatSliderResult(trackPosition, posX, posY, arrowColor, curve, type); data.sendSliderRepeatResult(trackPosition, posX, posY, arrowColor, curve, type);
} }
// held during new tick // held during new tick
if (isNewTick) { if (isNewTick) {
ticksHit++; ticksHit++;
data.sliderTickResult(trackPosition, GameData.HIT_SLIDER10, data.sendSliderTickResult(trackPosition, GameData.HIT_SLIDER10,
c.x, c.y, hitObject, currentRepeats); c.x, c.y, hitObject, currentRepeats);
} }
@ -662,9 +664,9 @@ public class Slider implements GameObject {
followCircleActive = false; followCircleActive = false;
if (isNewRepeat) if (isNewRepeat)
data.sliderTickResult(trackPosition, GameData.HIT_MISS, 0, 0, hitObject, currentRepeats); data.sendSliderTickResult(trackPosition, GameData.HIT_MISS, 0, 0, hitObject, currentRepeats);
if (isNewTick) if (isNewTick)
data.sliderTickResult(trackPosition, GameData.HIT_MISS, 0, 0, hitObject, currentRepeats); data.sendSliderTickResult(trackPosition, GameData.HIT_MISS, 0, 0, hitObject, currentRepeats);
} }
return false; return false;

View File

@ -252,7 +252,7 @@ public class Spinner implements GameObject {
else else
result = GameData.HIT_MISS; result = GameData.HIT_MISS;
data.hitResult(hitObject.getEndTime(), result, width / 2, height / 2, data.sendHitResult(hitObject.getEndTime(), result, width / 2, height / 2,
Color.transparent, true, hitObject, HitObjectType.SPINNER, true, 0, null, false); Color.transparent, true, hitObject, HitObjectType.SPINNER, true, 0, null, false);
return result; return result;
} }