mirror of
https://github.com/ppy/osu.git
synced 2025-01-30 23:23:18 +08:00
Merge pull request #9080 from bdach/sequential-scroll-lifetime-start
Fix display start time in sequential scroll algorithm
This commit is contained in:
commit
10af894b69
@ -29,8 +29,22 @@ namespace osu.Game.Tests.ScrollAlgorithms
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestDisplayStartTime()
|
public void TestDisplayStartTime()
|
||||||
{
|
{
|
||||||
// Sequential scroll algorithm approximates the start time
|
// easy cases - time range adjusted for velocity fits within control point duration
|
||||||
// This should be fixed in the future
|
Assert.AreEqual(2500, algorithm.GetDisplayStartTime(5000, 0, 2500, 1)); // 5000 - (2500 / 1)
|
||||||
|
Assert.AreEqual(13750, algorithm.GetDisplayStartTime(15000, 0, 2500, 1)); // 15000 - (2500 / 2)
|
||||||
|
Assert.AreEqual(20000, algorithm.GetDisplayStartTime(25000, 0, 2500, 1)); // 25000 - (2500 / 0.5)
|
||||||
|
|
||||||
|
// hard case - time range adjusted for velocity exceeds control point duration
|
||||||
|
|
||||||
|
// 1st multiplier point takes 10000 / 2500 = 4 scroll lengths
|
||||||
|
// 2nd multiplier point takes 10000 / (2500 / 2) = 8 scroll lengths
|
||||||
|
// 3rd multiplier point takes 2500 / (2500 * 2) = 0.5 scroll lengths up to hitobject start
|
||||||
|
|
||||||
|
// absolute position of the hitobject = 1000 * (4 + 8 + 0.5) = 12500
|
||||||
|
// minus one scroll length allowance = 12500 - 1000 = 11500 = 11.5 [scroll lengths]
|
||||||
|
// therefore the start time lies within the second multiplier point (because 11.5 < 4 + 8)
|
||||||
|
// its exact time position is = 10000 + 7.5 * (2500 / 2) = 19375
|
||||||
|
Assert.AreEqual(19375, algorithm.GetDisplayStartTime(22500, 0, 2500, 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -16,6 +16,7 @@ using osu.Game.Configuration;
|
|||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.Timing;
|
using osu.Game.Rulesets.Timing;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -77,19 +78,18 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
setUpHitObjects();
|
hitObjectSpawnDelegate?.Cancel();
|
||||||
});
|
});
|
||||||
|
|
||||||
private void setUpHitObjects()
|
private void setUpHitObjects() => AddStep("set up hit objects", () =>
|
||||||
{
|
{
|
||||||
scrollContainers.ForEach(c => c.ControlPoints.Add(new MultiplierControlPoint(0)));
|
scrollContainers.ForEach(c => c.ControlPoints.Add(new MultiplierControlPoint(0)));
|
||||||
|
|
||||||
for (int i = spawn_rate / 2; i <= time_range; i += spawn_rate)
|
for (int i = spawn_rate / 2; i <= time_range; i += spawn_rate)
|
||||||
addHitObject(Time.Current + i);
|
addHitObject(Time.Current + i);
|
||||||
|
|
||||||
hitObjectSpawnDelegate?.Cancel();
|
|
||||||
hitObjectSpawnDelegate = Scheduler.AddDelayed(() => addHitObject(Time.Current + time_range), spawn_rate, true);
|
hitObjectSpawnDelegate = Scheduler.AddDelayed(() => addHitObject(Time.Current + time_range), spawn_rate, true);
|
||||||
}
|
});
|
||||||
|
|
||||||
private IList<MultiplierControlPoint> testControlPoints => new List<MultiplierControlPoint>
|
private IList<MultiplierControlPoint> testControlPoints => new List<MultiplierControlPoint>
|
||||||
{
|
{
|
||||||
@ -101,6 +101,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestScrollAlgorithms()
|
public void TestScrollAlgorithms()
|
||||||
{
|
{
|
||||||
|
setUpHitObjects();
|
||||||
|
|
||||||
AddStep("constant scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Constant));
|
AddStep("constant scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Constant));
|
||||||
AddStep("overlapping scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Overlapping));
|
AddStep("overlapping scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Overlapping));
|
||||||
AddStep("sequential scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Sequential));
|
AddStep("sequential scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Sequential));
|
||||||
@ -113,6 +115,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestConstantScrollLifetime()
|
public void TestConstantScrollLifetime()
|
||||||
{
|
{
|
||||||
|
setUpHitObjects();
|
||||||
|
|
||||||
AddStep("set constant scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Constant));
|
AddStep("set constant scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Constant));
|
||||||
// scroll container time range must be less than the rate of spawning hitobjects
|
// scroll container time range must be less than the rate of spawning hitobjects
|
||||||
// otherwise the hitobjects will spawn already partly visible on screen and look wrong
|
// otherwise the hitobjects will spawn already partly visible on screen and look wrong
|
||||||
@ -122,14 +126,40 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestSequentialScrollLifetime()
|
public void TestSequentialScrollLifetime()
|
||||||
{
|
{
|
||||||
|
setUpHitObjects();
|
||||||
|
|
||||||
AddStep("set sequential scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Sequential));
|
AddStep("set sequential scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Sequential));
|
||||||
AddStep("set time range", () => scrollContainers.ForEach(c => c.TimeRange = time_range / 2.0));
|
AddStep("set time range", () => scrollContainers.ForEach(c => c.TimeRange = time_range / 2.0));
|
||||||
AddStep("add control points", () => addControlPoints(testControlPoints, Time.Current));
|
AddStep("add control points", () => addControlPoints(testControlPoints, Time.Current));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSlowSequentialScroll()
|
||||||
|
{
|
||||||
|
AddStep("set sequential scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Sequential));
|
||||||
|
AddStep("set time range", () => scrollContainers.ForEach(c => c.TimeRange = time_range));
|
||||||
|
AddStep("add control points", () => addControlPoints(
|
||||||
|
new List<MultiplierControlPoint>
|
||||||
|
{
|
||||||
|
new MultiplierControlPoint { Velocity = 0.1 }
|
||||||
|
},
|
||||||
|
Time.Current + time_range));
|
||||||
|
|
||||||
|
// All of the hit objects added below should be immediately visible on screen
|
||||||
|
AddStep("add hit objects", () =>
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 20; ++i)
|
||||||
|
{
|
||||||
|
addHitObject(Time.Current + time_range * (2 + 0.1 * i));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestOverlappingScrollLifetime()
|
public void TestOverlappingScrollLifetime()
|
||||||
{
|
{
|
||||||
|
setUpHitObjects();
|
||||||
|
|
||||||
AddStep("set overlapping scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Overlapping));
|
AddStep("set overlapping scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Overlapping));
|
||||||
AddStep("set time range", () => scrollContainers.ForEach(c => c.TimeRange = time_range / 2.0));
|
AddStep("set time range", () => scrollContainers.ForEach(c => c.TimeRange = time_range / 2.0));
|
||||||
AddStep("add control points", () => addControlPoints(testControlPoints, Time.Current));
|
AddStep("add control points", () => addControlPoints(testControlPoints, Time.Current));
|
||||||
@ -221,7 +251,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
private class TestDrawableControlPoint : DrawableHitObject<HitObject>
|
private class TestDrawableControlPoint : DrawableHitObject<HitObject>
|
||||||
{
|
{
|
||||||
public TestDrawableControlPoint(ScrollingDirection direction, double time)
|
public TestDrawableControlPoint(ScrollingDirection direction, double time)
|
||||||
: base(new HitObject { StartTime = time })
|
: base(new HitObject { StartTime = time, HitWindows = HitWindows.Empty })
|
||||||
{
|
{
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
@ -252,7 +282,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
private class TestDrawableHitObject : DrawableHitObject<HitObject>
|
private class TestDrawableHitObject : DrawableHitObject<HitObject>
|
||||||
{
|
{
|
||||||
public TestDrawableHitObject(double time)
|
public TestDrawableHitObject(double time)
|
||||||
: base(new HitObject { StartTime = time })
|
: base(new HitObject { StartTime = time, HitWindows = HitWindows.Empty })
|
||||||
{
|
{
|
||||||
Origin = Anchor.Custom;
|
Origin = Anchor.Custom;
|
||||||
OriginPosition = new Vector2(75 / 4.0f);
|
OriginPosition = new Vector2(75 / 4.0f);
|
||||||
|
@ -22,8 +22,7 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms
|
|||||||
|
|
||||||
public double GetDisplayStartTime(double originTime, float offset, double timeRange, float scrollLength)
|
public double GetDisplayStartTime(double originTime, float offset, double timeRange, float scrollLength)
|
||||||
{
|
{
|
||||||
double adjustedTime = TimeAt(-offset, originTime, timeRange, scrollLength);
|
return TimeAt(-(scrollLength + offset), originTime, timeRange, scrollLength);
|
||||||
return adjustedTime - timeRange - 1000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetLength(double startTime, double endTime, double timeRange, float scrollLength)
|
public float GetLength(double startTime, double endTime, double timeRange, float scrollLength)
|
||||||
|
Loading…
Reference in New Issue
Block a user