mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 23:07:26 +08:00
Merge pull request #7704 from TheWildTree/fix-follow-circle
Match osu-stable follow circle behaviour and size
This commit is contained in:
commit
d320ba416a
@ -44,6 +44,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
private const double time_during_slide_2 = 3000;
|
private const double time_during_slide_2 = 3000;
|
||||||
private const double time_during_slide_3 = 3500;
|
private const double time_during_slide_3 = 3500;
|
||||||
private const double time_during_slide_4 = 3800;
|
private const double time_during_slide_4 = 3800;
|
||||||
|
private const double time_slider_end = 4000;
|
||||||
|
|
||||||
private List<JudgementResult> judgementResults;
|
private List<JudgementResult> judgementResults;
|
||||||
private bool allJudgedFired;
|
private bool allJudgedFired;
|
||||||
@ -284,6 +285,48 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
AddAssert("Tracking acquired", assertMidSliderJudgements);
|
AddAssert("Tracking acquired", assertMidSliderJudgements);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Scenario:
|
||||||
|
/// - Press a key on the slider head
|
||||||
|
/// - While holding the key, move cursor close to the edge of tracking area
|
||||||
|
/// - Keep the cursor on the edge of tracking area until the slider ends
|
||||||
|
/// Expected Result:
|
||||||
|
/// A passing test case will have the slider track the cursor throughout the whole test.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestTrackingAreaEdge()
|
||||||
|
{
|
||||||
|
performTest(new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start },
|
||||||
|
new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 },
|
||||||
|
new OsuReplayFrame { Position = new Vector2(slider_path_length, OsuHitObject.OBJECT_RADIUS * 1.199f), Actions = { OsuAction.LeftButton }, Time = time_slider_end },
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("Tracking kept", assertGreatJudge);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Scenario:
|
||||||
|
/// - Press a key on the slider head
|
||||||
|
/// - While holding the key, move cursor just outside the tracking area
|
||||||
|
/// - Keep the cursor just outside the tracking area until the slider ends
|
||||||
|
/// Expected Result:
|
||||||
|
/// A passing test case will have the slider drop the tracking on frame 2.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestTrackingAreaOutsideEdge()
|
||||||
|
{
|
||||||
|
performTest(new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start },
|
||||||
|
new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 },
|
||||||
|
new OsuReplayFrame { Position = new Vector2(slider_path_length, OsuHitObject.OBJECT_RADIUS * 1.201f), Actions = { OsuAction.LeftButton }, Time = time_slider_end },
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("Tracking dropped", assertMidSliderJudgementFail);
|
||||||
|
}
|
||||||
|
|
||||||
private bool assertGreatJudge() => judgementResults.Last().Type == HitResult.Great;
|
private bool assertGreatJudge() => judgementResults.Last().Type == HitResult.Great;
|
||||||
|
|
||||||
private bool assertHeadMissTailTracked() => judgementResults[^2].Type == HitResult.Great && judgementResults.First().Type == HitResult.Miss;
|
private bool assertHeadMissTailTracked() => judgementResults[^2].Type == HitResult.Great && judgementResults.First().Type == HitResult.Miss;
|
||||||
@ -294,6 +337,8 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
|
|
||||||
private ScoreAccessibleReplayPlayer currentPlayer;
|
private ScoreAccessibleReplayPlayer currentPlayer;
|
||||||
|
|
||||||
|
private const float slider_path_length = 25;
|
||||||
|
|
||||||
private void performTest(List<ReplayFrame> frames)
|
private void performTest(List<ReplayFrame> frames)
|
||||||
{
|
{
|
||||||
AddStep("load player", () =>
|
AddStep("load player", () =>
|
||||||
@ -309,8 +354,8 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
Path = new SliderPath(PathType.PerfectCurve, new[]
|
Path = new SliderPath(PathType.PerfectCurve, new[]
|
||||||
{
|
{
|
||||||
Vector2.Zero,
|
Vector2.Zero,
|
||||||
new Vector2(25, 0),
|
new Vector2(slider_path_length, 0),
|
||||||
}, 25),
|
}, slider_path_length),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
BeatmapInfo =
|
BeatmapInfo =
|
||||||
|
@ -23,7 +23,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
public Func<OsuAction?> GetInitialHitAction;
|
public Func<OsuAction?> GetInitialHitAction;
|
||||||
|
|
||||||
private readonly Slider slider;
|
private readonly Slider slider;
|
||||||
public readonly Drawable FollowCircle;
|
private readonly Drawable followCircle;
|
||||||
|
private readonly Drawable trackingArea;
|
||||||
private readonly DrawableSlider drawableSlider;
|
private readonly DrawableSlider drawableSlider;
|
||||||
|
|
||||||
public SliderBall(Slider slider, DrawableSlider drawableSlider = null)
|
public SliderBall(Slider slider, DrawableSlider drawableSlider = null)
|
||||||
@ -38,7 +39,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
|
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
FollowCircle = new FollowCircleContainer
|
// This is separate from the visible followcircle to ensure consistent internal tracking area (needed to match osu-stable)
|
||||||
|
trackingArea = new CircularContainer
|
||||||
|
{
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.Both
|
||||||
|
},
|
||||||
|
followCircle = new FollowCircleContainer
|
||||||
{
|
{
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
@ -95,8 +103,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
|
|
||||||
tracking = value;
|
tracking = value;
|
||||||
|
|
||||||
FollowCircle.ScaleTo(tracking ? 2f : 1, 300, Easing.OutQuint);
|
// Tracking area is bigger than the visible followcircle and scales instantly to match osu-stable
|
||||||
FollowCircle.FadeTo(tracking ? 1f : 0, 300, Easing.OutQuint);
|
trackingArea.ScaleTo(tracking ? 2.4f : 1f);
|
||||||
|
followCircle.ScaleTo(tracking ? 2f : 1f, 300, Easing.OutQuint);
|
||||||
|
followCircle.FadeTo(tracking ? 1f : 0, 300, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +159,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
// in valid time range
|
// in valid time range
|
||||||
Time.Current >= slider.StartTime && Time.Current < slider.EndTime &&
|
Time.Current >= slider.StartTime && Time.Current < slider.EndTime &&
|
||||||
// in valid position range
|
// in valid position range
|
||||||
lastScreenSpaceMousePosition.HasValue && FollowCircle.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) &&
|
lastScreenSpaceMousePosition.HasValue && trackingArea.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) &&
|
||||||
// valid action
|
// valid action
|
||||||
(actions?.Any(isValidTrackingAction) ?? false);
|
(actions?.Any(isValidTrackingAction) ?? false);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user