1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-12 17:43:05 +08:00

Fix SPM calculation logic not handling paused clocks (#7253)

Fix SPM calculation logic not handling paused clocks

Co-authored-by: Dean Herbert <pe@ppy.sh>
This commit is contained in:
Dean Herbert 2019-12-18 16:30:18 +09:00 committed by GitHub
commit f150d22eaf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 6 deletions

View File

@ -70,6 +70,21 @@ namespace osu.Game.Rulesets.Osu.Tests
AddAssert("is rotation absolute almost same", () => Precision.AlmostEquals(drawableSpinner.Disc.RotationAbsolute, estimatedRotation, 100)); AddAssert("is rotation absolute almost same", () => Precision.AlmostEquals(drawableSpinner.Disc.RotationAbsolute, estimatedRotation, 100));
} }
[Test]
public void TestSpinPerMinuteOnRewind()
{
double estimatedSpm = 0;
addSeekStep(2500);
AddStep("retrieve spm", () => estimatedSpm = drawableSpinner.SpmCounter.SpinsPerMinute);
addSeekStep(5000);
AddAssert("spm still valid", () => Precision.AlmostEquals(drawableSpinner.SpmCounter.SpinsPerMinute, estimatedSpm, 1.0));
addSeekStep(2500);
AddAssert("spm still valid", () => Precision.AlmostEquals(drawableSpinner.SpmCounter.SpinsPerMinute, estimatedSpm, 1.0));
}
private void addSeekStep(double time) private void addSeekStep(double time)
{ {
AddStep($"seek to {time}", () => track.Seek(time)); AddStep($"seek to {time}", () => track.Seek(time));
@ -84,7 +99,7 @@ namespace osu.Game.Rulesets.Osu.Tests
new Spinner new Spinner
{ {
Position = new Vector2(256, 192), Position = new Vector2(256, 192),
EndTime = 5000, EndTime = 6000,
}, },
// placeholder object to avoid hitting the results screen // placeholder object to avoid hitting the results screen
new HitObject new HitObject

View File

@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
public readonly SpinnerDisc Disc; public readonly SpinnerDisc Disc;
public readonly SpinnerTicks Ticks; public readonly SpinnerTicks Ticks;
private readonly SpinnerSpmCounter spmCounter; public readonly SpinnerSpmCounter SpmCounter;
private readonly Container mainContainer; private readonly Container mainContainer;
@ -110,7 +110,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
}, },
} }
}, },
spmCounter = new SpinnerSpmCounter SpmCounter = new SpinnerSpmCounter
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
@ -177,8 +177,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
protected override void Update() protected override void Update()
{ {
Disc.Tracking = OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false; Disc.Tracking = OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false;
if (!spmCounter.IsPresent && Disc.Tracking) if (!SpmCounter.IsPresent && Disc.Tracking)
spmCounter.FadeIn(HitObject.TimeFadeIn); SpmCounter.FadeIn(HitObject.TimeFadeIn);
base.Update(); base.Update();
} }
@ -189,7 +189,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
circle.Rotation = Disc.Rotation; circle.Rotation = Disc.Rotation;
Ticks.Rotation = Disc.Rotation; Ticks.Rotation = Disc.Rotation;
spmCounter.SetRotation(Disc.RotationAbsolute); SpmCounter.SetRotation(Disc.RotationAbsolute);
float relativeCircleScale = Spinner.Scale * circle.DrawHeight / mainContainer.DrawHeight; float relativeCircleScale = Spinner.Scale * circle.DrawHeight / mainContainer.DrawHeight;
Disc.ScaleTo(relativeCircleScale + (1 - relativeCircleScale) * Progress, 200, Easing.OutQuint); Disc.ScaleTo(relativeCircleScale + (1 - relativeCircleScale) * Progress, 200, Easing.OutQuint);

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.MathUtils;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
@ -62,6 +63,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
public void SetRotation(float currentRotation) public void SetRotation(float currentRotation)
{ {
// Never calculate SPM by same time of record to avoid 0 / 0 = NaN or X / 0 = Infinity result.
if (Precision.AlmostEquals(0, Time.Elapsed))
return;
// If we've gone back in time, it's fine to work with a fresh set of records for now // If we've gone back in time, it's fine to work with a fresh set of records for now
if (records.Count > 0 && Time.Current < records.Last().Time) if (records.Count > 0 && Time.Current < records.Last().Time)
records.Clear(); records.Clear();
@ -71,6 +76,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
var record = records.Peek(); var record = records.Peek();
while (records.Count > 0 && Time.Current - records.Peek().Time > spm_count_duration) while (records.Count > 0 && Time.Current - records.Peek().Time > spm_count_duration)
record = records.Dequeue(); record = records.Dequeue();
SpinsPerMinute = (currentRotation - record.Rotation) / (Time.Current - record.Time) * 1000 * 60 / 360; SpinsPerMinute = (currentRotation - record.Rotation) / (Time.Current - record.Time) * 1000 * 60 / 360;
} }