1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-13 08:32:57 +08:00

An attempt at implementing storyboard loops.

This commit is contained in:
Damnae 2017-09-08 12:11:57 +02:00
parent 13322b4293
commit e02b481c69
7 changed files with 71 additions and 54 deletions

View File

@ -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<Drawable> sequence)
=> sequence.Loop(Duration - command.Duration, LoopCount);
public override string ToString()
=> $"{startTime} x{loopCount}";
=> $"{LoopStartTime} x{LoopCount}";
}
}

View File

@ -10,8 +10,8 @@ namespace osu.Game.Storyboards
{
public class CommandTimeline<T> : CommandTimeline
{
private readonly List<Command> commands = new List<Command>();
public IEnumerable<Command> Commands => commands.OrderBy(c => c.StartTime);
private readonly List<TypedCommand> commands = new List<TypedCommand>();
public IEnumerable<TypedCommand> Commands => commands.OrderBy(c => c.StartTime);
public bool HasCommands => commands.Count > 0;
private Cached<double> startTimeBacking;
@ -19,7 +19,7 @@ namespace osu.Game.Storyboards
private Cached<double> 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; }
}
}

View File

@ -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<Drawable> sequence)
{
}
}
}

View File

@ -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;
}
}
}

View File

@ -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<ElementDefinition> elements = new List<ElementDefinition>();
public IEnumerable<ElementDefinition> Elements => elements;
public LayerDefinition(string name, int depth)
{
Name = name;

View File

@ -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<CommandLoop> loops = new List<CommandLoop>();
private List<CommandTrigger> triggers = new List<CommandTrigger>();
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()

View File

@ -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<string, LayerDefinition> layers = new Dictionary<string, LayerDefinition>();
public IEnumerable<LayerDefinition> 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));
}