mirror of
https://github.com/osukey/osukey.git
synced 2025-07-02 08:49:59 +09:00
Make sliders respond to control point changes
This commit is contained in:
@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
public class TestCaseSliderSelectionMask : HitObjectSelectionMaskTestCase
|
public class TestCaseSliderSelectionMask : HitObjectSelectionMaskTestCase
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new Type[]
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
{
|
{
|
||||||
typeof(SliderSelectionMask),
|
typeof(SliderSelectionMask),
|
||||||
typeof(SliderCircleSelectionMask),
|
typeof(SliderCircleSelectionMask),
|
||||||
|
@ -72,11 +72,28 @@ namespace osu.Game.Rulesets.Osu.Edit.Masks.SliderMasks.Components
|
|||||||
protected override bool OnDragStart(DragStartEvent e) => true;
|
protected override bool OnDragStart(DragStartEvent e) => true;
|
||||||
|
|
||||||
protected override bool OnDrag(DragEvent e)
|
protected override bool OnDrag(DragEvent e)
|
||||||
|
{
|
||||||
|
if (index == 0)
|
||||||
|
{
|
||||||
|
// Special handling for the head - only the position of the slider changes
|
||||||
|
slider.Position += e.Delta;
|
||||||
|
|
||||||
|
// Since control points are relative to the position of the slider, they all need to be offset backwards by the delta
|
||||||
|
var newControlPoints = slider.ControlPoints.ToArray();
|
||||||
|
for (int i = 1; i < newControlPoints.Length; i++)
|
||||||
|
newControlPoints[i] -= e.Delta;
|
||||||
|
|
||||||
|
slider.ControlPoints = newControlPoints;
|
||||||
|
slider.Curve.Calculate(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
var newControlPoints = slider.ControlPoints.ToArray();
|
var newControlPoints = slider.ControlPoints.ToArray();
|
||||||
newControlPoints[index] += e.Delta;
|
newControlPoints[index] += e.Delta;
|
||||||
|
|
||||||
slider.ControlPoints = newControlPoints;
|
slider.ControlPoints = newControlPoints;
|
||||||
|
slider.Curve.Calculate(true);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Masks.SliderMasks.Components
|
|||||||
|
|
||||||
// Need to cause one update
|
// Need to cause one update
|
||||||
body.UpdateProgress(0);
|
body.UpdateProgress(0);
|
||||||
|
body.Refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Masks.SliderMasks.Components
|
|||||||
{
|
{
|
||||||
this.slider = slider;
|
this.slider = slider;
|
||||||
this.position = position;
|
this.position = position;
|
||||||
|
|
||||||
|
slider.ControlPointsChanged += _ => UpdatePosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdatePosition()
|
protected override void UpdatePosition()
|
||||||
|
@ -85,6 +85,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
}
|
}
|
||||||
|
|
||||||
HitObject.PositionChanged += _ => Position = HitObject.StackedPosition;
|
HitObject.PositionChanged += _ => Position = HitObject.StackedPosition;
|
||||||
|
|
||||||
|
slider.ControlPointsChanged += _ => Body.Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Color4 AccentColour
|
public override Color4 AccentColour
|
||||||
|
@ -16,7 +16,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
{
|
{
|
||||||
this.slider = slider;
|
this.slider = slider;
|
||||||
|
|
||||||
Position = HitObject.Position - slider.Position;
|
h.PositionChanged += _ => updatePosition();
|
||||||
|
slider.ControlPointsChanged += _ => updatePosition();
|
||||||
|
|
||||||
|
updatePosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
@ -33,5 +36,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
public Action<double> OnShake;
|
public Action<double> OnShake;
|
||||||
|
|
||||||
protected override void Shake(double maximumLength) => OnShake?.Invoke(maximumLength);
|
protected override void Shake(double maximumLength) => OnShake?.Invoke(maximumLength);
|
||||||
|
|
||||||
|
private void updatePosition() => Position = HitObject.Position - slider.Position;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
{
|
{
|
||||||
public class DrawableSliderTail : DrawableOsuHitObject, IRequireTracking
|
public class DrawableSliderTail : DrawableOsuHitObject, IRequireTracking
|
||||||
{
|
{
|
||||||
|
private readonly Slider slider;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The judgement text is provided by the <see cref="DrawableSlider"/>.
|
/// The judgement text is provided by the <see cref="DrawableSlider"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -18,6 +20,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
public DrawableSliderTail(Slider slider, SliderTailCircle hitCircle)
|
public DrawableSliderTail(Slider slider, SliderTailCircle hitCircle)
|
||||||
: base(hitCircle)
|
: base(hitCircle)
|
||||||
{
|
{
|
||||||
|
this.slider = slider;
|
||||||
|
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
@ -25,7 +29,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
AlwaysPresent = true;
|
AlwaysPresent = true;
|
||||||
|
|
||||||
Position = HitObject.Position - slider.Position;
|
hitCircle.PositionChanged += _ => updatePosition();
|
||||||
|
slider.ControlPointsChanged += _ => updatePosition();
|
||||||
|
|
||||||
|
updatePosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
||||||
@ -33,5 +40,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
if (!userTriggered && timeOffset >= 0)
|
if (!userTriggered && timeOffset >= 0)
|
||||||
ApplyResult(r => r.Type = Tracking ? HitResult.Great : HitResult.Miss);
|
ApplyResult(r => r.Type = Tracking ? HitResult.Great : HitResult.Miss);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updatePosition() => Position = HitObject.Position - slider.Position;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,15 +45,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
// Generate the entire curve
|
Refresh();
|
||||||
slider.Curve.GetPathToProgress(CurrentCurve, 0, 1);
|
|
||||||
SetVertices(CurrentCurve);
|
|
||||||
|
|
||||||
// The body is sized to the full path size to avoid excessive autosize computations
|
|
||||||
Size = Path.Size;
|
|
||||||
|
|
||||||
snakedPosition = Path.PositionInBoundingBox(Vector2.Zero);
|
|
||||||
snakedPathOffset = Path.PositionInBoundingBox(Path.Vertices[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateProgress(double completionProgress)
|
public void UpdateProgress(double completionProgress)
|
||||||
@ -80,6 +72,27 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
setRange(start, end);
|
setRange(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Refresh()
|
||||||
|
{
|
||||||
|
// Generate the entire curve
|
||||||
|
slider.Curve.GetPathToProgress(CurrentCurve, 0, 1);
|
||||||
|
SetVertices(CurrentCurve);
|
||||||
|
|
||||||
|
// The body is sized to the full path size to avoid excessive autosize computations
|
||||||
|
Size = Path.Size;
|
||||||
|
|
||||||
|
snakedPosition = Path.PositionInBoundingBox(Vector2.Zero);
|
||||||
|
snakedPathOffset = Path.PositionInBoundingBox(Path.Vertices[0]);
|
||||||
|
|
||||||
|
var lastSnakedStart = SnakedStart ?? 0;
|
||||||
|
var lastSnakedEnd = SnakedEnd ?? 0;
|
||||||
|
|
||||||
|
SnakedStart = null;
|
||||||
|
SnakedEnd = null;
|
||||||
|
|
||||||
|
setRange(lastSnakedStart, lastSnakedEnd);
|
||||||
|
}
|
||||||
|
|
||||||
private void setRange(double p0, double p1)
|
private void setRange(double p0, double p1)
|
||||||
{
|
{
|
||||||
if (p0 > p1)
|
if (p0 > p1)
|
||||||
|
@ -64,6 +64,9 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
Curve.ControlPoints = value;
|
Curve.ControlPoints = value;
|
||||||
|
|
||||||
ControlPointsChanged?.Invoke(value);
|
ControlPointsChanged?.Invoke(value);
|
||||||
|
|
||||||
|
if (TailCircle != null)
|
||||||
|
TailCircle.Position = EndPosition;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,10 +124,33 @@ namespace osu.Game.Rulesets.Objects
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Calculate()
|
private void calculateCumulativeLength()
|
||||||
|
{
|
||||||
|
double l = 0;
|
||||||
|
|
||||||
|
cumulativeLength.Clear();
|
||||||
|
cumulativeLength.Add(l);
|
||||||
|
|
||||||
|
for (int i = 0; i < calculatedPath.Count - 1; ++i)
|
||||||
|
{
|
||||||
|
Vector2 diff = calculatedPath[i + 1] - calculatedPath[i];
|
||||||
|
double d = diff.Length;
|
||||||
|
|
||||||
|
l += d;
|
||||||
|
cumulativeLength.Add(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
Distance = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Calculate(bool updateDistance = false)
|
||||||
{
|
{
|
||||||
calculatePath();
|
calculatePath();
|
||||||
|
|
||||||
|
if (!updateDistance)
|
||||||
calculateCumulativeLengthAndTrimPath();
|
calculateCumulativeLengthAndTrimPath();
|
||||||
|
else
|
||||||
|
calculateCumulativeLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int indexOfDistance(double d)
|
private int indexOfDistance(double d)
|
||||||
|
Reference in New Issue
Block a user