diff --git a/osu.Game/Storyboards/CommandLoop.cs b/osu.Game/Storyboards/CommandLoop.cs index b93a04cea1..d8d059aaed 100644 --- a/osu.Game/Storyboards/CommandLoop.cs +++ b/osu.Game/Storyboards/CommandLoop.cs @@ -2,26 +2,28 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Graphics; +using osu.Framework.Graphics.Transforms; namespace osu.Game.Storyboards { public class CommandLoop : CommandTimelineGroup { - private double startTime; - private int loopCount; + public double LoopStartTime; + public int LoopCount; public CommandLoop(double startTime, int loopCount) { - this.startTime = startTime; - this.loopCount = loopCount; + LoopStartTime = startTime; + LoopCount = loopCount; } - public override void ApplyTransforms(Drawable drawable) - { - //base.ApplyTransforms(drawable); - } + public override void ApplyTransforms(Drawable drawable, double offset = 0) + => base.ApplyTransforms(drawable, offset + LoopStartTime); + + protected override void PostProcess(Command command, TransformSequence sequence) + => sequence.Loop(Duration - command.Duration, LoopCount); public override string ToString() - => $"{startTime} x{loopCount}"; + => $"{LoopStartTime} x{LoopCount}"; } } diff --git a/osu.Game/Storyboards/CommandTimeline.cs b/osu.Game/Storyboards/CommandTimeline.cs index 04e165aa38..a533f213fc 100644 --- a/osu.Game/Storyboards/CommandTimeline.cs +++ b/osu.Game/Storyboards/CommandTimeline.cs @@ -10,8 +10,8 @@ namespace osu.Game.Storyboards { public class CommandTimeline : CommandTimeline { - private readonly List commands = new List(); - public IEnumerable Commands => commands.OrderBy(c => c.StartTime); + private readonly List commands = new List(); + public IEnumerable Commands => commands.OrderBy(c => c.StartTime); public bool HasCommands => commands.Count > 0; private Cached startTimeBacking; @@ -19,7 +19,7 @@ namespace osu.Game.Storyboards private Cached endTimeBacking; public double EndTime => endTimeBacking.IsValid ? endTimeBacking : (endTimeBacking.Value = HasCommands ? commands.Max(c => c.EndTime) : double.MaxValue); - + public T StartValue => HasCommands ? commands.OrderBy(c => c.StartTime).First().StartValue : default(T); public T EndValue => HasCommands ? commands.OrderByDescending(c => c.EndTime).First().EndValue : default(T); @@ -28,7 +28,7 @@ namespace osu.Game.Storyboards if (endTime < startTime) return; - commands.Add(new Command { Easing = easing, StartTime = startTime, EndTime = endTime, StartValue = startValue, EndValue = endValue, }); + commands.Add(new TypedCommand { Easing = easing, StartTime = startTime, EndTime = endTime, StartValue = startValue, EndValue = endValue, }); startTimeBacking.Invalidate(); endTimeBacking.Invalidate(); @@ -37,16 +37,16 @@ namespace osu.Game.Storyboards public override string ToString() => $"{commands.Count} command(s)"; - public class Command + public class TypedCommand : Command { - public Easing Easing; - public double StartTime; - public double EndTime; + public Easing Easing { get; set; } + public double StartTime { get; set; } + public double EndTime { get; set; } + public double Duration => EndTime - StartTime; + public T StartValue; public T EndValue; - public double Duration => EndTime - StartTime; - public override string ToString() => $"{StartTime} -> {EndTime}, {StartValue} -> {EndValue} {Easing}"; } @@ -58,4 +58,12 @@ namespace osu.Game.Storyboards double EndTime { get; } bool HasCommands { get; } } + + public interface Command + { + Easing Easing { get; set; } + double StartTime { get; set; } + double EndTime { get; set; } + double Duration { get; } + } } diff --git a/osu.Game/Storyboards/CommandTimelineGroup.cs b/osu.Game/Storyboards/CommandTimelineGroup.cs index cc67c9dd68..109104b120 100644 --- a/osu.Game/Storyboards/CommandTimelineGroup.cs +++ b/osu.Game/Storyboards/CommandTimelineGroup.cs @@ -4,6 +4,7 @@ using OpenTK; using OpenTK.Graphics; using osu.Framework.Graphics; +using osu.Framework.Graphics.Transforms; using osu.Game.Storyboards.Drawables; using System.Collections.Generic; using System.Linq; @@ -40,45 +41,52 @@ namespace osu.Game.Storyboards public double StartTime => Timelines.Where(t => t.HasCommands).Min(t => t.StartTime); public double EndTime => Timelines.Where(t => t.HasCommands).Max(t => t.EndTime); + public double Duration => EndTime - StartTime; public bool HasCommands => Timelines.Any(t => t.HasCommands); - public virtual void ApplyTransforms(Drawable drawable) + public virtual void ApplyTransforms(Drawable drawable, double offset = 0) { if (X.HasCommands) drawable.X = X.StartValue; foreach (var command in X.Commands) - using (drawable.BeginAbsoluteSequence(command.StartTime)) - drawable.MoveToX(command.StartValue) - .MoveToX(command.EndValue, command.Duration, command.Easing); + using (drawable.BeginAbsoluteSequence(offset + command.StartTime)) + PostProcess(command, + drawable.MoveToX(command.StartValue) + .MoveToX(command.EndValue, command.Duration, command.Easing)); if (Y.HasCommands) drawable.Y = Y.StartValue; foreach (var command in Y.Commands) - using (drawable.BeginAbsoluteSequence(command.StartTime)) - drawable.MoveToY(command.StartValue) - .MoveToY(command.EndValue, command.Duration, command.Easing); + using (drawable.BeginAbsoluteSequence(offset + command.StartTime)) + PostProcess(command, + drawable.MoveToY(command.StartValue) + .MoveToY(command.EndValue, command.Duration, command.Easing)); if (Scale.HasCommands) drawable.Scale = Scale.StartValue; foreach (var command in Scale.Commands) - using (drawable.BeginAbsoluteSequence(command.StartTime)) - drawable.ScaleTo(command.StartValue) - .ScaleTo(command.EndValue, command.Duration, command.Easing); + using (drawable.BeginAbsoluteSequence(offset + command.StartTime)) + PostProcess(command, + drawable.ScaleTo(command.StartValue) + .ScaleTo(command.EndValue, command.Duration, command.Easing)); if (Rotation.HasCommands) drawable.Rotation = Rotation.StartValue; foreach (var command in Rotation.Commands) - using (drawable.BeginAbsoluteSequence(command.StartTime)) - drawable.RotateTo(command.StartValue) - .RotateTo(command.EndValue, command.Duration, command.Easing); + using (drawable.BeginAbsoluteSequence(offset + command.StartTime)) + PostProcess(command, + drawable.RotateTo(command.StartValue) + .RotateTo(command.EndValue, command.Duration, command.Easing)); if (Colour.HasCommands) drawable.Colour = Colour.StartValue; foreach (var command in Colour.Commands) - using (drawable.BeginAbsoluteSequence(command.StartTime)) - drawable.FadeColour(command.StartValue) - .FadeColour(command.EndValue, command.Duration, command.Easing); + using (drawable.BeginAbsoluteSequence(offset + command.StartTime)) + PostProcess(command, + drawable.FadeColour(command.StartValue) + .FadeColour(command.EndValue, command.Duration, command.Easing)); if (Alpha.HasCommands) drawable.Alpha = Alpha.StartValue; foreach (var command in Alpha.Commands) - using (drawable.BeginAbsoluteSequence(command.StartTime)) - drawable.FadeTo(command.StartValue) - .FadeTo(command.EndValue, command.Duration, command.Easing); + using (drawable.BeginAbsoluteSequence(offset + command.StartTime)) + PostProcess(command, + drawable.FadeTo(command.StartValue) + .FadeTo(command.EndValue, command.Duration, command.Easing)); if (Additive.HasCommands) drawable.BlendingMode = BlendingMode.Additive; @@ -90,5 +98,9 @@ namespace osu.Game.Storyboards flippable.FlipV = FlipV.HasCommands; } } + + protected virtual void PostProcess(Command command, TransformSequence sequence) + { + } } } diff --git a/osu.Game/Storyboards/Drawables/Storyboard.cs b/osu.Game/Storyboards/Drawables/Storyboard.cs index a5b242357f..45aa063f79 100644 --- a/osu.Game/Storyboards/Drawables/Storyboard.cs +++ b/osu.Game/Storyboards/Drawables/Storyboard.cs @@ -53,7 +53,7 @@ namespace osu.Game.Storyboards.Drawables private void updateLayerVisibility() { foreach (var layer in Children) - layer.Enabled = passing ? layer.Definition.EnabledWhenPassing : layer.Definition.ShowWhenFailing; + layer.Enabled = passing ? layer.Definition.EnabledWhenPassing : layer.Definition.EnabledWhenFailing; } } } diff --git a/osu.Game/Storyboards/LayerDefinition.cs b/osu.Game/Storyboards/LayerDefinition.cs index e632a700f1..871462c3fd 100644 --- a/osu.Game/Storyboards/LayerDefinition.cs +++ b/osu.Game/Storyboards/LayerDefinition.cs @@ -11,11 +11,11 @@ namespace osu.Game.Storyboards public string Name; public int Depth; public bool EnabledWhenPassing = true; - public bool ShowWhenFailing = true; + public bool EnabledWhenFailing = true; private List elements = new List(); public IEnumerable Elements => elements; - + public LayerDefinition(string name, int depth) { Name = name; diff --git a/osu.Game/Storyboards/SpriteDefinition.cs b/osu.Game/Storyboards/SpriteDefinition.cs index 2574e7adb6..b47b6c935e 100644 --- a/osu.Game/Storyboards/SpriteDefinition.cs +++ b/osu.Game/Storyboards/SpriteDefinition.cs @@ -5,6 +5,7 @@ using OpenTK; using osu.Framework.Graphics; using osu.Game.Storyboards.Drawables; using System.Collections.Generic; +using System.Linq; namespace osu.Game.Storyboards { @@ -16,7 +17,7 @@ namespace osu.Game.Storyboards private List loops = new List(); private List triggers = new List(); - + public SpriteDefinition(string path, Anchor origin, Vector2 initialPosition) { Path = path; @@ -41,16 +42,11 @@ namespace osu.Game.Storyboards public virtual Drawable CreateDrawable() => new StoryboardSprite(this); - public override void ApplyTransforms(Drawable target) + public override void ApplyTransforms(Drawable target, double offset = 0) { - base.ApplyTransforms(target); - foreach (var loop in loops) - loop.ApplyTransforms(target); - - // TODO - return; - foreach (var trigger in triggers) - trigger.ApplyTransforms(target); + base.ApplyTransforms(target, offset); + foreach (var loop in loops.OrderBy(l => l.StartTime)) + loop.ApplyTransforms(target, offset); } public override string ToString() diff --git a/osu.Game/Storyboards/StoryboardDefinition.cs b/osu.Game/Storyboards/StoryboardDefinition.cs index 853ebe42dc..e357440bc9 100644 --- a/osu.Game/Storyboards/StoryboardDefinition.cs +++ b/osu.Game/Storyboards/StoryboardDefinition.cs @@ -4,7 +4,6 @@ using osu.Game.Storyboards.Drawables; using System.Collections.Generic; using System.Linq; -using System; namespace osu.Game.Storyboards { @@ -12,12 +11,12 @@ namespace osu.Game.Storyboards { private Dictionary layers = new Dictionary(); public IEnumerable Layers => layers.Values; - + public StoryboardDefinition() { layers.Add("Background", new LayerDefinition("Background", 3)); layers.Add("Fail", new LayerDefinition("Fail", 2) { EnabledWhenPassing = false, }); - layers.Add("Pass", new LayerDefinition("Pass", 1) { ShowWhenFailing = false, }); + layers.Add("Pass", new LayerDefinition("Pass", 1) { EnabledWhenFailing = false, }); layers.Add("Foreground", new LayerDefinition("Foreground", 0)); }