From 9ab0f6d8bc5a160f9859305a4a70e3d889f644ec Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 22 Apr 2020 05:12:29 +0300 Subject: [PATCH] Separate trail-related logic to its own container --- osu.Game.Rulesets.Catch/UI/Catcher.cs | 120 ++++----------- .../UI/CatcherTrailDisplay.cs | 137 ++++++++++++++++++ 2 files changed, 168 insertions(+), 89 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index 029de2cac0..e30988d8f7 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -8,7 +8,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; using osu.Framework.Utils; using osu.Game.Beatmaps; @@ -37,6 +36,11 @@ namespace osu.Game.Rulesets.Catch.UI /// public static readonly Color4 DEFAULT_CATCHER_HYPER_DASH_COLOUR = Color4.OrangeRed; + /// + /// The duration between transitioning to hyper-dash state. + /// + public const double HYPER_DASH_TRANSITION_DURATION = 180; + /// /// Whether we are hyper-dashing or not. /// @@ -49,10 +53,10 @@ namespace osu.Game.Rulesets.Catch.UI public Container ExplodingFruitTarget; - private readonly Container additiveTarget; - private Container dashTrails; - private Container hyperDashTrails; - private Container endGlowSprites; + [NotNull] + private readonly Container trailsTarget; + + private CatcherTrailDisplay trails; public CatcherAnimationState CurrentState { get; private set; } @@ -66,33 +70,23 @@ namespace osu.Game.Rulesets.Catch.UI /// internal float CatchWidth => CatcherArea.CATCHER_SIZE * Math.Abs(Scale.X) * allowed_catch_range; - protected bool Dashing + /// + /// The drawable catcher for . + /// + internal Drawable CurrentDrawableCatcher => currentCatcher.Drawable; + + private bool dashing; + + public bool Dashing { get => dashing; - set + protected set { if (value == dashing) return; dashing = value; - Trail |= dashing; - } - } - - /// - /// Activate or deactivate the trail. Will be automatically deactivated when conditions to keep the trail displayed are no longer met. - /// - protected bool Trail - { - get => trail; - set - { - if (value == trail || additiveTarget == null) return; - - trail = value; - - if (Trail) - beginTrail(); + trails.DisplayTrail |= dashing; } } @@ -109,17 +103,13 @@ namespace osu.Game.Rulesets.Catch.UI private int currentDirection; - private bool dashing; - - private bool trail; - private double hyperDashModifier = 1; private int hyperDashDirection; private float hyperDashTargetPosition; - public Catcher([NotNull] Container additiveTarget, BeatmapDifficulty difficulty = null) + public Catcher([NotNull] Container trailsTarget, BeatmapDifficulty difficulty = null) { - this.additiveTarget = additiveTarget; + this.trailsTarget = trailsTarget; RelativePositionAxes = Axes.X; X = 0.5f; @@ -158,12 +148,7 @@ namespace osu.Game.Rulesets.Catch.UI } }; - additiveTarget?.AddRange(new[] - { - dashTrails = new Container { RelativeSizeAxes = Axes.Both }, - hyperDashTrails = new Container { RelativeSizeAxes = Axes.Both, Colour = hyperDashColour }, - endGlowSprites = new Container { RelativeSizeAxes = Axes.Both, Colour = hyperDashEndGlowColour } - }); + trailsTarget.Add(trails = new CatcherTrailDisplay(this)); updateCatcher(); } @@ -257,7 +242,7 @@ namespace osu.Game.Rulesets.Catch.UI if (wasHyperDashing) { updateCatcherColour(false); - Trail &= Dashing; + trails.DisplayTrail &= Dashing; } } else @@ -269,21 +254,15 @@ namespace osu.Game.Rulesets.Catch.UI if (!wasHyperDashing) { updateCatcherColour(true); - Trail = true; - var hyperDashEndGlow = createAdditiveSprite(endGlowSprites); - hyperDashEndGlow.MoveToOffset(new Vector2(0, -10), 1200, Easing.In); - hyperDashEndGlow.ScaleTo(hyperDashEndGlow.Scale * 0.95f).ScaleTo(hyperDashEndGlow.Scale * 1.2f, 1200, Easing.In); - hyperDashEndGlow.FadeOut(1200); - hyperDashEndGlow.Expire(true); + trails.DisplayTrail = true; + trails.DisplayEndGlow(); } } } private void updateCatcherColour(bool hyperDashing) { - const float hyper_dash_transition_length = 180; - if (hyperDashing) { // special behaviour for catcher colour if no skin overrides. @@ -292,17 +271,17 @@ namespace osu.Game.Rulesets.Catch.UI ? DEFAULT_CATCHER_HYPER_DASH_COLOUR : hyperDashColour; - this.FadeColour(catcherColour, hyper_dash_transition_length, Easing.OutQuint); - this.FadeTo(0.2f, hyper_dash_transition_length, Easing.OutQuint); + this.FadeColour(catcherColour, HYPER_DASH_TRANSITION_DURATION, Easing.OutQuint); + this.FadeTo(0.2f, HYPER_DASH_TRANSITION_DURATION, Easing.OutQuint); } else { - this.FadeColour(Color4.White, hyper_dash_transition_length, Easing.OutQuint); - this.FadeTo(1f, hyper_dash_transition_length, Easing.OutQuint); + this.FadeColour(Color4.White, HYPER_DASH_TRANSITION_DURATION, Easing.OutQuint); + this.FadeTo(1f, HYPER_DASH_TRANSITION_DURATION, Easing.OutQuint); } - hyperDashTrails?.FadeColour(hyperDashColour, hyper_dash_transition_length, Easing.OutQuint); - endGlowSprites?.FadeColour(hyperDashEndGlowColour, hyper_dash_transition_length, Easing.OutQuint); + trails.HyperDashTrailsColour = hyperDashColour; + trails.EndGlowSpritesColour = hyperDashEndGlowColour; } public bool OnPressed(CatchAction action) @@ -453,22 +432,6 @@ namespace osu.Game.Rulesets.Catch.UI (currentCatcher.Drawable as IFramedAnimation)?.GotoFrame(0); } - private void beginTrail() - { - if (!dashing && !HyperDashing) - { - Trail = false; - return; - } - - var additive = createAdditiveSprite(HyperDashing ? hyperDashTrails : dashTrails); - - additive.FadeTo(0.4f).FadeOut(800, Easing.OutQuint); - additive.Expire(true); - - Scheduler.AddDelayed(beginTrail, HyperDashing ? 25 : 50); - } - private void updateState(CatcherAnimationState state) { if (CurrentState == state) @@ -478,27 +441,6 @@ namespace osu.Game.Rulesets.Catch.UI updateCatcher(); } - private CatcherTrailSprite createAdditiveSprite(Container target) - { - if (target == null) - return null; - - var tex = (currentCatcher.Drawable as TextureAnimation)?.CurrentFrame ?? ((Sprite)currentCatcher.Drawable).Texture; - - var sprite = new CatcherTrailSprite(tex) - { - Anchor = Anchor, - Scale = Scale, - Blending = BlendingParameters.Additive, - RelativePositionAxes = RelativePositionAxes, - Position = Position - }; - - target.Add(sprite); - - return sprite; - } - private void removeFromPlateWithTransform(DrawableHitObject fruit, Action action) { if (ExplodingFruitTarget != null) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs b/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs new file mode 100644 index 0000000000..afbfac9a51 --- /dev/null +++ b/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs @@ -0,0 +1,137 @@ +// 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; + } + } +}