diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs index 022e9ea12b..9d0c406295 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs @@ -24,10 +24,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { } + public DrawableOsuJudgement() + { + } + [BackgroundDependencyLoader] private void load(OsuConfigManager config) { - if (config.Get(OsuSetting.HitLighting) && Result.Type != HitResult.Miss) + if (config.Get(OsuSetting.HitLighting)) { AddInternal(lighting = new SkinnableSprite("lighting") { @@ -36,16 +40,23 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Blending = BlendingParameters.Additive, Depth = float.MaxValue }); + } + } - if (JudgedObject != null) - { - lightingColour = JudgedObject.AccentColour.GetBoundCopy(); - lightingColour.BindValueChanged(colour => lighting.Colour = colour.NewValue, true); - } - else - { - lighting.Colour = Color4.White; - } + protected override void PrepareForUse() + { + base.PrepareForUse(); + + lightingColour?.UnbindAll(); + + if (JudgedObject != null) + { + lightingColour = JudgedObject.AccentColour.GetBoundCopy(); + lightingColour.BindValueChanged(colour => lighting.Colour = Result.Type == HitResult.Miss ? Color4.Transparent : colour.NewValue, true); + } + else + { + lighting.Colour = Color4.White; } } @@ -55,13 +66,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { if (lighting != null) { - JudgementBody.Delay(FadeInDuration).FadeOut(400); + JudgementBody.FadeIn().Delay(FadeInDuration).FadeOut(400); lighting.ScaleTo(0.8f).ScaleTo(1.2f, 600, Easing.Out); lighting.FadeIn(200).Then().Delay(200).FadeOut(1000); } - JudgementText?.TransformSpacingTo(new Vector2(14, 0), 1800, Easing.OutQuint); + JudgementText?.TransformSpacingTo(Vector2.Zero).Then().TransformSpacingTo(new Vector2(14, 0), 1800, Easing.OutQuint); base.ApplyHitAnimations(); } } diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index 4b1a2ce43c..f9002a29ca 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -4,6 +4,8 @@ using osuTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Pooling; +using osu.Framework.Logging; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; @@ -26,10 +28,13 @@ namespace osu.Game.Rulesets.Osu.UI protected override GameplayCursorContainer CreateCursor() => new OsuCursorContainer(); + private readonly DrawablePool judgementPool; + public OsuPlayfield() { InternalChildren = new Drawable[] { + judgementPool = new DrawablePool(20), followPoints = new FollowPointRenderer { RelativeSizeAxes = Axes.Both, @@ -91,12 +96,17 @@ namespace osu.Game.Rulesets.Osu.UI if (!judgedObject.DisplayResult || !DisplayJudgements.Value) return; - DrawableOsuJudgement explosion = new DrawableOsuJudgement(result, judgedObject) + DrawableOsuJudgement explosion = judgementPool.Get(doj => { - Origin = Anchor.Centre, - Position = ((OsuHitObject)judgedObject.HitObject).StackedEndPosition, - Scale = new Vector2(((OsuHitObject)judgedObject.HitObject).Scale) - }; + if (doj.Result != null) + Logger.Log("reused!"); + doj.Result = result; + doj.JudgedObject = judgedObject; + + doj.Origin = Anchor.Centre; + doj.Position = ((OsuHitObject)judgedObject.HitObject).StackedEndPosition; + doj.Scale = new Vector2(((OsuHitObject)judgedObject.HitObject).Scale); + }); judgementLayer.Add(explosion); } diff --git a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs index 7113acbbfb..86dd02f2bb 100644 --- a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs +++ b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs @@ -1,11 +1,14 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Diagnostics; using osuTK; using osu.Framework.Allocation; +using osu.Framework.Caching; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Pooling; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; @@ -18,16 +21,31 @@ namespace osu.Game.Rulesets.Judgements /// /// A drawable object which visualises the hit result of a . /// - public class DrawableJudgement : CompositeDrawable + public class DrawableJudgement : PoolableDrawable { private const float judgement_size = 128; [Resolved] private OsuColour colours { get; set; } - protected readonly JudgementResult Result; + private readonly Cached drawableCache = new Cached(); - public readonly DrawableHitObject JudgedObject; + private JudgementResult result; + + public JudgementResult Result + { + get => result; + set + { + if (result?.Type == value.Type) + return; + + result = value; + drawableCache.Invalidate(); + } + } + + public DrawableHitObject JudgedObject; protected Container JudgementBody; protected SpriteText JudgementText; @@ -48,29 +66,15 @@ namespace osu.Game.Rulesets.Judgements /// The judgement to visualise. /// The object which was judged. public DrawableJudgement(JudgementResult result, DrawableHitObject judgedObject) + : this() { Result = result; JudgedObject = judgedObject; - - Size = new Vector2(judgement_size); } - [BackgroundDependencyLoader] - private void load() + public DrawableJudgement() { - InternalChild = JudgementBody = new Container - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Child = new SkinnableDrawable(new GameplaySkinComponent(Result.Type), _ => JudgementText = new OsuSpriteText - { - Text = Result.Type.GetDescription().ToUpperInvariant(), - Font = OsuFont.Numeric.With(size: 20), - Colour = colours.ForHitResult(Result.Type), - Scale = new Vector2(0.85f, 1), - }, confineMode: ConfineMode.NoScaling) - }; + Size = new Vector2(judgement_size); } protected virtual void ApplyHitAnimations() @@ -81,11 +85,25 @@ namespace osu.Game.Rulesets.Judgements this.Delay(FadeOutDelay).FadeOut(400); } - protected override void LoadComplete() + [BackgroundDependencyLoader] + private void load() { - base.LoadComplete(); + prepareDrawables(); + } + + protected override void PrepareForUse() + { + base.PrepareForUse(); + + Debug.Assert(Result != null); + + if (!drawableCache.IsValid) + prepareDrawables(); this.FadeInFromZero(FadeInDuration, Easing.OutQuint); + JudgementBody.ScaleTo(1); + JudgementBody.RotateTo(0); + JudgementBody.MoveTo(Vector2.Zero); switch (Result.Type) { @@ -109,5 +127,26 @@ namespace osu.Game.Rulesets.Judgements Expire(true); } + + private void prepareDrawables() + { + var type = Result?.Type ?? HitResult.Perfect; //TODO: better default type from ruleset + + InternalChild = JudgementBody = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Child = new SkinnableDrawable(new GameplaySkinComponent(type), _ => JudgementText = new OsuSpriteText + { + Text = type.GetDescription().ToUpperInvariant(), + Font = OsuFont.Numeric.With(size: 20), + Colour = colours.ForHitResult(type), + Scale = new Vector2(0.85f, 1), + }, confineMode: ConfineMode.NoScaling) + }; + + drawableCache.Validate(); + } } }