diff --git a/src/itdelatrisu/opsu/beatmap/HitObject.java b/src/itdelatrisu/opsu/beatmap/HitObject.java index 9cbe280a..dcf3fa59 100644 --- a/src/itdelatrisu/opsu/beatmap/HitObject.java +++ b/src/itdelatrisu/opsu/beatmap/HitObject.java @@ -19,6 +19,11 @@ package itdelatrisu.opsu.beatmap; import itdelatrisu.opsu.GameMod; +import itdelatrisu.opsu.objects.curves.CatmullCurve; +import itdelatrisu.opsu.objects.curves.CircumscribedCircle; +import itdelatrisu.opsu.objects.curves.Curve; +import itdelatrisu.opsu.objects.curves.LinearBezier; +import itdelatrisu.opsu.objects.curves.Vec2f; import java.text.DecimalFormat; import java.text.NumberFormat; @@ -403,6 +408,35 @@ public class HitObject { */ public float getPixelLength() { return pixelLength; } + /** + * Returns the time duration of the slider (excluding repeats), in milliseconds. + * @param sliderMultiplier the beatmap's slider movement speed multiplier + * @param beatLength the beat length + * @return the slider segment length + */ + public float getSliderTime(float sliderMultiplier, float beatLength) { + return beatLength * (pixelLength / sliderMultiplier) / 100f; + } + + /** + * Returns the slider curve. + * @param scaled whether to use scaled coordinates + * @return a new Curve instance + */ + public Curve getSliderCurve(boolean scaled) { + if (sliderType == SLIDER_PASSTHROUGH && sliderX.length == 2) { + Vec2f nora = new Vec2f(sliderX[0] - x, sliderY[0] - y).nor(); + Vec2f norb = new Vec2f(sliderX[0] - sliderX[1], sliderY[0] - sliderY[1]).nor(); + if (Math.abs(norb.x * nora.y - norb.y * nora.x) < 0.00001f) + return new LinearBezier(this, false, scaled); // vectors parallel, use linear bezier instead + else + return new CircumscribedCircle(this, scaled); + } else if (sliderType == SLIDER_CATMULL) + return new CatmullCurve(this, scaled); + else + return new LinearBezier(this, sliderType == SLIDER_LINEAR, scaled); + } + /** * Returns the spinner end time. * @return the end time (in ms) diff --git a/src/itdelatrisu/opsu/objects/Slider.java b/src/itdelatrisu/opsu/objects/Slider.java index 5c01a9b3..65cfc257 100644 --- a/src/itdelatrisu/opsu/objects/Slider.java +++ b/src/itdelatrisu/opsu/objects/Slider.java @@ -26,10 +26,7 @@ import itdelatrisu.opsu.Options; import itdelatrisu.opsu.Utils; import itdelatrisu.opsu.beatmap.Beatmap; import itdelatrisu.opsu.beatmap.HitObject; -import itdelatrisu.opsu.objects.curves.CatmullCurve; -import itdelatrisu.opsu.objects.curves.CircumscribedCircle; import itdelatrisu.opsu.objects.curves.Curve; -import itdelatrisu.opsu.objects.curves.LinearBezier; import itdelatrisu.opsu.states.Game; import itdelatrisu.opsu.ui.Colors; @@ -157,7 +154,7 @@ public class Slider implements GameObject { updatePosition(); // slider time calculations - this.sliderTime = game.getBeatLength() * (hitObject.getPixelLength() / sliderMultiplier) / 100f; + this.sliderTime = hitObject.getSliderTime(sliderMultiplier, game.getBeatLength()); this.sliderTimeTotal = sliderTime * hitObject.getRepeatCount(); // ticks @@ -525,13 +522,7 @@ public class Slider implements GameObject { public void updatePosition() { this.x = hitObject.getScaledX(); this.y = hitObject.getScaledY(); - - if (hitObject.getSliderType() == HitObject.SLIDER_PASSTHROUGH && hitObject.getSliderX().length == 2) - this.curve = new CircumscribedCircle(hitObject); - else if (hitObject.getSliderType() == HitObject.SLIDER_CATMULL) - this.curve = new CatmullCurve(hitObject); - else - this.curve = new LinearBezier(hitObject, hitObject.getSliderType() == HitObject.SLIDER_LINEAR); + this.curve = hitObject.getSliderCurve(true); } @Override