1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-14 02:03:22 +08:00

Move snapping logic into SnapFinder

This commit is contained in:
Justus Franklin Tumacder 2021-04-24 20:54:05 +08:00
parent 91bf0d422d
commit 3103fd8343
3 changed files with 83 additions and 67 deletions

View File

@ -7,12 +7,9 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Input.Bindings;
using osu.Framework.Utils;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Skinning.Default;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Mania.Utils;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI.Scrolling;
using osu.Game.Screens.Edit;
@ -31,8 +28,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
[Resolved]
private Bindable<bool> configColourCode { get; set; }
[Resolved(canBeNull: true)]
private ManiaBeatmap beatmap { get; set; }
[Resolved]
private SnapFinder snapFinder { get; set; }
protected virtual ManiaSkinComponents Component => ManiaSkinComponents.Note;
@ -63,7 +60,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
{
base.LoadComplete();
HitObject.StartTimeBindable.BindValueChanged(_ => SnapToBeatmap(), true);
HitObject.StartTimeBindable.BindValueChanged(_ => Snap = snapFinder.FindSnap(HitObject), true);
SnapBindable.BindValueChanged(snap => UpdateSnapColour(configColourCode.Value, snap.NewValue), true);
configColourCode.BindValueChanged(colourCode => UpdateSnapColour(colourCode.NewValue, Snap));
@ -108,63 +105,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
public virtual void OnReleased(ManiaAction action)
{
}
private void SnapToBeatmap()
{
if (beatmap != null)
{
TimingControlPoint currentTimingPoint = beatmap.ControlPointInfo.TimingPointAt(HitObject.StartTime);
int timeSignature = (int)currentTimingPoint.TimeSignature;
double startTime = currentTimingPoint.Time;
double secondsPerFourCounts = currentTimingPoint.BeatLength * 4;
double offset = startTime % secondsPerFourCounts;
double snapResult = HitObject.StartTime % secondsPerFourCounts - offset;
if (AlmostDivisibleBy(snapResult, secondsPerFourCounts / 4.0))
{
Snap = 1;
}
else if (AlmostDivisibleBy(snapResult, secondsPerFourCounts / 8.0))
{
Snap = 2;
}
else if (AlmostDivisibleBy(snapResult, secondsPerFourCounts / 12.0))
{
Snap = 3;
}
else if (AlmostDivisibleBy(snapResult, secondsPerFourCounts / 16.0))
{
Snap = 4;
}
else if (AlmostDivisibleBy(snapResult, secondsPerFourCounts / 24.0))
{
Snap = 6;
}
else if (AlmostDivisibleBy(snapResult, secondsPerFourCounts / 32.0))
{
Snap = 8;
}
else if (AlmostDivisibleBy(snapResult, secondsPerFourCounts / 48.0))
{
Snap = 12;
}
else if (AlmostDivisibleBy(snapResult, secondsPerFourCounts / 64.0))
{
Snap = 16;
}
else
{
Snap = 0;
}
}
}
private const double LENIENCY_MS = 1.0;
private static bool AlmostDivisibleBy(double dividend, double divisor)
{
double remainder = Math.Abs(dividend) % divisor;
return Precision.AlmostEquals(remainder, 0, LENIENCY_MS) || Precision.AlmostEquals(remainder - divisor, 0, LENIENCY_MS);
}
private void UpdateSnapColour(bool colourCode, int snap)
{

View File

@ -20,6 +20,7 @@ using osu.Game.Rulesets.Mania.Configuration;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Mania.Replays;
using osu.Game.Rulesets.Mania.Utils;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
@ -45,8 +46,8 @@ namespace osu.Game.Rulesets.Mania.UI
public new ManiaBeatmap Beatmap => (ManiaBeatmap)base.Beatmap;
[Cached(typeof(ManiaBeatmap))]
private ManiaBeatmap CachedBeatmap { get; }
[Cached]
private SnapFinder snapFinder { get; set; }
public IEnumerable<BarLine> BarLines;
@ -84,7 +85,7 @@ namespace osu.Game.Rulesets.Mania.UI
{
BarLines = new BarLineGenerator<BarLine>(Beatmap).BarLines;
CachedBeatmap = Beatmap;
snapFinder = new SnapFinder(Beatmap);
}
[BackgroundDependencyLoader]

View File

@ -0,0 +1,75 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Utils;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Objects;
namespace osu.Game.Rulesets.Mania.Utils
{
public class SnapFinder
{
private ManiaBeatmap beatmap;
public SnapFinder(ManiaBeatmap beatmap)
{
this.beatmap = beatmap;
}
public int FindSnap(HitObject hitObject)
{
TimingControlPoint currentTimingPoint = beatmap.ControlPointInfo.TimingPointAt(hitObject.StartTime);
int timeSignature = (int)currentTimingPoint.TimeSignature;
double startTime = currentTimingPoint.Time;
double secondsPerFourCounts = currentTimingPoint.BeatLength * 4;
double offset = startTime % secondsPerFourCounts;
double snapResult = hitObject.StartTime % secondsPerFourCounts - offset;
if (AlmostDivisibleBy(snapResult, secondsPerFourCounts / 4.0))
{
return 1;
}
else if (AlmostDivisibleBy(snapResult, secondsPerFourCounts / 8.0))
{
return 2;
}
else if (AlmostDivisibleBy(snapResult, secondsPerFourCounts / 12.0))
{
return 3;
}
else if (AlmostDivisibleBy(snapResult, secondsPerFourCounts / 16.0))
{
return 4;
}
else if (AlmostDivisibleBy(snapResult, secondsPerFourCounts / 24.0))
{
return 6;
}
else if (AlmostDivisibleBy(snapResult, secondsPerFourCounts / 32.0))
{
return 8;
}
else if (AlmostDivisibleBy(snapResult, secondsPerFourCounts / 48.0))
{
return 12;
}
else if (AlmostDivisibleBy(snapResult, secondsPerFourCounts / 64.0))
{
return 16;
}
else
{
return 0;
}
}
private const double LENIENCY_MS = 1.0;
private static bool AlmostDivisibleBy(double dividend, double divisor)
{
double remainder = Math.Abs(dividend) % divisor;
return Precision.AlmostEquals(remainder, 0, LENIENCY_MS) || Precision.AlmostEquals(remainder - divisor, 0, LENIENCY_MS);
}
}
}