diff --git a/osu.Desktop.VisualTests/Tests/TestCaseContextMenu.cs b/osu.Desktop.VisualTests/Tests/TestCaseContextMenu.cs
index 6c0da885ac..c46aacc91a 100644
--- a/osu.Desktop.VisualTests/Tests/TestCaseContextMenu.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCaseContextMenu.cs
@@ -21,10 +21,10 @@ namespace osu.Desktop.VisualTests.Tests
private const int start_time = 0;
private const int duration = 1000;
+ private Container container;
+
public TestCaseContextMenu()
{
- MyContextMenuContainer container;
-
Add(container = new MyContextMenuContainer
{
Size = new Vector2(200),
@@ -54,43 +54,26 @@ namespace osu.Desktop.VisualTests.Tests
}
}
});
+ }
- container.Transforms.Add(new TransformPosition
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ using (container.BeginLoopedSequece())
{
- 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.Desktop.VisualTests/Tests/TestCaseNotificationManager.cs b/osu.Desktop.VisualTests/Tests/TestCaseNotificationManager.cs
index 4ba50c8220..bb2aa9ab0f 100644
--- a/osu.Desktop.VisualTests/Tests/TestCaseNotificationManager.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCaseNotificationManager.cs
@@ -34,7 +34,7 @@ namespace osu.Desktop.VisualTests.Tests
AddStep(@"simple #2", sendNotification2);
AddStep(@"progress #1", sendProgress1);
AddStep(@"progress #2", sendProgress2);
- AddStep(@"barrage", () => sendBarrage());
+ //AddStep(@"barrage", () => sendBarrage());
}
private void sendBarrage(int remaining = 100)
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBouncer.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBouncer.cs
index 65679dd7d3..12d8193641 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.BeginLoopedSequece())
+ icon.RotateTo(360, 1000);
}
public void UpdateProgress(double progress, int repeat)
diff --git a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs
index c0defceac0..68b7637e10 100644
--- a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs
+++ b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs
@@ -23,6 +23,11 @@ namespace osu.Game.Graphics.Containers
///
protected double EarlyActivationMilliseconds;
+ ///
+ /// The time in milliseconds until the next beat.
+ ///
+ public double TimeUntilNextBeat { get; private set; }
+
protected override void Update()
{
if (Beatmap.Value?.Track == null)
@@ -42,12 +47,12 @@ namespace osu.Game.Graphics.Containers
if (currentTrackTime < timingPoint.Time)
beatIndex--;
+ TimeUntilNextBeat = (timingPoint.Time - currentTrackTime) % timingPoint.BeatLength;
+
if (timingPoint == lastTimingPoint && beatIndex == lastBeat)
return;
- double offsetFromBeat = (timingPoint.Time - currentTrackTime) % timingPoint.BeatLength;
-
- using (BeginDelayedSequence(offsetFromBeat, true))
+ using (BeginDelayedSequence(TimeUntilNextBeat, true))
OnNewBeat(beatIndex, timingPoint, effectPoint, Beatmap.Value.Track.CurrentAmplitudes);
lastBeat = beatIndex;
diff --git a/osu.Game/Graphics/UserInterface/LoadingAnimation.cs b/osu.Game/Graphics/UserInterface/LoadingAnimation.cs
index 27a888f0b5..59e08ba004 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.BeginLoopedSequece())
+ spinner.RotateTo(360, 2000);
}
private const float transition_duration = 500;
diff --git a/osu.Game/Overlays/Notifications/Notification.cs b/osu.Game/Overlays/Notifications/Notification.cs
index 3380c61385..2a9297c443 100644
--- a/osu.Game/Overlays/Notifications/Notification.cs
+++ b/osu.Game/Overlays/Notifications/Notification.cs
@@ -203,6 +203,8 @@ namespace osu.Game.Overlays.Notifications
get { return pulsate; }
set
{
+ if (pulsate == value) return;
+
pulsate = value;
pulsateLayer.ClearTransforms();
@@ -211,25 +213,12 @@ namespace osu.Game.Overlays.Notifications
if (pulsate)
{
const float length = 1000;
- pulsateLayer.Transforms.Add(new TransformAlpha
+ using (pulsateLayer.BeginLoopedSequece(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).
///
- public class Button : Container, IStateful
+ public class Button : BeatSyncedContainer, IStateful
{
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)