// Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE namespace osu.Game.Rulesets.Mania.Timing.Drawables { public class DrawableGravityTimingChange : DrawableTimingChange { public DrawableGravityTimingChange(TimingChange timingChange) : base(timingChange) { } protected override void Update() { base.Update(); // The gravity-adjusted start position float startY = (float)computeGravityTime(TimingChange.Time); // The gravity-adjusted end position float endY = (float)computeGravityTime(TimingChange.Time + Content.RelativeCoordinateSpace.Y); Content.Y = startY; Content.Height = endY - startY; } /// /// Applies gravity to a time value based on the current time. /// /// The time value gravity should be applied to. /// The time after gravity is applied to . private double computeGravityTime(double time) { double relativeTime = relativeTimeAt(time); // The sign of the relative time, this is used to apply backwards acceleration leading into startTime double sign = relativeTime < 0 ? -1 : 1; return timeSpan - acceleration * relativeTime * relativeTime * sign; } /// /// The time spanned by this container. /// private double timeSpan => RelativeCoordinateSpace.Y; /// /// The acceleration due to "gravity" of the content of this container. /// private double acceleration => timeSpan / travelTime / travelTime; /// /// The travel time, after beat length adjustments. /// private double travelTime => timeSpan / TimingChange.SpeedMultiplier; /// /// Computes the current time relative to , accounting for . /// /// The non-offset time. /// The current time relative to - . private double relativeTimeAt(double time) => Time.Current - time + travelTime; } }