diff --git a/osu.Android.props b/osu.Android.props index b147fdd05b..6db4220fad 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs index 7e530ca047..8bb324d02e 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections /// /// A single follow point positioned between two adjacent s. /// - public class FollowPoint : Container + public class FollowPoint : Container, IAnimationTimeReference { private const float width = 8; @@ -45,5 +45,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections } }, confineMode: ConfineMode.NoScaling); } + + public double AnimationStartTime { get; set; } } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs index d0935e46f7..6f09bbcd57 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs @@ -116,6 +116,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections int point = 0; + ClearInternal(); + for (int d = (int)(spacing * 1.5); d < distance - spacing; d += spacing) { float fraction = (float)d / distance; @@ -126,13 +128,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections FollowPoint fp; - if (InternalChildren.Count > point) - { - fp = (FollowPoint)InternalChildren[point]; - fp.ClearTransforms(); - } - else - AddInternal(fp = new FollowPoint()); + AddInternal(fp = new FollowPoint()); fp.Position = pointStartPosition; fp.Rotation = rotation; @@ -142,6 +138,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections if (firstTransformStartTime == null) firstTransformStartTime = fadeInTime; + fp.AnimationStartTime = fadeInTime; + using (fp.BeginAbsoluteSequence(fadeInTime)) { fp.FadeIn(osuEnd.TimeFadeIn); diff --git a/osu.Game/Skinning/IAnimationTimeReference.cs b/osu.Game/Skinning/IAnimationTimeReference.cs new file mode 100644 index 0000000000..bcff10a24b --- /dev/null +++ b/osu.Game/Skinning/IAnimationTimeReference.cs @@ -0,0 +1,25 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Timing; + +namespace osu.Game.Skinning +{ + /// + /// Denotes an object which provides a reference time to start animations from. + /// + [Cached] + public interface IAnimationTimeReference + { + /// + /// The reference clock. + /// + IFrameBasedClock Clock { get; } + + /// + /// The time which animations should be started from, relative to . + /// + double AnimationStartTime { get; } + } +} diff --git a/osu.Game/Skinning/LegacySkinExtensions.cs b/osu.Game/Skinning/LegacySkinExtensions.cs index 52328d43b2..8765b161d4 100644 --- a/osu.Game/Skinning/LegacySkinExtensions.cs +++ b/osu.Game/Skinning/LegacySkinExtensions.cs @@ -3,10 +3,12 @@ using System.Collections.Generic; using System.Linq; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; +using osu.Framework.Timing; namespace osu.Game.Skinning { @@ -22,7 +24,7 @@ namespace osu.Game.Skinning if (textures.Length > 0) { - var animation = new TextureAnimation + var animation = new SkinnableTextureAnimation { DefaultFrameLength = getFrameLength(source, applyConfigFrameRate, textures), Repeat = looping, @@ -53,6 +55,25 @@ namespace osu.Game.Skinning } } + public class SkinnableTextureAnimation : TextureAnimation + { + [Resolved(canBeNull: true)] + private IAnimationTimeReference timeReference { get; set; } + + public SkinnableTextureAnimation() + : base(false) + { + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + if (timeReference != null) + Clock = new FramedOffsetClock(timeReference.Clock) { Offset = -timeReference.AnimationStartTime }; + } + } + private const double default_frame_time = 1000 / 60d; private static double getFrameLength(ISkin source, bool applyConfigFrameRate, Texture[] textures) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 781c566b5f..4163044273 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -23,7 +23,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index a2c6106931..17430e4b25 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -71,7 +71,7 @@ - + @@ -79,7 +79,7 @@ - +