mirror of
https://github.com/ppy/osu.git
synced 2025-03-21 21:47:20 +08:00
Improve code clarity and allow snaking "away" the beginning of the slider that has already been tracked.
This commit is contained in:
parent
4dbc6ad4d0
commit
a1efd25ac1
@ -1 +1 @@
|
||||
Subproject commit 7ca1719b5cdc8b0a9600abe6472b38a426abedb0
|
||||
Subproject commit 3d9bf098319583fc4fbbab5117702d000ad4fb9b
|
@ -63,16 +63,21 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
|
||||
|
||||
ball.Alpha = Time.Current >= slider.StartTime && Time.Current <= slider.EndTime ? 1 : 0;
|
||||
|
||||
double t = (Time.Current - slider.StartTime) / slider.Duration;
|
||||
if (slider.RepeatCount > 1)
|
||||
{
|
||||
int currentRepeat = (int)(t * slider.RepeatCount);
|
||||
t = (t * slider.RepeatCount) % 1;
|
||||
if (currentRepeat % 2 == 1)
|
||||
t = 1 - t;
|
||||
}
|
||||
double currentProgress = MathHelper.Clamp((Time.Current - slider.StartTime) / slider.Duration, 0, 1);
|
||||
double drawStartProgress = 0;
|
||||
|
||||
ball.Position = slider.Curve.PositionAt(t);
|
||||
int currentRepeat = (int)(currentProgress * slider.RepeatCount);
|
||||
currentProgress = (currentProgress * slider.RepeatCount) % 1;
|
||||
if (currentRepeat % 2 == 1)
|
||||
currentProgress = 1 - currentProgress;
|
||||
|
||||
if (currentRepeat >= slider.RepeatCount - 1)
|
||||
drawStartProgress = currentProgress;
|
||||
|
||||
ball.Position = slider.Curve.PositionAt(currentProgress);
|
||||
|
||||
double drawEndProgress = MathHelper.Clamp((Time.Current - slider.StartTime + TIME_PREEMPT) / TIME_FADEIN, 0, 1);
|
||||
body.SetRange(drawStartProgress, drawEndProgress);
|
||||
}
|
||||
|
||||
protected override void CheckJudgement(bool userTriggered)
|
||||
@ -187,7 +192,8 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
|
||||
private Path path;
|
||||
private BufferedContainer container;
|
||||
|
||||
private double? drawnProgress;
|
||||
private double drawnProgressStart;
|
||||
private double drawnProgressEnd;
|
||||
|
||||
private Slider slider;
|
||||
public Body(Slider s)
|
||||
@ -227,33 +233,37 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
|
||||
path.PathWidth = 32;
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
public void SetRange(double p0, double p1)
|
||||
{
|
||||
base.Update();
|
||||
if (p0 > p1)
|
||||
MathHelper.Swap(ref p0, ref p1);
|
||||
|
||||
if (updateSnaking())
|
||||
if (updateSnaking(p0, p1))
|
||||
{
|
||||
// Autosizing does not give us the desired behaviour here.
|
||||
// We want the container to have the same size as the slider,
|
||||
// and to be positioned such that the slider head is at (0,0).
|
||||
container.Size = path.Size;
|
||||
container.Position = -path.HeadPosition;
|
||||
container.Position = -path.PositionInBoundingBox(slider.Curve.PositionAt(0) - currentCurve[0]);
|
||||
|
||||
container.ForceRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
private bool updateSnaking()
|
||||
private List<Vector2> currentCurve = new List<Vector2>();
|
||||
private bool updateSnaking(double p0, double p1)
|
||||
{
|
||||
double progress = MathHelper.Clamp((Time.Current - slider.StartTime + TIME_PREEMPT) / TIME_FADEIN, 0, 1);
|
||||
if (drawnProgressStart == p0 && drawnProgressEnd == p1) return false;
|
||||
|
||||
if (progress == drawnProgress) return false;
|
||||
drawnProgress = progress;
|
||||
drawnProgressStart = p0;
|
||||
drawnProgressEnd = p1;
|
||||
|
||||
Vector2 startPosition = slider.Curve.PositionAt(0);
|
||||
slider.Curve.GetPathToProgress(currentCurve, p0, p1);
|
||||
|
||||
path.ClearVertices();
|
||||
slider.Curve.FillCurveUntilProgress(p => path.AddVertex(p - startPosition), progress);
|
||||
foreach (Vector2 p in currentCurve)
|
||||
path.AddVertex(p - currentCurve[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -102,17 +102,36 @@ namespace osu.Game.Modes.Osu.Objects
|
||||
return p0 + (p1 - p0) * (float)w;
|
||||
}
|
||||
|
||||
public void FillCurveUntilProgress(Action<Vector2> action, double progress)
|
||||
/// <summary>
|
||||
/// Computes the slider curve until a given progress that ranges from 0 (beginning of the slider)
|
||||
/// to 1 (end of the slider) and stores the generated path in the given list.
|
||||
/// </summary>
|
||||
/// <param name="path">The list to be filled with the computed curve.</param>
|
||||
/// <param name="progress">Ranges from 0 (beginning of the slider) to 1 (end of the slider).</param>
|
||||
public void GetPathToProgress(List<Vector2> path, double p0, double p1)
|
||||
{
|
||||
double d = progressToDistance(progress);
|
||||
double d0 = progressToDistance(p0);
|
||||
double d1 = progressToDistance(p1);
|
||||
|
||||
path.Clear();
|
||||
|
||||
int i = 0;
|
||||
for (; i < calculatedPath.Count && cumulativeLength[i] <= d; ++i)
|
||||
action.Invoke(calculatedPath[i]);
|
||||
for (; i < calculatedPath.Count && cumulativeLength[i] < d0; ++i);
|
||||
|
||||
action.Invoke(interpolateVertices(i, d));
|
||||
path.Add(interpolateVertices(i, d0));
|
||||
|
||||
for (; i < calculatedPath.Count && cumulativeLength[i] <= d1; ++i)
|
||||
path.Add(calculatedPath[i]);
|
||||
|
||||
path.Add(interpolateVertices(i, d1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the position on the slider at a given progress that ranges from 0 (beginning of the slider)
|
||||
/// to 1 (end of the slider).
|
||||
/// </summary>
|
||||
/// <param name="progress">Ranges from 0 (beginning of the slider) to 1 (end of the slider).</param>
|
||||
/// <returns></returns>
|
||||
public Vector2 PositionAt(double progress)
|
||||
{
|
||||
double d = progressToDistance(progress);
|
||||
|
Loading…
x
Reference in New Issue
Block a user