mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 23:12:56 +08:00
Merge pull request #1824 from Shawdooow/approach-rate
Add support for variable approach rate
This commit is contained in:
commit
57d02f9b64
@ -1 +1 @@
|
|||||||
Subproject commit 65947291229541de3eb1aff0e703f6968b07f976
|
Subproject commit a6090d3f6f03eaf9a3f643cf1ef3db96384c62ff
|
@ -5,7 +5,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Beatmaps
|
namespace osu.Game.Rulesets.Osu.Beatmaps
|
||||||
{
|
{
|
||||||
@ -37,7 +36,6 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
private void applyStacking(Beatmap<OsuHitObject> beatmap)
|
private void applyStacking(Beatmap<OsuHitObject> beatmap)
|
||||||
{
|
{
|
||||||
const int stack_distance = 3;
|
const int stack_distance = 3;
|
||||||
float stackThreshold = DrawableOsuHitObject.TIME_PREEMPT * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f;
|
|
||||||
|
|
||||||
// Reset stacking
|
// Reset stacking
|
||||||
for (int i = 0; i <= beatmap.HitObjects.Count - 1; i++)
|
for (int i = 0; i <= beatmap.HitObjects.Count - 1; i++)
|
||||||
@ -58,6 +56,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
double endTime = (stackBaseObject as IHasEndTime)?.EndTime ?? stackBaseObject.StartTime;
|
double endTime = (stackBaseObject as IHasEndTime)?.EndTime ?? stackBaseObject.StartTime;
|
||||||
|
float stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f;
|
||||||
|
|
||||||
if (objectN.StartTime - endTime > stackThreshold)
|
if (objectN.StartTime - endTime > stackThreshold)
|
||||||
//We are no longer within stacking range of the next object.
|
//We are no longer within stacking range of the next object.
|
||||||
@ -100,6 +99,8 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
OsuHitObject objectI = beatmap.HitObjects[i];
|
OsuHitObject objectI = beatmap.HitObjects[i];
|
||||||
if (objectI.StackHeight != 0 || objectI is Spinner) continue;
|
if (objectI.StackHeight != 0 || objectI is Spinner) continue;
|
||||||
|
|
||||||
|
float stackThreshold = objectI.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f;
|
||||||
|
|
||||||
/* If this object is a hitcircle, then we enter this "special" case.
|
/* If this object is a hitcircle, then we enter this "special" case.
|
||||||
* It either ends with a stack of hitcircles only, or a stack of hitcircles that are underneath a slider.
|
* It either ends with a stack of hitcircles only, or a stack of hitcircles that are underneath a slider.
|
||||||
* Any other case is handled by the "is Slider" code below this.
|
* Any other case is handled by the "is Slider" code below this.
|
||||||
|
@ -16,17 +16,15 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public override string Description => @"Play with no approach circles and fading notes for a slight score advantage.";
|
public override string Description => @"Play with no approach circles and fading notes for a slight score advantage.";
|
||||||
public override double ScoreMultiplier => 1.06;
|
public override double ScoreMultiplier => 1.06;
|
||||||
|
|
||||||
private const double fade_in_duration_multiplier = 0.4;
|
private const float fade_in_duration_multiplier = 0.4f;
|
||||||
private const double fade_out_duration_multiplier = 0.3;
|
private const double fade_out_duration_multiplier = 0.3;
|
||||||
|
|
||||||
private float preEmpt => DrawableOsuHitObject.TIME_PREEMPT;
|
|
||||||
|
|
||||||
public void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
public void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
||||||
{
|
{
|
||||||
foreach (var d in drawables.OfType<DrawableOsuHitObject>())
|
foreach (var d in drawables.OfType<DrawableOsuHitObject>())
|
||||||
{
|
{
|
||||||
d.ApplyCustomUpdateState += ApplyHiddenState;
|
d.ApplyCustomUpdateState += ApplyHiddenState;
|
||||||
d.FadeInDuration = preEmpt * fade_in_duration_multiplier;
|
d.HitObject.TimeFadein = d.HitObject.TimePreempt * fade_in_duration_multiplier;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,8 +33,8 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
if (!(drawable is DrawableOsuHitObject d))
|
if (!(drawable is DrawableOsuHitObject d))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var fadeOutStartTime = d.HitObject.StartTime - preEmpt + d.FadeInDuration;
|
var fadeOutStartTime = d.HitObject.StartTime - d.HitObject.TimePreempt + d.HitObject.TimeFadein;
|
||||||
var fadeOutDuration = preEmpt * fade_out_duration_multiplier;
|
var fadeOutDuration = d.HitObject.TimePreempt * fade_out_duration_multiplier;
|
||||||
|
|
||||||
// new duration from completed fade in to end (before fading out)
|
// new duration from completed fade in to end (before fading out)
|
||||||
var longFadeDuration = ((d.HitObject as IHasEndTime)?.EndTime ?? d.HitObject.StartTime) - fadeOutStartTime;
|
var longFadeDuration = ((d.HitObject as IHasEndTime)?.EndTime ?? d.HitObject.StartTime) - fadeOutStartTime;
|
||||||
|
@ -96,12 +96,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
|
|||||||
|
|
||||||
using (fp.BeginAbsoluteSequence(fadeInTime))
|
using (fp.BeginAbsoluteSequence(fadeInTime))
|
||||||
{
|
{
|
||||||
fp.FadeIn(DrawableOsuHitObject.TIME_FADEIN);
|
fp.FadeIn(currHitObject.TimeFadein);
|
||||||
fp.ScaleTo(1, DrawableOsuHitObject.TIME_FADEIN, Easing.Out);
|
fp.ScaleTo(1, currHitObject.TimeFadein, Easing.Out);
|
||||||
|
|
||||||
fp.MoveTo(pointEndPosition, DrawableOsuHitObject.TIME_FADEIN, Easing.Out);
|
fp.MoveTo(pointEndPosition, currHitObject.TimeFadein, Easing.Out);
|
||||||
|
|
||||||
fp.Delay(fadeOutTime - fadeInTime).FadeOut(DrawableOsuHitObject.TIME_FADEIN);
|
fp.Delay(fadeOutTime - fadeInTime).FadeOut(currHitObject.TimeFadein);
|
||||||
}
|
}
|
||||||
|
|
||||||
fp.Expire(true);
|
fp.Expire(true);
|
||||||
|
@ -88,8 +88,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
{
|
{
|
||||||
base.UpdatePreemptState();
|
base.UpdatePreemptState();
|
||||||
|
|
||||||
ApproachCircle.FadeIn(Math.Min(FadeInDuration * 2, TIME_PREEMPT));
|
ApproachCircle.FadeIn(Math.Min(HitObject.TimeFadein * 2, HitObject.TimePreempt));
|
||||||
ApproachCircle.ScaleTo(1.1f, TIME_PREEMPT);
|
ApproachCircle.ScaleTo(1.1f, HitObject.TimePreempt);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateCurrentState(ArmedState state)
|
protected override void UpdateCurrentState(ArmedState state)
|
||||||
@ -99,7 +99,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case ArmedState.Idle:
|
case ArmedState.Idle:
|
||||||
this.Delay(TIME_PREEMPT).FadeOut(500);
|
this.Delay(HitObject.TimePreempt).FadeOut(500);
|
||||||
|
|
||||||
Expire(true);
|
Expire(true);
|
||||||
|
|
||||||
|
@ -10,15 +10,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
{
|
{
|
||||||
public class DrawableOsuHitObject : DrawableHitObject<OsuHitObject>
|
public class DrawableOsuHitObject : DrawableHitObject<OsuHitObject>
|
||||||
{
|
{
|
||||||
public const float TIME_PREEMPT = 600;
|
public override bool IsPresent => base.IsPresent || State.Value == ArmedState.Idle && Time.Current >= HitObject.StartTime - HitObject.TimePreempt;
|
||||||
public const float TIME_FADEIN = 400;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The number of milliseconds used to fade in.
|
|
||||||
/// </summary>
|
|
||||||
public virtual double FadeInDuration { get; set; } = TIME_FADEIN;
|
|
||||||
|
|
||||||
public override bool IsPresent => base.IsPresent || State.Value == ArmedState.Idle && Time.Current >= HitObject.StartTime - TIME_PREEMPT;
|
|
||||||
|
|
||||||
protected DrawableOsuHitObject(OsuHitObject hitObject)
|
protected DrawableOsuHitObject(OsuHitObject hitObject)
|
||||||
: base(hitObject)
|
: base(hitObject)
|
||||||
@ -29,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
protected sealed override void UpdateState(ArmedState state)
|
protected sealed override void UpdateState(ArmedState state)
|
||||||
{
|
{
|
||||||
double transformTime = HitObject.StartTime - TIME_PREEMPT;
|
double transformTime = HitObject.StartTime - HitObject.TimePreempt;
|
||||||
|
|
||||||
base.ApplyTransformsAt(transformTime, true);
|
base.ApplyTransformsAt(transformTime, true);
|
||||||
base.ClearTransformsAfter(transformTime, true);
|
base.ClearTransformsAfter(transformTime, true);
|
||||||
@ -38,12 +30,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
{
|
{
|
||||||
UpdatePreemptState();
|
UpdatePreemptState();
|
||||||
|
|
||||||
using (BeginDelayedSequence(TIME_PREEMPT + (Judgements.FirstOrDefault()?.TimeOffset ?? 0), true))
|
using (BeginDelayedSequence(HitObject.TimePreempt + (Judgements.FirstOrDefault()?.TimeOffset ?? 0), true))
|
||||||
UpdateCurrentState(state);
|
UpdateCurrentState(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void UpdatePreemptState() => this.FadeIn(FadeInDuration);
|
protected virtual void UpdatePreemptState() => this.FadeIn(HitObject.TimeFadein);
|
||||||
|
|
||||||
protected virtual void UpdateCurrentState(ArmedState state)
|
protected virtual void UpdateCurrentState(ArmedState state)
|
||||||
{
|
{
|
||||||
|
@ -58,7 +58,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
Scale = s.Scale,
|
Scale = s.Scale,
|
||||||
ComboColour = s.ComboColour,
|
ComboColour = s.ComboColour,
|
||||||
Samples = s.Samples,
|
Samples = s.Samples,
|
||||||
SampleControlPoint = s.SampleControlPoint
|
SampleControlPoint = s.SampleControlPoint,
|
||||||
|
TimePreempt = s.TimePreempt,
|
||||||
|
TimeFadein = s.TimeFadein
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -71,7 +73,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
foreach (var tick in s.NestedHitObjects.OfType<SliderTick>())
|
foreach (var tick in s.NestedHitObjects.OfType<SliderTick>())
|
||||||
{
|
{
|
||||||
var repeatStartTime = s.StartTime + tick.RepeatIndex * repeatDuration;
|
var repeatStartTime = s.StartTime + tick.RepeatIndex * repeatDuration;
|
||||||
var fadeInTime = repeatStartTime + (tick.StartTime - repeatStartTime) / 2 - (tick.RepeatIndex == 0 ? FadeInDuration : FadeInDuration / 2);
|
var fadeInTime = repeatStartTime + (tick.StartTime - repeatStartTime) / 2 - (tick.RepeatIndex == 0 ? HitObject.TimeFadein : HitObject.TimeFadein / 2);
|
||||||
var fadeOutTime = repeatStartTime + repeatDuration;
|
var fadeOutTime = repeatStartTime + repeatDuration;
|
||||||
|
|
||||||
var drawableTick = new DrawableSliderTick(tick)
|
var drawableTick = new DrawableSliderTick(tick)
|
||||||
@ -88,7 +90,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
foreach (var repeatPoint in s.NestedHitObjects.OfType<RepeatPoint>())
|
foreach (var repeatPoint in s.NestedHitObjects.OfType<RepeatPoint>())
|
||||||
{
|
{
|
||||||
var repeatStartTime = s.StartTime + repeatPoint.RepeatIndex * repeatDuration;
|
var repeatStartTime = s.StartTime + repeatPoint.RepeatIndex * repeatDuration;
|
||||||
var fadeInTime = repeatStartTime + (repeatPoint.StartTime - repeatStartTime) / 2 - (repeatPoint.RepeatIndex == 0 ? FadeInDuration : FadeInDuration / 2);
|
var fadeInTime = repeatStartTime + (repeatPoint.StartTime - repeatStartTime) / 2 - (repeatPoint.RepeatIndex == 0 ? HitObject.TimeFadein : HitObject.TimeFadein / 2);
|
||||||
var fadeOutTime = repeatStartTime + repeatDuration;
|
var fadeOutTime = repeatStartTime + repeatDuration;
|
||||||
|
|
||||||
var drawableRepeatPoint = new DrawableRepeatPoint(repeatPoint, this)
|
var drawableRepeatPoint = new DrawableRepeatPoint(repeatPoint, this)
|
||||||
@ -106,12 +108,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
private int currentRepeat;
|
private int currentRepeat;
|
||||||
public bool Tracking;
|
public bool Tracking;
|
||||||
|
|
||||||
public override double FadeInDuration
|
|
||||||
{
|
|
||||||
get { return base.FadeInDuration; }
|
|
||||||
set { InitialCircle.FadeInDuration = base.FadeInDuration = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
|
@ -167,7 +167,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
{
|
{
|
||||||
Disc.Tracking = OsuActionInputManager.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton);
|
Disc.Tracking = OsuActionInputManager.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton);
|
||||||
if (!spmCounter.IsPresent && Disc.Tracking)
|
if (!spmCounter.IsPresent && Disc.Tracking)
|
||||||
spmCounter.FadeIn(FadeInDuration);
|
spmCounter.FadeIn(HitObject.TimeFadein);
|
||||||
|
|
||||||
base.Update();
|
base.Update();
|
||||||
}
|
}
|
||||||
@ -191,14 +191,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
base.UpdatePreemptState();
|
base.UpdatePreemptState();
|
||||||
|
|
||||||
circleContainer.ScaleTo(Spinner.Scale * 0.3f);
|
circleContainer.ScaleTo(Spinner.Scale * 0.3f);
|
||||||
circleContainer.ScaleTo(Spinner.Scale, TIME_PREEMPT / 1.4f, Easing.OutQuint);
|
circleContainer.ScaleTo(Spinner.Scale, HitObject.TimePreempt / 1.4f, Easing.OutQuint);
|
||||||
|
|
||||||
Disc.RotateTo(-720);
|
Disc.RotateTo(-720);
|
||||||
symbol.RotateTo(-720);
|
symbol.RotateTo(-720);
|
||||||
|
|
||||||
mainContainer
|
mainContainer
|
||||||
.ScaleTo(0)
|
.ScaleTo(0)
|
||||||
.ScaleTo(Spinner.Scale * circle.DrawHeight / DrawHeight * 1.4f, TIME_PREEMPT - 150, Easing.OutQuint)
|
.ScaleTo(Spinner.Scale * circle.DrawHeight / DrawHeight * 1.4f, HitObject.TimePreempt - 150, Easing.OutQuint)
|
||||||
.Then()
|
.Then()
|
||||||
.ScaleTo(1, 500, Easing.OutQuint);
|
.ScaleTo(1, 500, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
public void UpdateProgress(double progress, int repeat)
|
public void UpdateProgress(double progress, int repeat)
|
||||||
{
|
{
|
||||||
double start = 0;
|
double start = 0;
|
||||||
double end = snakingIn ? MathHelper.Clamp((Time.Current - (slider.StartTime - DrawableOsuHitObject.TIME_PREEMPT)) / DrawableOsuHitObject.TIME_FADEIN, 0, 1) : 1;
|
double end = snakingIn ? MathHelper.Clamp((Time.Current - (slider.StartTime - slider.TimePreempt)) / slider.TimeFadein, 0, 1) : 1;
|
||||||
|
|
||||||
if (repeat >= slider.RepeatCount - 1)
|
if (repeat >= slider.RepeatCount - 1)
|
||||||
{
|
{
|
||||||
|
@ -20,6 +20,9 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
private const double hit_window_100 = 80;
|
private const double hit_window_100 = 80;
|
||||||
private const double hit_window_300 = 30;
|
private const double hit_window_300 = 30;
|
||||||
|
|
||||||
|
public float TimePreempt = 600;
|
||||||
|
public float TimeFadein = 400;
|
||||||
|
|
||||||
public Vector2 Position { get; set; }
|
public Vector2 Position { get; set; }
|
||||||
public float X => Position.X;
|
public float X => Position.X;
|
||||||
public float Y => Position.Y;
|
public float Y => Position.Y;
|
||||||
@ -72,6 +75,9 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
{
|
{
|
||||||
base.ApplyDefaultsToSelf(controlPointInfo, difficulty);
|
base.ApplyDefaultsToSelf(controlPointInfo, difficulty);
|
||||||
|
|
||||||
|
TimePreempt = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1800, 1200, 450);
|
||||||
|
TimeFadein = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1200, 800, 300);
|
||||||
|
|
||||||
Scale = (1.0f - 0.7f * (difficulty.CircleSize - 5) / 5) / 2;
|
Scale = (1.0f - 0.7f * (difficulty.CircleSize - 5) / 5) / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ using OpenTK;
|
|||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -133,7 +132,7 @@ namespace osu.Game.Rulesets.Osu.Replays
|
|||||||
// Do some nice easing for cursor movements
|
// Do some nice easing for cursor movements
|
||||||
if (Frames.Count > 0)
|
if (Frames.Count > 0)
|
||||||
{
|
{
|
||||||
moveToHitObject(h.StartTime, startPosition, h.Radius, easing);
|
moveToHitObject(h, startPosition, easing);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add frames to click the hitobject
|
// Add frames to click the hitobject
|
||||||
@ -191,12 +190,12 @@ namespace osu.Game.Rulesets.Osu.Replays
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void moveToHitObject(double targetTime, Vector2 targetPos, double hitObjectRadius, Easing easing)
|
private void moveToHitObject(OsuHitObject h, Vector2 targetPos, Easing easing)
|
||||||
{
|
{
|
||||||
ReplayFrame lastFrame = Frames[Frames.Count - 1];
|
ReplayFrame lastFrame = Frames[Frames.Count - 1];
|
||||||
|
|
||||||
// Wait until Auto could "see and react" to the next note.
|
// Wait until Auto could "see and react" to the next note.
|
||||||
double waitTime = targetTime - Math.Max(0.0, DrawableOsuHitObject.TIME_PREEMPT - reactionTime);
|
double waitTime = h.StartTime - Math.Max(0.0, h.TimePreempt - reactionTime);
|
||||||
if (waitTime > lastFrame.Time)
|
if (waitTime > lastFrame.Time)
|
||||||
{
|
{
|
||||||
lastFrame = new ReplayFrame(waitTime, lastFrame.MouseX, lastFrame.MouseY, lastFrame.ButtonState);
|
lastFrame = new ReplayFrame(waitTime, lastFrame.MouseX, lastFrame.MouseY, lastFrame.ButtonState);
|
||||||
@ -205,17 +204,17 @@ namespace osu.Game.Rulesets.Osu.Replays
|
|||||||
|
|
||||||
Vector2 lastPosition = lastFrame.Position;
|
Vector2 lastPosition = lastFrame.Position;
|
||||||
|
|
||||||
double timeDifference = ApplyModsToTime(targetTime - lastFrame.Time);
|
double timeDifference = ApplyModsToTime(h.StartTime - lastFrame.Time);
|
||||||
|
|
||||||
// Only "snap" to hitcircles if they are far enough apart. As the time between hitcircles gets shorter the snapping threshold goes up.
|
// Only "snap" to hitcircles if they are far enough apart. As the time between hitcircles gets shorter the snapping threshold goes up.
|
||||||
if (timeDifference > 0 && // Sanity checks
|
if (timeDifference > 0 && // Sanity checks
|
||||||
((lastPosition - targetPos).Length > hitObjectRadius * (1.5 + 100.0 / timeDifference) || // Either the distance is big enough
|
((lastPosition - targetPos).Length > h.Radius * (1.5 + 100.0 / timeDifference) || // Either the distance is big enough
|
||||||
timeDifference >= 266)) // ... or the beats are slow enough to tap anyway.
|
timeDifference >= 266)) // ... or the beats are slow enough to tap anyway.
|
||||||
{
|
{
|
||||||
// Perform eased movement
|
// Perform eased movement
|
||||||
for (double time = lastFrame.Time + FrameDelay; time < targetTime; time += FrameDelay)
|
for (double time = lastFrame.Time + FrameDelay; time < h.StartTime; time += FrameDelay)
|
||||||
{
|
{
|
||||||
Vector2 currentPosition = Interpolation.ValueAt(time, lastPosition, targetPos, lastFrame.Time, targetTime, easing);
|
Vector2 currentPosition = Interpolation.ValueAt(time, lastPosition, targetPos, lastFrame.Time, h.StartTime, easing);
|
||||||
AddFrameToReplay(new ReplayFrame((int)time, currentPosition.X, currentPosition.Y, lastFrame.ButtonState));
|
AddFrameToReplay(new ReplayFrame((int)time, currentPosition.X, currentPosition.Y, lastFrame.ButtonState));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user