mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 09:32:55 +08:00
Merge remote-tracking branch 'upstream/master' into general-slider-improvements
This commit is contained in:
commit
3b4e4bd110
@ -78,7 +78,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
bool isRepeatAtEnd = repeatPoint.RepeatIndex % 2 == 0;
|
||||
List<Vector2> curve = drawableSlider.Body.CurrentCurve;
|
||||
|
||||
Position = isRepeatAtEnd ? end : start;
|
||||
var positionOnCurve = isRepeatAtEnd ? end : start;
|
||||
Position = positionOnCurve + drawableSlider.HitObject.StackOffset;
|
||||
|
||||
if (curve.Count < 2)
|
||||
return;
|
||||
@ -89,10 +90,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
// find the next vector2 in the curve which is not equal to our current position to infer a rotation.
|
||||
for (int i = searchStart; i >= 0 && i < curve.Count; i += direction)
|
||||
{
|
||||
if (curve[i] == Position)
|
||||
if (curve[i] == positionOnCurve)
|
||||
continue;
|
||||
|
||||
Rotation = MathHelper.RadiansToDegrees((float)Math.Atan2(curve[i].Y - Position.Y, curve[i].X - Position.X));
|
||||
Rotation = MathHelper.RadiansToDegrees((float)Math.Atan2(curve[i].Y - positionOnCurve.Y, curve[i].X - positionOnCurve.X));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Rulesets.Osu.Judgements;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
@ -68,7 +67,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
{
|
||||
var drawableTick = new DrawableSliderTick(tick)
|
||||
{
|
||||
Position = tick.Position
|
||||
Position = tick.StackedPosition
|
||||
};
|
||||
|
||||
ticks.Add(drawableTick);
|
||||
@ -80,7 +79,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
{
|
||||
var drawableRepeatPoint = new DrawableRepeatPoint(repeatPoint, this)
|
||||
{
|
||||
Position = repeatPoint.Position
|
||||
Position = repeatPoint.StackedPosition
|
||||
};
|
||||
|
||||
repeatPoints.Add(drawableRepeatPoint);
|
||||
@ -96,7 +95,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
config.BindWith(OsuSetting.SnakingOutSliders, Body.SnakingOut);
|
||||
}
|
||||
|
||||
private int currentSpan;
|
||||
public bool Tracking;
|
||||
|
||||
protected override void Update()
|
||||
@ -105,19 +103,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
|
||||
Tracking = Ball.Tracking;
|
||||
|
||||
double progress = MathHelper.Clamp((Time.Current - slider.StartTime) / slider.Duration, 0, 1);
|
||||
|
||||
int span = slider.SpanAt(progress);
|
||||
progress = slider.ProgressAt(progress);
|
||||
|
||||
if (span > currentSpan)
|
||||
currentSpan = span;
|
||||
double completionProgress = MathHelper.Clamp((Time.Current - slider.StartTime) / slider.Duration, 0, 1);
|
||||
|
||||
//todo: we probably want to reconsider this before adding scoring, but it looks and feels nice.
|
||||
if (!HeadCircle.IsHit)
|
||||
HeadCircle.Position = slider.Curve.PositionAt(progress);
|
||||
HeadCircle.Position = slider.StackedPositionAt(completionProgress);
|
||||
|
||||
foreach (var c in components.OfType<ISliderProgress>()) c.UpdateProgress(progress, span);
|
||||
foreach (var c in components.OfType<ISliderProgress>()) c.UpdateProgress(completionProgress);
|
||||
foreach (var c in components.OfType<ITrackSnaking>()) c.UpdateSnakingPosition(slider.Curve.PositionAt(Body.SnakedStart ?? 0), slider.Curve.PositionAt(Body.SnakedEnd ?? 0));
|
||||
foreach (var t in components.OfType<IRequireTracking>()) t.Tracking = Ball.Tracking;
|
||||
}
|
||||
|
@ -139,9 +139,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateProgress(double progress, int span)
|
||||
public void UpdateProgress(double completionProgress)
|
||||
{
|
||||
Position = slider.Curve.PositionAt(progress);
|
||||
Position = slider.StackedPositionAt(completionProgress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -181,8 +181,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
return true;
|
||||
}
|
||||
|
||||
public void UpdateProgress(double progress, int span)
|
||||
public void UpdateProgress(double completionProgress)
|
||||
{
|
||||
var span = slider.SpanAt(completionProgress);
|
||||
var spanProgress = slider.ProgressAt(completionProgress);
|
||||
|
||||
double start = 0;
|
||||
double end = SnakingIn ? MathHelper.Clamp((Time.Current - (slider.StartTime - slider.TimePreempt)) / slider.TimeFadein, 0, 1) : 1;
|
||||
|
||||
@ -191,11 +194,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
if (Math.Min(span, slider.SpanCount() - 1) % 2 == 1)
|
||||
{
|
||||
start = 0;
|
||||
end = SnakingOut ? progress : 1;
|
||||
end = SnakingOut ? spanProgress : 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
start = SnakingOut ? progress : 0;
|
||||
start = SnakingOut ? spanProgress : 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,10 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
{
|
||||
public interface ISliderProgress
|
||||
{
|
||||
void UpdateProgress(double progress, int span);
|
||||
/// <summary>
|
||||
/// Updates the progress of this <see cref="ISliderProgress"/> element along the slider.
|
||||
/// </summary>
|
||||
/// <param name="completionProgress">Amount of the slider completed.</param>
|
||||
void UpdateProgress(double completionProgress);
|
||||
}
|
||||
}
|
||||
|
@ -66,18 +66,6 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
/// </summary>
|
||||
public double SpanDuration => Duration / this.SpanCount();
|
||||
|
||||
private int stackHeight;
|
||||
|
||||
public override int StackHeight
|
||||
{
|
||||
get { return stackHeight; }
|
||||
set
|
||||
{
|
||||
stackHeight = value;
|
||||
Curve.Offset = StackOffset;
|
||||
}
|
||||
}
|
||||
|
||||
public double Velocity;
|
||||
public double TickDistance;
|
||||
|
||||
|
@ -315,11 +315,11 @@ namespace osu.Game.Rulesets.Osu.Replays
|
||||
|
||||
for (double j = FrameDelay; j < s.Duration; j += FrameDelay)
|
||||
{
|
||||
Vector2 pos = s.PositionAt(j / s.Duration);
|
||||
Vector2 pos = s.StackedPositionAt(j / s.Duration);
|
||||
AddFrameToReplay(new ReplayFrame(h.StartTime + j, pos.X, pos.Y, button));
|
||||
}
|
||||
|
||||
AddFrameToReplay(new ReplayFrame(s.EndTime, s.EndPosition.X, s.EndPosition.Y, button));
|
||||
AddFrameToReplay(new ReplayFrame(s.EndTime, s.StackedEndPosition.X, s.StackedEndPosition.Y, button));
|
||||
}
|
||||
|
||||
// We only want to let go of our button if we are at the end of the current replay. Otherwise something is still going on after us so we need to keep the button pressed!
|
||||
|
@ -88,10 +88,15 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
AddStep("Catmull Slider", () => testCatmull());
|
||||
AddStep("Catmull Slider 1 Repeat", () => testCatmull(1));
|
||||
AddStep("Catmull Slider 2 Repeats", () => testCatmull(2));
|
||||
|
||||
AddStep("Big Single, Large StackOffset", () => testSimpleBigLargeStackOffset());
|
||||
AddStep("Big 1 Repeat, Large StackOffset", () => testSimpleBigLargeStackOffset(1));
|
||||
}
|
||||
|
||||
private void testSimpleBig(int repeats = 0) => createSlider(2, repeats: repeats);
|
||||
|
||||
private void testSimpleBigLargeStackOffset(int repeats = 0) => createSlider(2, repeats: repeats, stackHeight: 10);
|
||||
|
||||
private void testSimpleMedium(int repeats = 0) => createSlider(5, repeats: repeats);
|
||||
|
||||
private void testSimpleSmall(int repeats = 0) => createSlider(7, repeats: repeats);
|
||||
@ -104,7 +109,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
|
||||
private void testShortHighSpeed(int repeats = 0) => createSlider(distance: 100, repeats: repeats, speedMultiplier: 15);
|
||||
|
||||
private void createSlider(float circleSize = 2, float distance = 400, int repeats = 0, double speedMultiplier = 2)
|
||||
private void createSlider(float circleSize = 2, float distance = 400, int repeats = 0, double speedMultiplier = 2, int stackHeight = 0)
|
||||
{
|
||||
var slider = new Slider
|
||||
{
|
||||
@ -118,7 +123,8 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
},
|
||||
Distance = distance,
|
||||
RepeatCount = repeats,
|
||||
RepeatSamples = createEmptySamples(repeats)
|
||||
RepeatSamples = createEmptySamples(repeats),
|
||||
StackHeight = stackHeight
|
||||
};
|
||||
|
||||
addSlider(slider, circleSize, speedMultiplier);
|
||||
|
@ -30,21 +30,19 @@ namespace osu.Game.Rulesets.Objects.Types
|
||||
public static class HasCurveExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Computes the position on the curve at a given progress, accounting for repeat logic.
|
||||
/// <para>
|
||||
/// Ranges from [0, 1] where 0 is the beginning of the curve and 1 is the end of the curve.
|
||||
/// </para>
|
||||
/// Computes the position on the curve relative to how much of the <see cref="HitObject"/> has been completed.
|
||||
/// </summary>
|
||||
/// <param name="obj">The curve.</param>
|
||||
/// <param name="progress">[0, 1] where 0 is the beginning of the curve and 1 is the end of the curve.</param>
|
||||
/// <param name="progress">[0, 1] where 0 is the start time of the <see cref="HitObject"/> and 1 is the end time of the <see cref="HitObject"/>.</param>
|
||||
/// <returns>The position on the curve.</returns>
|
||||
public static Vector2 PositionAt(this IHasCurve obj, double progress)
|
||||
=> obj.Curve.PositionAt(obj.ProgressAt(progress));
|
||||
|
||||
/// <summary>
|
||||
/// Finds the progress along the curve, accounting for repeat logic.
|
||||
/// Computes the progress along the curve relative to how much of the <see cref="HitObject"/> has been completed.
|
||||
/// </summary>
|
||||
/// <param name="obj">The curve.</param>
|
||||
/// <param name="progress">[0, 1] where 0 is the beginning of the curve and 1 is the end of the curve.</param>
|
||||
/// <param name="progress">[0, 1] where 0 is the start time of the <see cref="HitObject"/> and 1 is the end time of the <see cref="HitObject"/>.</param>
|
||||
/// <returns>[0, 1] where 0 is the beginning of the curve and 1 is the end of the curve.</returns>
|
||||
public static double ProgressAt(this IHasCurve obj, double progress)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user