diff --git a/osu-framework b/osu-framework index 3c76bce457..870ae62a35 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 3c76bce45762765b7268f8036da681a788f756b9 +Subproject commit 870ae62a35fc0296009bf6d711922da5b9b5612f diff --git a/osu.Desktop.VisualTests/Tests/TestCaseBeatSyncedContainer.cs b/osu.Desktop.VisualTests/Tests/TestCaseBeatSyncedContainer.cs index 067bf47521..01d7d4ff01 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseBeatSyncedContainer.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseBeatSyncedContainer.cs @@ -58,6 +58,8 @@ namespace osu.Desktop.VisualTests.Tests private readonly InfoString currentBeat; private readonly InfoString beatsPerMinute; private readonly InfoString adjustedBeatLength; + private readonly InfoString timeUntilNextBeat; + private readonly InfoString timeSinceLastBeat; private readonly Box flashLayer; @@ -95,6 +97,8 @@ namespace osu.Desktop.VisualTests.Tests currentBeat = new InfoString(@"Current beat"), beatsPerMinute = new InfoString(@"BPM"), adjustedBeatLength = new InfoString(@"Adjusted beat length"), + timeUntilNextBeat = new InfoString(@"Time until next beat"), + timeSinceLastBeat = new InfoString(@"Time since last beat"), } } } @@ -131,6 +135,8 @@ namespace osu.Desktop.VisualTests.Tests currentBeat.Value = 0; beatsPerMinute.Value = 0; adjustedBeatLength.Value = 0; + timeUntilNextBeat.Value = 0; + timeSinceLastBeat.Value = 0; }; } @@ -151,6 +157,13 @@ namespace osu.Desktop.VisualTests.Tests return (int)Math.Ceiling((getNextTimingPoint(current).Time - current.Time) / current.BeatLength); } + protected override void Update() + { + base.Update(); + timeUntilNextBeat.Value = TimeUntilNextBeat; + timeSinceLastBeat.Value = TimeSinceLastBeat; + } + protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes) { base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes); diff --git a/osu.Desktop.VisualTests/Tests/TestCaseContextMenu.cs b/osu.Desktop.VisualTests/Tests/TestCaseContextMenu.cs index 6c0da885ac..f9dc424153 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseContextMenu.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseContextMenu.cs @@ -7,7 +7,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Transforms; using osu.Framework.Graphics.UserInterface; using osu.Framework.Testing; using osu.Game.Graphics.UserInterface; @@ -21,10 +20,10 @@ namespace osu.Desktop.VisualTests.Tests private const int start_time = 0; private const int duration = 1000; + private readonly Container container; + public TestCaseContextMenu() { - MyContextMenuContainer container; - Add(container = new MyContextMenuContainer { Size = new Vector2(200), @@ -54,43 +53,26 @@ namespace osu.Desktop.VisualTests.Tests } } }); + } - container.Transforms.Add(new TransformPosition + protected override void LoadComplete() + { + base.LoadComplete(); + + using (container.BeginLoopedSequence()) { - StartValue = Vector2.Zero, - EndValue = new Vector2(0, 100), - StartTime = start_time, - EndTime = start_time + duration, - LoopCount = -1, - LoopDelay = duration * 3 - }); - container.Transforms.Add(new TransformPosition - { - StartValue = new Vector2(0, 100), - EndValue = new Vector2(100, 100), - StartTime = start_time + duration, - EndTime = start_time + duration * 2, - LoopCount = -1, - LoopDelay = duration * 3 - }); - container.Transforms.Add(new TransformPosition - { - StartValue = new Vector2(100, 100), - EndValue = new Vector2(100, 0), - StartTime = start_time + duration * 2, - EndTime = start_time + duration * 3, - LoopCount = -1, - LoopDelay = duration * 3 - }); - container.Transforms.Add(new TransformPosition - { - StartValue = new Vector2(100, 0), - EndValue = Vector2.Zero, - StartTime = start_time + duration * 3, - EndTime = start_time + duration * 4, - LoopCount = -1, - LoopDelay = duration * 3 - }); + container.MoveTo(new Vector2(0, 100), duration); + using (container.BeginDelayedSequence(duration)) + { + container.MoveTo(new Vector2(100, 100), duration); + using (container.BeginDelayedSequence(duration)) + { + container.MoveTo(new Vector2(100, 0), duration); + using (container.BeginDelayedSequence(duration)) + container.MoveTo(Vector2.Zero, duration); + } + } + } } private class MyContextMenuContainer : Container, IHasContextMenu diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index ae6585bdb2..3e7d9bd6d7 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -5,18 +5,17 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; -using osu.Framework.Graphics.Transforms; using OpenTK; namespace osu.Game.Rulesets.Catch.Objects.Drawable { internal class DrawableFruit : Sprite { - private readonly CatchBaseHit h; + //private readonly CatchBaseHit h; public DrawableFruit(CatchBaseHit h) { - this.h = h; + //this.h = h; Origin = Anchor.Centre; Scale = new Vector2(0.1f); @@ -29,10 +28,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { Texture = textures.Get(@"Menu/logo"); - const double duration = 0; - - Transforms.Add(new TransformPosition { StartTime = h.StartTime - 200, EndTime = h.StartTime, StartValue = new Vector2(h.Position, -0.1f), EndValue = new Vector2(h.Position, 0.9f) }); - Transforms.Add(new TransformAlpha { StartTime = h.StartTime + duration + 200, EndTime = h.StartTime + duration + 400, StartValue = 1, EndValue = 0 }); + //Transforms.Add(new TransformPosition { StartTime = h.StartTime - 200, EndTime = h.StartTime, StartValue = new Vector2(h.Position, -0.1f), EndValue = new Vector2(h.Position, 0.9f) }); + //Transforms.Add(new TransformAlpha { StartTime = h.StartTime + duration + 200, EndTime = h.StartTime + duration + 400, StartValue = 1, EndValue = 0 }); Expire(true); } } diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index a0c683143c..3feb448752 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -235,7 +235,7 @@ namespace osu.Game.Rulesets.Mania.UI private void transformVisibleTimeRangeTo(double newTimeRange, double duration = 0, EasingTypes easing = EasingTypes.None) { - TransformTo(() => visibleTimeRange.Value, newTimeRange, duration, easing, new TransformTimeSpan()); + TransformTo(newTimeRange, duration, easing, new TransformTimeSpan()); } protected override void Update() @@ -247,7 +247,7 @@ namespace osu.Game.Rulesets.Mania.UI private class TransformTimeSpan : Transform<double, Drawable> { - public override double CurrentValue + public double CurrentValue { get { @@ -259,13 +259,8 @@ namespace osu.Game.Rulesets.Mania.UI } } - public override void Apply(Drawable d) - { - base.Apply(d); - - var p = (ManiaPlayfield)d; - p.visibleTimeRange.Value = (float)CurrentValue; - } + public override void Apply(Drawable d) => ((ManiaPlayfield)d).visibleTimeRange.Value = (float)CurrentValue; + public override void ReadIntoStartValue(Drawable d) => StartValue = ((ManiaPlayfield)d).visibleTimeRange.Value; } } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index 09bfffeefe..75b2dc0a32 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -89,11 +89,15 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { base.UpdateInitialState(); - //sane defaults - ring.Alpha = circle.Alpha = number.Alpha = glow.Alpha = 1; - ApproachCircle.Alpha = 0; - ApproachCircle.Scale = new Vector2(4); - explode.Alpha = 0; + // sane defaults + ring.Show(); + circle.Show(); + number.Show(); + glow.Show(); + + ApproachCircle.Hide(); + ApproachCircle.ScaleTo(new Vector2(4)); + explode.Hide(); } protected override void UpdatePreemptState() @@ -106,43 +110,45 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void UpdateCurrentState(ArmedState state) { - ApproachCircle.FadeOut(); + double duration = ((HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime) - HitObject.StartTime; - double endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime; - double duration = endTime - HitObject.StartTime; - - glow.Delay(duration); - glow.FadeOut(400); + using (glow.BeginDelayedSequence(duration)) + glow.FadeOut(400); switch (state) { case ArmedState.Idle: - Delay(duration + TIME_PREEMPT); - FadeOut(TIME_FADEOUT); + using (BeginDelayedSequence(duration + TIME_PREEMPT)) + FadeOut(TIME_FADEOUT); Expire(true); break; case ArmedState.Miss: + ApproachCircle.FadeOut(50); FadeOut(TIME_FADEOUT / 5); Expire(); break; case ArmedState.Hit: + ApproachCircle.FadeOut(50); + const double flash_in = 40; flash.FadeTo(0.8f, flash_in); - flash.Delay(flash_in); - flash.FadeOut(100); + using (flash.BeginDelayedSequence(flash_in)) + flash.FadeOut(100); explode.FadeIn(flash_in); - Delay(flash_in, true); + using (BeginDelayedSequence(flash_in, true)) + { + //after the flash, we can hide some elements that were behind it + ring.FadeOut(); + circle.FadeOut(); + number.FadeOut(); - //after the flash, we can hide some elements that were behind it - ring.FadeOut(); - circle.FadeOut(); - number.FadeOut(); + FadeOut(800); + ScaleTo(Scale * 1.5f, 400, EasingTypes.OutQuad); + } - FadeOut(800); - ScaleTo(Scale * 1.5f, 400, EasingTypes.OutQuad); Expire(); break; } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index 57a9804330..2711ec1a62 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -17,6 +17,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables : base(hitObject) { AccentColour = HitObject.ComboColour; + Alpha = 0; } protected override OsuJudgement CreateJudgement() => new OsuJudgement { MaxScore = OsuScoreResult.Hit300 }; @@ -25,10 +26,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { Flush(); - UpdateInitialState(); - using (BeginAbsoluteSequence(HitObject.StartTime - TIME_PREEMPT, true)) { + UpdateInitialState(); + UpdatePreemptState(); using (BeginDelayedSequence(TIME_PREEMPT + Judgement.TimeOffset, true)) @@ -36,8 +37,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables } } - protected virtual void UpdateCurrentState(ArmedState state) + protected virtual void UpdateInitialState() { + Hide(); } protected virtual void UpdatePreemptState() @@ -45,9 +47,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables FadeIn(TIME_FADEIN); } - protected virtual void UpdateInitialState() + protected virtual void UpdateCurrentState(ArmedState state) { - Alpha = 0; } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBouncer.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBouncer.cs index 65679dd7d3..a34ff30a43 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBouncer.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBouncer.cs @@ -37,8 +37,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces protected override void LoadComplete() { base.LoadComplete(); - icon.RotateTo(360, 1000); - icon.Loop(); + using (icon.BeginLoopedSequence()) + icon.RotateTo(360, 1000); } public void UpdateProgress(double progress, int repeat) diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 4a6b972f4a..910918297f 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -111,7 +111,7 @@ namespace osu.Game.Tests.Beatmaps.IO return osu; } - private void ensureLoaded(GameHost host, int timeout = 10000) + private void ensureLoaded(GameHost host, int timeout = 60000) { IEnumerable<BeatmapSetInfo> resultSets = null; diff --git a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs index c0defceac0..5d8a5753b0 100644 --- a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs +++ b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs @@ -23,6 +23,16 @@ namespace osu.Game.Graphics.Containers /// </summary> protected double EarlyActivationMilliseconds; + /// <summary> + /// The time in milliseconds until the next beat. + /// </summary> + public double TimeUntilNextBeat { get; private set; } + + /// <summary> + /// The time in milliseconds since the last beat + /// </summary> + public double TimeSinceLastBeat { get; private set; } + protected override void Update() { if (Beatmap.Value?.Track == null) @@ -42,12 +52,16 @@ namespace osu.Game.Graphics.Containers if (currentTrackTime < timingPoint.Time) beatIndex--; + TimeUntilNextBeat = (timingPoint.Time - currentTrackTime) % timingPoint.BeatLength; + if (TimeUntilNextBeat < 0) + TimeUntilNextBeat += timingPoint.BeatLength; + + TimeSinceLastBeat = timingPoint.BeatLength - TimeUntilNextBeat; + if (timingPoint == lastTimingPoint && beatIndex == lastBeat) return; - double offsetFromBeat = (timingPoint.Time - currentTrackTime) % timingPoint.BeatLength; - - using (BeginDelayedSequence(offsetFromBeat, true)) + using (BeginDelayedSequence(-TimeSinceLastBeat, true)) OnNewBeat(beatIndex, timingPoint, effectPoint, Beatmap.Value.Track.CurrentAmplitudes); lastBeat = beatIndex; diff --git a/osu.Game/Graphics/IHasAccentColour.cs b/osu.Game/Graphics/IHasAccentColour.cs index 672c59a935..9eb66d8fac 100644 --- a/osu.Game/Graphics/IHasAccentColour.cs +++ b/osu.Game/Graphics/IHasAccentColour.cs @@ -30,7 +30,7 @@ namespace osu.Game.Graphics public static void FadeAccent<T>(this T accentedDrawable, Color4 newColour, double duration = 0, EasingTypes easing = EasingTypes.None) where T : Transformable<Drawable>, IHasAccentColour { - accentedDrawable.TransformTo(() => accentedDrawable.AccentColour, newColour, duration, easing, new TransformAccent()); + accentedDrawable.TransformTo(newColour, duration, easing, new TransformAccent()); } } } diff --git a/osu.Game/Graphics/Transforms/TransformAccent.cs b/osu.Game/Graphics/Transforms/TransformAccent.cs index d49f969c20..53a452ad8a 100644 --- a/osu.Game/Graphics/Transforms/TransformAccent.cs +++ b/osu.Game/Graphics/Transforms/TransformAccent.cs @@ -13,7 +13,7 @@ namespace osu.Game.Graphics.Transforms /// <summary> /// Current value of the transformed colour in linear colour space. /// </summary> - public override Color4 CurrentValue + public virtual Color4 CurrentValue { get { @@ -25,13 +25,7 @@ namespace osu.Game.Graphics.Transforms } } - public override void Apply(Drawable d) - { - base.Apply(d); - - var accented = d as IHasAccentColour; - if (accented != null) - accented.AccentColour = CurrentValue; - } + public override void Apply(Drawable d) => ((IHasAccentColour)d).AccentColour = CurrentValue; + public override void ReadIntoStartValue(Drawable d) => StartValue = ((IHasAccentColour)d).AccentColour; } } diff --git a/osu.Game/Graphics/UserInterface/LoadingAnimation.cs b/osu.Game/Graphics/UserInterface/LoadingAnimation.cs index 27a888f0b5..eed5061abd 100644 --- a/osu.Game/Graphics/UserInterface/LoadingAnimation.cs +++ b/osu.Game/Graphics/UserInterface/LoadingAnimation.cs @@ -34,9 +34,8 @@ namespace osu.Game.Graphics.UserInterface { base.LoadComplete(); - spinner.RotateTo(360, 2000); - using (spinner.BeginDelayedSequence(2000)) - spinner.Loop(); + using (spinner.BeginLoopedSequence()) + spinner.RotateTo(360, 2000); } private const float transition_duration = 500; diff --git a/osu.Game/Graphics/UserInterface/PercentageCounter.cs b/osu.Game/Graphics/UserInterface/PercentageCounter.cs index 79cdc9effe..b51dd2287b 100644 --- a/osu.Game/Graphics/UserInterface/PercentageCounter.cs +++ b/osu.Game/Graphics/UserInterface/PercentageCounter.cs @@ -47,7 +47,7 @@ namespace osu.Game.Graphics.UserInterface protected class TransformAccuracy : Transform<double, Drawable> { - public override double CurrentValue + public virtual double CurrentValue { get { @@ -59,11 +59,8 @@ namespace osu.Game.Graphics.UserInterface } } - public override void Apply(Drawable d) - { - base.Apply(d); - ((PercentageCounter)d).DisplayedCount = CurrentValue; - } + public override void Apply(Drawable d) => ((PercentageCounter)d).DisplayedCount = CurrentValue; + public override void ReadIntoStartValue(Drawable d) => StartValue = ((PercentageCounter)d).DisplayedCount; } } } diff --git a/osu.Game/Graphics/UserInterface/RollingCounter.cs b/osu.Game/Graphics/UserInterface/RollingCounter.cs index 4338dd23eb..db6e6ff44f 100644 --- a/osu.Game/Graphics/UserInterface/RollingCounter.cs +++ b/osu.Game/Graphics/UserInterface/RollingCounter.cs @@ -210,7 +210,6 @@ namespace osu.Game.Graphics.UserInterface transform.StartTime = TransformStartTime; transform.EndTime = TransformStartTime + rollingTotalDuration; - transform.StartValue = currentValue; transform.EndValue = newValue; transform.Easing = RollingEasing; diff --git a/osu.Game/Graphics/UserInterface/ScoreCounter.cs b/osu.Game/Graphics/UserInterface/ScoreCounter.cs index f98e84852a..6fe43e1fcc 100644 --- a/osu.Game/Graphics/UserInterface/ScoreCounter.cs +++ b/osu.Game/Graphics/UserInterface/ScoreCounter.cs @@ -58,7 +58,7 @@ namespace osu.Game.Graphics.UserInterface protected class TransformScore : Transform<double, Drawable> { - public override double CurrentValue + public virtual double CurrentValue { get { @@ -70,11 +70,8 @@ namespace osu.Game.Graphics.UserInterface } } - public override void Apply(Drawable d) - { - base.Apply(d); - ((ScoreCounter)d).DisplayedCount = CurrentValue; - } + public override void Apply(Drawable d) => ((ScoreCounter)d).DisplayedCount = CurrentValue; + public override void ReadIntoStartValue(Drawable d) => StartValue = ((ScoreCounter)d).DisplayedCount; } } } diff --git a/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs b/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs index bee1a71894..7664eeee40 100644 --- a/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs +++ b/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs @@ -39,7 +39,7 @@ namespace osu.Game.Graphics.UserInterface private class TransformCounterCount : Transform<int, Drawable> { - public override int CurrentValue + public int CurrentValue { get { @@ -51,11 +51,8 @@ namespace osu.Game.Graphics.UserInterface } } - public override void Apply(Drawable d) - { - base.Apply(d); - ((SimpleComboCounter)d).DisplayedCount = CurrentValue; - } + public override void Apply(Drawable d) => ((SimpleComboCounter)d).DisplayedCount = CurrentValue; + public override void ReadIntoStartValue(Drawable d) => StartValue = ((SimpleComboCounter)d).DisplayedCount; } } } \ No newline at end of file diff --git a/osu.Game/Overlays/DragBar.cs b/osu.Game/Overlays/DragBar.cs index 07e0c76396..89bb81c70b 100644 --- a/osu.Game/Overlays/DragBar.cs +++ b/osu.Game/Overlays/DragBar.cs @@ -75,7 +75,7 @@ namespace osu.Game.Overlays private void updatePosition(float position, bool easing = true) { position = MathHelper.Clamp(position, 0, 1); - Fill.TransformTo(() => Fill.Width, position, easing ? 200 : 0, EasingTypes.OutQuint, new TransformSeek()); + Fill.TransformTo(position, easing ? 200 : 0, EasingTypes.OutQuint, new TransformSeek()); } protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) @@ -100,11 +100,8 @@ namespace osu.Game.Overlays private class TransformSeek : TransformFloat<Drawable> { - public override void Apply(Drawable d) - { - base.Apply(d); - d.Width = CurrentValue; - } + public override void Apply(Drawable d) => d.Width = CurrentValue; + public override void ReadIntoStartValue(Drawable d) => StartValue = d.Width; } } } diff --git a/osu.Game/Overlays/Notifications/Notification.cs b/osu.Game/Overlays/Notifications/Notification.cs index 3380c61385..74cced5ee9 100644 --- a/osu.Game/Overlays/Notifications/Notification.cs +++ b/osu.Game/Overlays/Notifications/Notification.cs @@ -7,7 +7,6 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Transforms; using osu.Framework.Input; using osu.Game.Graphics; using OpenTK; @@ -203,6 +202,8 @@ namespace osu.Game.Overlays.Notifications get { return pulsate; } set { + if (pulsate == value) return; + pulsate = value; pulsateLayer.ClearTransforms(); @@ -211,25 +212,12 @@ namespace osu.Game.Overlays.Notifications if (pulsate) { const float length = 1000; - pulsateLayer.Transforms.Add(new TransformAlpha + using (pulsateLayer.BeginLoopedSequence(length / 2)) { - StartTime = Time.Current, - EndTime = Time.Current + length, - StartValue = 1, - EndValue = 0.4f, - Easing = EasingTypes.In - }); - pulsateLayer.Transforms.Add(new TransformAlpha - { - StartTime = Time.Current + length, - EndTime = Time.Current + length * 2, - StartValue = 0.4f, - EndValue = 1, - Easing = EasingTypes.Out - }); - - //todo: figure why we can't add arbitrary delays at the end of loop. - pulsateLayer.Loop(length * 2); + pulsateLayer.FadeTo(0.4f, length, EasingTypes.In); + using (pulsateLayer.BeginDelayedSequence(length)) + pulsateLayer.FadeTo(1, length, EasingTypes.Out); + } } } } diff --git a/osu.Game/Screens/Menu/Button.cs b/osu.Game/Screens/Menu/Button.cs index c8739f8894..8dad83bd0e 100644 --- a/osu.Game/Screens/Menu/Button.cs +++ b/osu.Game/Screens/Menu/Button.cs @@ -9,7 +9,6 @@ using osu.Framework.Audio.Sample; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Transforms; using osu.Framework.Input; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; @@ -17,6 +16,9 @@ using OpenTK; using OpenTK.Graphics; using OpenTK.Input; using osu.Framework.Extensions.Color4Extensions; +using osu.Game.Graphics.Containers; +using osu.Framework.Audio.Track; +using osu.Game.Beatmaps.ControlPoints; namespace osu.Game.Screens.Menu { @@ -24,7 +26,7 @@ namespace osu.Game.Screens.Menu /// Button designed specifically for the osu!next main menu. /// In order to correctly flow, we have to use a negative margin on the parent container (due to the parallelogram shape). /// </summary> - public class Button : Container, IStateful<ButtonState> + public class Button : BeatSyncedContainer, IStateful<ButtonState> { private readonly Container iconText; private readonly Container box; @@ -117,6 +119,27 @@ namespace osu.Game.Screens.Menu }; } + protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes) + { + base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes); + + if (!IsHovered) return; + + bool rightward = beatIndex % 2 == 1; + double duration = timingPoint.BeatLength / 2; + + icon.RotateTo(rightward ? 10 : -10, duration * 2, EasingTypes.InOutSine); + + icon.MoveToY(-10, duration, EasingTypes.Out); + icon.ScaleTo(Vector2.One, duration, EasingTypes.Out); + + using (icon.BeginDelayedSequence(duration)) + { + icon.MoveToY(0, duration, EasingTypes.In); + icon.ScaleTo(new Vector2(1, 0.9f), duration, EasingTypes.In); + } + } + protected override bool OnHover(InputState state) { if (State != ButtonState.Expanded) return true; @@ -125,85 +148,11 @@ namespace osu.Game.Screens.Menu box.ScaleTo(new Vector2(1.5f, 1), 500, EasingTypes.OutElastic); - int duration = 0; //(int)(Game.Audio.BeatLength / 2); - if (duration == 0) duration = 250; + double duration = TimeUntilNextBeat; icon.ClearTransforms(); - - icon.ScaleTo(1, 500, EasingTypes.OutElasticHalf); - - const double offset = 0; //(1 - Game.Audio.SyncBeatProgress) * duration; - double startTime = Time.Current + offset; - - icon.RotateTo(10, offset, EasingTypes.InOutSine); - icon.ScaleTo(new Vector2(1, 0.9f), offset, EasingTypes.Out); - - icon.Transforms.Add(new TransformRotation - { - StartValue = -10, - EndValue = 10, - StartTime = startTime, - EndTime = startTime + duration * 2, - Easing = EasingTypes.InOutSine, - LoopCount = -1, - LoopDelay = duration * 2 - }); - - icon.Transforms.Add(new TransformPosition - { - StartValue = Vector2.Zero, - EndValue = new Vector2(0, -10), - StartTime = startTime, - EndTime = startTime + duration, - Easing = EasingTypes.Out, - LoopCount = -1, - LoopDelay = duration - }); - - icon.Transforms.Add(new TransformScale - { - StartValue = new Vector2(1, 0.9f), - EndValue = Vector2.One, - StartTime = startTime, - EndTime = startTime + duration, - Easing = EasingTypes.Out, - LoopCount = -1, - LoopDelay = duration - }); - - icon.Transforms.Add(new TransformPosition - { - StartValue = new Vector2(0, -10), - EndValue = Vector2.Zero, - StartTime = startTime + duration, - EndTime = startTime + duration * 2, - Easing = EasingTypes.In, - LoopCount = -1, - LoopDelay = duration - }); - - icon.Transforms.Add(new TransformScale - { - StartValue = Vector2.One, - EndValue = new Vector2(1, 0.9f), - StartTime = startTime + duration, - EndTime = startTime + duration * 2, - Easing = EasingTypes.In, - LoopCount = -1, - LoopDelay = duration - }); - - icon.Transforms.Add(new TransformRotation - { - StartValue = 10, - EndValue = -10, - StartTime = startTime + duration * 2, - EndTime = startTime + duration * 4, - Easing = EasingTypes.InOutSine, - LoopCount = -1, - LoopDelay = duration * 2 - }); - + icon.RotateTo(10, duration, EasingTypes.InOutSine); + icon.ScaleTo(new Vector2(1, 0.9f), duration, EasingTypes.Out); return true; } @@ -212,7 +161,6 @@ namespace osu.Game.Screens.Menu icon.ClearTransforms(); icon.RotateTo(0, 500, EasingTypes.Out); icon.MoveTo(Vector2.Zero, 500, EasingTypes.Out); - icon.ScaleTo(0.7f, 500, EasingTypes.OutElasticHalf); icon.ScaleTo(Vector2.One, 200, EasingTypes.Out); if (State == ButtonState.Expanded) diff --git a/osu.Game/Screens/Play/HUD/ComboCounter.cs b/osu.Game/Screens/Play/HUD/ComboCounter.cs index 3793181ecd..f527eaacaf 100644 --- a/osu.Game/Screens/Play/HUD/ComboCounter.cs +++ b/osu.Game/Screens/Play/HUD/ComboCounter.cs @@ -198,7 +198,6 @@ namespace osu.Game.Screens.Play.HUD transform.StartTime = Time.Current; transform.EndTime = Time.Current + getProportionalDuration(currentValue, newValue); - transform.StartValue = currentValue; transform.EndValue = newValue; transform.Easing = RollingEasing; @@ -207,7 +206,7 @@ namespace osu.Game.Screens.Play.HUD protected class TransformComboRoll : Transform<int, Drawable> { - public override int CurrentValue + public virtual int CurrentValue { get { @@ -219,11 +218,8 @@ namespace osu.Game.Screens.Play.HUD } } - public override void Apply(Drawable d) - { - base.Apply(d); - ((ComboCounter)d).DisplayedCount = CurrentValue; - } + public override void Apply(Drawable d) => ((ComboCounter)d).DisplayedCount = CurrentValue; + public override void ReadIntoStartValue(Drawable d) => StartValue = ((ComboCounter)d).DisplayedCount; } protected abstract void OnDisplayedCountRolling(int currentValue, int newValue); diff --git a/osu.Game/Screens/Play/HUD/ComboResultCounter.cs b/osu.Game/Screens/Play/HUD/ComboResultCounter.cs index a4a20c1fd0..c280702390 100644 --- a/osu.Game/Screens/Play/HUD/ComboResultCounter.cs +++ b/osu.Game/Screens/Play/HUD/ComboResultCounter.cs @@ -36,7 +36,7 @@ namespace osu.Game.Screens.Play.HUD protected class TransformComboResult : Transform<ulong, Drawable> { - public override ulong CurrentValue + public virtual ulong CurrentValue { get { @@ -48,11 +48,8 @@ namespace osu.Game.Screens.Play.HUD } } - public override void Apply(Drawable d) - { - base.Apply(d); - ((ComboResultCounter)d).DisplayedCount = CurrentValue; - } + public override void Apply(Drawable d) => ((ComboResultCounter)d).DisplayedCount = CurrentValue; + public override void ReadIntoStartValue(Drawable d) => StartValue = ((ComboResultCounter)d).DisplayedCount; } } } diff --git a/osu.Game/Screens/Tournament/ScrollingTeamContainer.cs b/osu.Game/Screens/Tournament/ScrollingTeamContainer.cs index a7019f1e35..30f109e598 100644 --- a/osu.Game/Screens/Tournament/ScrollingTeamContainer.cs +++ b/osu.Game/Screens/Tournament/ScrollingTeamContainer.cs @@ -297,7 +297,7 @@ namespace osu.Game.Screens.Tournament } } - private void speedTo(float value, double duration = 0, EasingTypes easing = EasingTypes.None) => TransformTo(() => speed, value, duration, easing, new TransformScrollSpeed()); + private void speedTo(float value, double duration = 0, EasingTypes easing = EasingTypes.None) => TransformTo(value, duration, easing, new TransformScrollSpeed()); private enum ScrollState { @@ -310,11 +310,8 @@ namespace osu.Game.Screens.Tournament public class TransformScrollSpeed : TransformFloat<Drawable> { - public override void Apply(Drawable d) - { - base.Apply(d); - ((ScrollingTeamContainer)d).speed = CurrentValue; - } + public override void Apply(Drawable d) => ((ScrollingTeamContainer)d).speed = CurrentValue; + public override void ReadIntoStartValue(Drawable d) => StartValue = ((ScrollingTeamContainer)d).speed; } public class ScrollingTeam : Container