1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-12 16:43:00 +08:00

Separate trail-related logic to its own container

This commit is contained in:
Salman Ahmed 2020-04-22 05:12:29 +03:00
parent 95de2c6f7f
commit 9ab0f6d8bc
No known key found for this signature in database
GPG Key ID: ED81FD33FD9B58BC
2 changed files with 168 additions and 89 deletions

View File

@ -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
/// </remarks>
public static readonly Color4 DEFAULT_CATCHER_HYPER_DASH_COLOUR = Color4.OrangeRed;
/// <summary>
/// The duration between transitioning to hyper-dash state.
/// </summary>
public const double HYPER_DASH_TRANSITION_DURATION = 180;
/// <summary>
/// Whether we are hyper-dashing or not.
/// </summary>
@ -49,10 +53,10 @@ namespace osu.Game.Rulesets.Catch.UI
public Container ExplodingFruitTarget;
private readonly Container additiveTarget;
private Container<CatcherTrailSprite> dashTrails;
private Container<CatcherTrailSprite> hyperDashTrails;
private Container<CatcherTrailSprite> 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
/// </summary>
internal float CatchWidth => CatcherArea.CATCHER_SIZE * Math.Abs(Scale.X) * allowed_catch_range;
protected bool Dashing
/// <summary>
/// The drawable catcher for <see cref="CurrentState"/>.
/// </summary>
internal Drawable CurrentDrawableCatcher => currentCatcher.Drawable;
private bool dashing;
public bool Dashing
{
get => dashing;
set
protected set
{
if (value == dashing) return;
dashing = value;
Trail |= dashing;
}
}
/// <summary>
/// Activate or deactivate the trail. Will be automatically deactivated when conditions to keep the trail displayed are no longer met.
/// </summary>
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<CatcherTrailSprite> { RelativeSizeAxes = Axes.Both },
hyperDashTrails = new Container<CatcherTrailSprite> { RelativeSizeAxes = Axes.Both, Colour = hyperDashColour },
endGlowSprites = new Container<CatcherTrailSprite> { 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<CatcherTrailSprite> 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<DrawableHitObject> action)
{
if (ExplodingFruitTarget != null)

View File

@ -0,0 +1,137 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. 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
{
/// <summary>
/// Represents a component responsible for displaying
/// the appropriate catcher trails when requested to.
/// </summary>
public class CatcherTrailDisplay : CompositeDrawable
{
private readonly Catcher catcher;
private readonly Container<CatcherTrailSprite> dashTrails;
private readonly Container<CatcherTrailSprite> hyperDashTrails;
private readonly Container<CatcherTrailSprite> 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;
/// <summary>
/// Whether to start displaying trails following the catcher.
/// </summary>
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<CatcherTrailSprite> { RelativeSizeAxes = Axes.Both },
hyperDashTrails = new Container<CatcherTrailSprite> { RelativeSizeAxes = Axes.Both, Colour = Catcher.DEFAULT_HYPER_DASH_COLOUR },
endGlowSprites = new Container<CatcherTrailSprite> { RelativeSizeAxes = Axes.Both, Colour = Catcher.DEFAULT_HYPER_DASH_COLOUR },
};
}
/// <summary>
/// Displays a single end-glow catcher sprite.
/// </summary>
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<CatcherTrailSprite> 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;
}
}
}