diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneKiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneKiaiHitExplosion.cs new file mode 100644 index 0000000000..b558709592 --- /dev/null +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneKiaiHitExplosion.cs @@ -0,0 +1,37 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Rulesets.Taiko.UI; + +namespace osu.Game.Rulesets.Taiko.Tests.Skinning +{ + [TestFixture] + public class TestSceneKiaiHitExplosion : TaikoSkinnableTestScene + { + [Test] + public void TestKiaiHits() + { + AddStep("rim hit", () => SetContents(() => getContentFor(createHit(HitType.Rim)))); + AddStep("centre hit", () => SetContents(() => getContentFor(createHit(HitType.Centre)))); + } + + private Drawable getContentFor(DrawableTestHit hit) + { + return new Container + { + RelativeSizeAxes = Axes.Both, + Child = new KiaiHitExplosion(hit, hit.HitObject.Type) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + }; + } + + private DrawableTestHit createHit(HitType type) => new DrawableTestHit(new Hit { StartTime = Time.Current, Type = type }); + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/TaikoLegacySkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/TaikoLegacySkinTransformer.cs index c88480d18f..96fb065e79 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/TaikoLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/TaikoLegacySkinTransformer.cs @@ -114,6 +114,14 @@ namespace osu.Game.Rulesets.Taiko.Skinning return null; + case TaikoSkinComponents.TaikoExplosionKiai: + // suppress the default kiai explosion if the skin brings its own sprites. + // the drawable needs to expire as soon as possible to avoid accumulating empty drawables on the playfield. + if (hasExplosion.Value) + return Drawable.Empty().With(d => d.LifetimeEnd = double.MinValue); + + return null; + case TaikoSkinComponents.Scroller: if (GetTexture("taiko-slider") != null) return new LegacyTaikoScroller(); diff --git a/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs b/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs index 132d8f8868..bf48898dd2 100644 --- a/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs +++ b/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs @@ -18,6 +18,7 @@ namespace osu.Game.Rulesets.Taiko TaikoExplosionMiss, TaikoExplosionOk, TaikoExplosionGreat, + TaikoExplosionKiai, Scroller, Mascot, } diff --git a/osu.Game.Rulesets.Taiko/UI/DefaultKiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/DefaultKiaiHitExplosion.cs new file mode 100644 index 0000000000..7ce8b016d5 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/UI/DefaultKiaiHitExplosion.cs @@ -0,0 +1,64 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osuTK; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Rulesets.Taiko.Objects; + +namespace osu.Game.Rulesets.Taiko.UI +{ + public class DefaultKiaiHitExplosion : CircularContainer + { + public override bool RemoveWhenNotAlive => true; + + private readonly HitType type; + + public DefaultKiaiHitExplosion(HitType type) + { + this.type = type; + + RelativeSizeAxes = Axes.Both; + + Blending = BlendingParameters.Additive; + + Masking = true; + Alpha = 0.25f; + + Children = new[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + AlwaysPresent = true + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = type == HitType.Rim ? colours.BlueDarker : colours.PinkDarker, + Radius = 60, + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + this.ScaleTo(new Vector2(1, 3f), 500, Easing.OutQuint); + this.FadeOut(250); + + Expire(true); + } + } +} diff --git a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs index 067d390894..20900a9352 100644 --- a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs @@ -1,71 +1,47 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osuTK; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Effects; -using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Skinning; +using osuTK; namespace osu.Game.Rulesets.Taiko.UI { - public class KiaiHitExplosion : CircularContainer + public class KiaiHitExplosion : Container { public override bool RemoveWhenNotAlive => true; + [Cached(typeof(DrawableHitObject))] public readonly DrawableHitObject JudgedObject; - private readonly HitType type; - public KiaiHitExplosion(DrawableHitObject judgedObject, HitType type) + private readonly HitType hitType; + + private SkinnableDrawable skinnable; + + public override double LifetimeStart => skinnable.Drawable.LifetimeStart; + + public override double LifetimeEnd => skinnable.Drawable.LifetimeEnd; + + public KiaiHitExplosion(DrawableHitObject judgedObject, HitType hitType) { JudgedObject = judgedObject; - this.type = type; + this.hitType = hitType; Anchor = Anchor.CentreLeft; Origin = Anchor.Centre; RelativeSizeAxes = Axes.Both; Size = new Vector2(TaikoHitObject.DEFAULT_SIZE, 1); - - Blending = BlendingParameters.Additive; - - Masking = true; - Alpha = 0.25f; - - Children = new[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0, - AlwaysPresent = true - } - }; } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load() { - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Glow, - Colour = type == HitType.Rim ? colours.BlueDarker : colours.PinkDarker, - Radius = 60, - }; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - this.ScaleTo(new Vector2(1, 3f), 500, Easing.OutQuint); - this.FadeOut(250); - - Expire(true); + Child = skinnable = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.TaikoExplosionKiai), _ => new DefaultKiaiHitExplosion(hitType)); } } }