From ae72f91975aa946616368a4d58eb8c9c9f543105 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Dec 2016 21:14:38 +0900 Subject: [PATCH] Reshuffle hit explosions to be on their own layer. Style misses better. --- .../Objects/Drawables/DrawableHitCircle.cs | 11 ----- .../Objects/Drawables/DrawableSlider.cs | 2 +- .../Objects/Drawables/HitExplosion.cs | 42 ++++++++++++++++--- osu.Game.Mode.Osu/Objects/OsuHitObject.cs | 2 + osu.Game.Mode.Osu/Objects/Slider.cs | 3 ++ osu.Game.Mode.Osu/UI/OsuHitRenderer.cs | 1 - osu.Game.Mode.Osu/UI/OsuPlayfield.cs | 20 +++++++-- osu.Game/Modes/UI/Playfield.cs | 15 ++++++- 8 files changed, 72 insertions(+), 24 deletions(-) diff --git a/osu.Game.Mode.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Mode.Osu/Objects/Drawables/DrawableHitCircle.cs index c9d2901930..b916a7bc74 100644 --- a/osu.Game.Mode.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Mode.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -22,7 +22,6 @@ namespace osu.Game.Modes.Osu.Objects.Drawables private ExplodePiece explode; private NumberPiece number; private GlowPiece glow; - private HitExplosion explosion; public DrawableHitCircle(OsuHitObject h) : base(h) { @@ -130,9 +129,6 @@ namespace osu.Game.Modes.Osu.Objects.Drawables case ArmedState.Idle: Delay(osuObject.Duration + TIME_PREEMPT); FadeOut(TIME_FADEOUT); - - explosion?.Expire(); - explosion = null; break; case ArmedState.Miss: ring.FadeOut(); @@ -140,11 +136,6 @@ namespace osu.Game.Modes.Osu.Objects.Drawables number.FadeOut(); glow.FadeOut(); - explosion?.Expire(); - explosion = null; - - Schedule(() => Add(explosion = new HitExplosion((OsuJudgementInfo)Judgement))); - FadeOut(800); break; case ArmedState.Hit: @@ -156,8 +147,6 @@ namespace osu.Game.Modes.Osu.Objects.Drawables explode.FadeIn(flash_in); - Schedule(() => Add(explosion = new HitExplosion((OsuJudgementInfo)Judgement))); - Delay(flash_in, true); //after the flash, we can hide some elements that were behind it diff --git a/osu.Game.Mode.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Mode.Osu/Objects/Drawables/DrawableSlider.cs index e93ebba366..34318d3cec 100644 --- a/osu.Game.Mode.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Mode.Osu/Objects/Drawables/DrawableSlider.cs @@ -83,7 +83,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables base.UpdateState(state); Delay(HitObject.Duration); - FadeOut(300); + FadeOut(100); } } diff --git a/osu.Game.Mode.Osu/Objects/Drawables/HitExplosion.cs b/osu.Game.Mode.Osu/Objects/Drawables/HitExplosion.cs index 43a8aa1f92..a288e93068 100644 --- a/osu.Game.Mode.Osu/Objects/Drawables/HitExplosion.cs +++ b/osu.Game.Mode.Osu/Objects/Drawables/HitExplosion.cs @@ -5,22 +5,25 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Transformations; using osu.Game.Modes.Objects.Drawables; using OpenTK; +using OpenTK.Graphics; namespace osu.Game.Modes.Osu.Objects.Drawables { public class HitExplosion : FlowContainer { + private readonly OsuJudgementInfo judgement; private SpriteText line1; private SpriteText line2; - public HitExplosion(OsuJudgementInfo judgement) + public HitExplosion(OsuJudgementInfo judgement, OsuHitObject h = null) { + this.judgement = judgement; AutoSizeAxes = Axes.Both; - Anchor = Anchor.Centre; Origin = Anchor.Centre; Direction = FlowDirection.VerticalOnly; Spacing = new Vector2(0, 2); + Position = (h?.EndPosition ?? Vector2.Zero) + judgement.PositionOffset; Children = new Drawable[] { @@ -30,13 +33,13 @@ namespace osu.Game.Modes.Osu.Objects.Drawables Origin = Anchor.TopCentre, Text = judgement.Score.GetDescription(), Font = @"Venera", - TextSize = 20, + TextSize = 16, }, line2 = new SpriteText { Text = judgement.Combo.GetDescription(), Font = @"Venera", - TextSize = 14, + TextSize = 11, } }; } @@ -44,8 +47,35 @@ namespace osu.Game.Modes.Osu.Objects.Drawables protected override void LoadComplete() { base.LoadComplete(); - line1.TransformSpacingTo(new Vector2(14, 0), 1800, EasingTypes.OutQuint); - line2.TransformSpacingTo(new Vector2(14, 0), 1800, EasingTypes.OutQuint); + + if (judgement.Result == HitResult.Miss) + { + FadeInFromZero(60); + + ScaleTo(1.6f); + ScaleTo(1, 100, EasingTypes.In); + + MoveToRelative(new Vector2(0, 100), 800, EasingTypes.InQuint); + RotateTo(40, 800, EasingTypes.InQuint); + + Delay(600); + FadeOut(200); + } + else + { + line1.TransformSpacingTo(new Vector2(14, 0), 1800, EasingTypes.OutQuint); + line2.TransformSpacingTo(new Vector2(14, 0), 1800, EasingTypes.OutQuint); + FadeOut(500); + } + + switch (judgement.Result) + { + case HitResult.Miss: + Colour = Color4.Red; + break; + } + + Expire(); } } } \ No newline at end of file diff --git a/osu.Game.Mode.Osu/Objects/OsuHitObject.cs b/osu.Game.Mode.Osu/Objects/OsuHitObject.cs index 35f24699f1..61932f80a3 100644 --- a/osu.Game.Mode.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Mode.Osu/Objects/OsuHitObject.cs @@ -12,6 +12,8 @@ namespace osu.Game.Modes.Osu.Objects { public Vector2 Position { get; set; } + public virtual Vector2 EndPosition => Position; + [Flags] internal enum HitObjectType { diff --git a/osu.Game.Mode.Osu/Objects/Slider.cs b/osu.Game.Mode.Osu/Objects/Slider.cs index a0cdbeae7c..3c11ead7e4 100644 --- a/osu.Game.Mode.Osu/Objects/Slider.cs +++ b/osu.Game.Mode.Osu/Objects/Slider.cs @@ -4,6 +4,7 @@ using osu.Game.Database; using osu.Game.Beatmaps; using System; +using OpenTK; namespace osu.Game.Modes.Osu.Objects { @@ -11,6 +12,8 @@ namespace osu.Game.Modes.Osu.Objects { public override double EndTime => StartTime + RepeatCount * Curve.Length / Velocity; + public override Vector2 EndPosition => RepeatCount % 2 == 0 ? Position : Curve.PositionAt(1); + public double Velocity; public override void SetDefaultsFromBeatmap(Beatmap beatmap) diff --git a/osu.Game.Mode.Osu/UI/OsuHitRenderer.cs b/osu.Game.Mode.Osu/UI/OsuHitRenderer.cs index 01f95de5fb..02e7521c4f 100644 --- a/osu.Game.Mode.Osu/UI/OsuHitRenderer.cs +++ b/osu.Game.Mode.Osu/UI/OsuHitRenderer.cs @@ -6,7 +6,6 @@ using osu.Game.Modes.Objects.Drawables; using osu.Game.Modes.Osu.Objects; using osu.Game.Modes.Osu.Objects.Drawables; using osu.Game.Modes.UI; -using OsuConverter = osu.Game.Modes.Osu.Objects.OsuHitObjectConverter; namespace osu.Game.Modes.Osu.UI { diff --git a/osu.Game.Mode.Osu/UI/OsuPlayfield.cs b/osu.Game.Mode.Osu/UI/OsuPlayfield.cs index 1e69cd78a3..3ee3339f2a 100644 --- a/osu.Game.Mode.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Mode.Osu/UI/OsuPlayfield.cs @@ -3,19 +3,18 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; using osu.Game.Modes.Objects.Drawables; using osu.Game.Modes.Osu.Objects; using osu.Game.Modes.Osu.Objects.Drawables; using osu.Game.Modes.UI; using OpenTK; -using OpenTK.Graphics; namespace osu.Game.Modes.Osu.UI { public class OsuPlayfield : Playfield { private Container approachCircles; + private Container judgementLayer; public override Vector2 Size { @@ -35,11 +34,17 @@ namespace osu.Game.Modes.Osu.UI RelativeSizeAxes = Axes.Both; Size = new Vector2(0.75f); - AddInternal(new Drawable[] + Add(new Drawable[] { + judgementLayer = new Container + { + RelativeSizeAxes = Axes.Both, + Depth = 1, + }, approachCircles = new Container { RelativeSizeAxes = Axes.Both, + Depth = -1, } }); } @@ -52,7 +57,16 @@ namespace osu.Game.Modes.Osu.UI approachCircles.Add(c.ApproachCircle.CreateProxy()); } + h.OnJudgement += judgement; + base.Add(h); } + + private void judgement(DrawableHitObject h, JudgementInfo j) + { + HitExplosion explosion = new HitExplosion((OsuJudgementInfo)j, (OsuHitObject)h.HitObject); + + judgementLayer.Add(explosion); + } } } \ No newline at end of file diff --git a/osu.Game/Modes/UI/Playfield.cs b/osu.Game/Modes/UI/Playfield.cs index ff8a03db2a..ec91536f29 100644 --- a/osu.Game/Modes/UI/Playfield.cs +++ b/osu.Game/Modes/UI/Playfield.cs @@ -11,23 +11,34 @@ namespace osu.Game.Modes.UI public abstract class Playfield : Container { public HitObjectContainer HitObjects; + private Container content; public virtual void Add(DrawableHitObject h) => HitObjects.Add(h); public override bool Contains(Vector2 screenSpacePos) => true; + protected override Container Content => content; + public Playfield() { - AddInternal(HitObjects = new HitObjectContainer + AddInternal(content = new ScaledContainer() + { + RelativeSizeAxes = Axes.Both, + }); + + Add(HitObjects = new HitObjectContainer { RelativeSizeAxes = Axes.Both, }); } - public class HitObjectContainer : Container + public class ScaledContainer : Container { protected override Vector2 DrawScale => new Vector2(DrawSize.X / 512); + } + public class HitObjectContainer : Container + { public override bool Contains(Vector2 screenSpacePos) => true; } }