From 08cb84b325e0d11f7cf97f0cb665dbbf6fa3c5bb Mon Sep 17 00:00:00 2001 From: ekrctb Date: Tue, 1 Dec 2020 11:32:20 +0900 Subject: [PATCH] Pool osu!catch hit explosion --- osu.Game.Rulesets.Catch/UI/Catcher.cs | 22 ++-- osu.Game.Rulesets.Catch/UI/HitExplosion.cs | 116 ++++++++++++--------- 2 files changed, 82 insertions(+), 56 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index 0f0b9df76e..ae374a7cde 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -9,6 +9,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Pooling; using osu.Framework.Input.Bindings; using osu.Framework.Utils; using osu.Game.Beatmaps; @@ -107,6 +108,9 @@ namespace osu.Game.Rulesets.Catch.UI private float hyperDashTargetPosition; private Bindable hitLighting; + private DrawablePool hitExplosionPool; + private Container hitExplosionContainer; + public Catcher([NotNull] Container trailsTarget, BeatmapDifficulty difficulty = null) { this.trailsTarget = trailsTarget; @@ -127,6 +131,7 @@ namespace osu.Game.Rulesets.Catch.UI InternalChildren = new Drawable[] { + hitExplosionPool = new DrawablePool(10), caughtFruitContainer, catcherIdle = new CatcherSprite(CatcherAnimationState.Idle) { @@ -142,7 +147,12 @@ namespace osu.Game.Rulesets.Catch.UI { Anchor = Anchor.TopCentre, Alpha = 0, - } + }, + hitExplosionContainer = new Container + { + Anchor = Anchor.TopCentre, + Origin = Anchor.BottomCentre, + }, }; trails = new CatcherTrailDisplay(this); @@ -209,11 +219,11 @@ namespace osu.Game.Rulesets.Catch.UI if (hitLighting.Value) { - AddInternal(new HitExplosion(fruit) - { - X = fruit.X, - Scale = new Vector2(fruit.HitObject.Scale) - }); + var hitExplosion = hitExplosionPool.Get(); + hitExplosion.X = fruit.X; + hitExplosion.Scale = new Vector2(fruit.HitObject.Scale); + hitExplosion.ObjectColour = fruit.AccentColour.Value; + hitExplosionContainer.Add(hitExplosion); } } diff --git a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs index 04a86f83be..9716c1ed09 100644 --- a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs @@ -5,35 +5,40 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.Pooling; using osu.Framework.Utils; -using osu.Game.Rulesets.Catch.Objects.Drawables; using osuTK; using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.UI { - public class HitExplosion : CompositeDrawable + public class HitExplosion : PoolableDrawable { - private readonly CircularContainer largeFaint; + private Color4 objectColour; - public HitExplosion(DrawableCatchHitObject fruit) + public Color4 ObjectColour + { + get => objectColour; + set + { + if (objectColour == value) return; + + objectColour = value; + onColourChanged(); + } + } + + private readonly CircularContainer largeFaint, smallFaint, directionalGrow1, directionalGrow2; + + public HitExplosion() { Size = new Vector2(20); Anchor = Anchor.TopCentre; Origin = Anchor.BottomCentre; - Color4 objectColour = fruit.AccentColour.Value; - // scale roughly in-line with visual appearance of notes - - const float angle_variangle = 15; // should be less than 45 - - const float roundness = 100; - const float initial_height = 10; - var colour = Interpolation.ValueAt(0.4f, objectColour, Color4.White, 0, 1); - InternalChildren = new Drawable[] { largeFaint = new CircularContainer @@ -42,33 +47,17 @@ namespace osu.Game.Rulesets.Catch.UI Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, Masking = true, - // we want our size to be very small so the glow dominates it. - Size = new Vector2(0.8f), Blending = BlendingParameters.Additive, - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Glow, - Colour = Interpolation.ValueAt(0.1f, objectColour, Color4.White, 0, 1).Opacity(0.3f), - Roundness = 160, - Radius = 200, - }, }, - new CircularContainer + smallFaint = new CircularContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, Masking = true, Blending = BlendingParameters.Additive, - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Glow, - Colour = Interpolation.ValueAt(0.6f, objectColour, Color4.White, 0, 1), - Roundness = 20, - Radius = 50, - }, }, - new CircularContainer + directionalGrow1 = new CircularContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -76,16 +65,8 @@ namespace osu.Game.Rulesets.Catch.UI Masking = true, Size = new Vector2(0.01f, initial_height), Blending = BlendingParameters.Additive, - Rotation = RNG.NextSingle(-angle_variangle, angle_variangle), - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Glow, - Colour = colour, - Roundness = roundness, - Radius = 40, - }, }, - new CircularContainer + directionalGrow2 = new CircularContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -93,30 +74,65 @@ namespace osu.Game.Rulesets.Catch.UI Masking = true, Size = new Vector2(0.01f, initial_height), Blending = BlendingParameters.Additive, - Rotation = RNG.NextSingle(-angle_variangle, angle_variangle), - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Glow, - Colour = colour, - Roundness = roundness, - Radius = 40, - }, } }; } - protected override void LoadComplete() + protected override void PrepareForUse() { - base.LoadComplete(); + base.PrepareForUse(); const double duration = 400; + // we want our size to be very small so the glow dominates it. + largeFaint.Size = new Vector2(0.8f); largeFaint .ResizeTo(largeFaint.Size * new Vector2(5, 1), duration, Easing.OutQuint) .FadeOut(duration * 2); + const float angle_variangle = 15; // should be less than 45 + directionalGrow1.Rotation = RNG.NextSingle(-angle_variangle, angle_variangle); + directionalGrow2.Rotation = RNG.NextSingle(-angle_variangle, angle_variangle); + this.FadeInFromZero(50).Then().FadeOut(duration, Easing.Out); Expire(true); } + + private void onColourChanged() + { + const float roundness = 100; + + largeFaint.EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = Interpolation.ValueAt(0.1f, objectColour, Color4.White, 0, 1).Opacity(0.3f), + Roundness = 160, + Radius = 200, + }; + + smallFaint.EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = Interpolation.ValueAt(0.6f, objectColour, Color4.White, 0, 1), + Roundness = 20, + Radius = 50, + }; + + directionalGrow1.EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = Interpolation.ValueAt(0.4f, objectColour, Color4.White, 0, 1), + Roundness = roundness, + Radius = 40, + }; + + directionalGrow2.EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = Interpolation.ValueAt(0.4f, objectColour, Color4.White, 0, 1), + Roundness = roundness, + Radius = 40, + }; + } } }