// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osuTK; using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.UI { /// /// Represents a component responsible for displaying /// the appropriate catcher trails when requested to. /// public class CatcherTrailDisplay : CompositeDrawable { private readonly Catcher catcher; private readonly Container dashTrails; private readonly Container hyperDashTrails; private readonly Container endGlowSprites; private Color4 hyperDashTrailsColour; public Color4 HyperDashTrailsColour { get => hyperDashTrailsColour; set { if (hyperDashTrailsColour == value) return; hyperDashTrailsColour = value; hyperDashTrails.FadeColour(hyperDashTrailsColour, Catcher.HYPER_DASH_TRANSITION_DURATION, Easing.OutQuint); } } private Color4 endGlowSpritesColour; public Color4 EndGlowSpritesColour { get => endGlowSpritesColour; set { if (endGlowSpritesColour == value) return; endGlowSpritesColour = value; endGlowSprites.FadeColour(endGlowSpritesColour, Catcher.HYPER_DASH_TRANSITION_DURATION, Easing.OutQuint); } } private bool trail; /// /// Whether to start displaying trails following the catcher. /// public bool DisplayTrail { get => trail; set { if (trail == value) return; trail = value; if (trail) displayTrail(); } } public CatcherTrailDisplay(Catcher catcher) { this.catcher = catcher ?? throw new ArgumentNullException(nameof(catcher)); RelativeSizeAxes = Axes.Both; InternalChildren = new[] { dashTrails = new Container { RelativeSizeAxes = Axes.Both }, hyperDashTrails = new Container { RelativeSizeAxes = Axes.Both, Colour = Catcher.DEFAULT_HYPER_DASH_COLOUR }, endGlowSprites = new Container { RelativeSizeAxes = Axes.Both, Colour = Catcher.DEFAULT_HYPER_DASH_COLOUR }, }; } /// /// Displays a single end-glow catcher sprite. /// public void DisplayEndGlow() { var endGlow = createTrailSprite(endGlowSprites); endGlow.MoveToOffset(new Vector2(0, -10), 1200, Easing.In); endGlow.ScaleTo(endGlow.Scale * 0.95f).ScaleTo(endGlow.Scale * 1.2f, 1200, Easing.In); endGlow.FadeOut(1200); endGlow.Expire(true); } private void displayTrail() { if (!catcher.Dashing && !catcher.HyperDashing) { DisplayTrail = false; return; } var sprite = createTrailSprite(catcher.HyperDashing ? hyperDashTrails : dashTrails); sprite.FadeTo(0.4f).FadeOut(800, Easing.OutQuint); sprite.Expire(true); Scheduler.AddDelayed(displayTrail, catcher.HyperDashing ? 25 : 50); } private CatcherTrailSprite createTrailSprite(Container target) { var texture = (catcher.CurrentDrawableCatcher as TextureAnimation)?.CurrentFrame ?? ((Sprite)catcher.CurrentDrawableCatcher).Texture; var sprite = new CatcherTrailSprite(texture) { Anchor = catcher.Anchor, Scale = catcher.Scale, Blending = BlendingParameters.Additive, RelativePositionAxes = catcher.RelativePositionAxes, Position = catcher.Position }; target.Add(sprite); return sprite; } } }