From 869f8e5e1b21dfe53bb56a54a8479797956358f8 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 1 Oct 2023 00:20:53 +0300 Subject: [PATCH 01/21] Adjust test scene to apply miss judgements as well --- .../Gameplay/TestSceneSkinnableHealthDisplay.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs index b4ebb7c410..e3700a2a8b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs @@ -6,6 +6,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Testing; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Scoring; @@ -28,15 +29,21 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep(@"Reset all", delegate { healthProcessor.Health.Value = 1; + healthProcessor.Failed += () => false; // health won't be updated if the processor gets into a "fail" state. }); } [Test] public void TestHealthDisplayIncrementing() { - AddRepeatStep(@"decrease hp", delegate + AddRepeatStep("apply miss judgement", delegate { - healthProcessor.Health.Value -= 0.08f; + healthProcessor.ApplyResult(new JudgementResult(new HitObject(), new Judgement()) { Type = HitResult.Miss }); + }, 5); + + AddRepeatStep(@"decrease hp slightly", delegate + { + healthProcessor.Health.Value -= 0.01f; }, 10); AddRepeatStep(@"increase hp without flash", delegate From 33b0cb15a88ece545779bad5ac754f1a79275398 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 1 Oct 2023 00:21:12 +0300 Subject: [PATCH 02/21] Add handling for miss judgements in `HealthDisplay` --- osu.Game/Screens/Play/HUD/HealthDisplay.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/osu.Game/Screens/Play/HUD/HealthDisplay.cs b/osu.Game/Screens/Play/HUD/HealthDisplay.cs index 9fdd735804..5131f93ca2 100644 --- a/osu.Game/Screens/Play/HUD/HealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HealthDisplay.cs @@ -29,10 +29,22 @@ namespace osu.Game.Screens.Play.HUD MaxValue = 1 }; + /// + /// Triggered when a is a successful hit, signaling the health display to perform a flash animation (if designed to do so). + /// + /// The judgement result. protected virtual void Flash(JudgementResult result) { } + /// + /// Triggered when a resulted in the player losing health. + /// + /// The judgement result. + protected virtual void Miss(JudgementResult result) + { + } + [Resolved] private HUDOverlay? hudOverlay { get; set; } @@ -54,6 +66,8 @@ namespace osu.Game.Screens.Play.HUD { if (judgement.IsHit && judgement.Type != HitResult.IgnoreHit) Flash(judgement); + else if (judgement.Judgement.HealthIncreaseFor(judgement) < 0) + Miss(judgement); } protected override void Dispose(bool isDisposing) From 776536e816075e179a595e42c56c275f989e039b Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 26 Sep 2023 02:23:29 +0300 Subject: [PATCH 03/21] Add "Argon" health display implementation --- .../TestSceneSkinnableHealthDisplay.cs | 3 +- .../Screens/Play/HUD/ArgonHealthDisplay.cs | 284 ++++++++++++++++++ 2 files changed, 286 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs index e3700a2a8b..4d8ddcd581 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs @@ -20,6 +20,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Cached(typeof(HealthProcessor))] private HealthProcessor healthProcessor = new DrainingHealthProcessor(0); + protected override Drawable CreateArgonImplementation() => new ArgonHealthDisplay(); protected override Drawable CreateDefaultImplementation() => new DefaultHealthDisplay(); protected override Drawable CreateLegacyImplementation() => new LegacyHealthDisplay(); @@ -61,4 +62,4 @@ namespace osu.Game.Tests.Visual.Gameplay }, 3); } } -} +} \ No newline at end of file diff --git a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs new file mode 100644 index 0000000000..ca7a4a6cf7 --- /dev/null +++ b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs @@ -0,0 +1,284 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Lines; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Threading; +using osu.Framework.Utils; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; +using osu.Game.Skinning; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Screens.Play.HUD +{ + public partial class ArgonHealthDisplay : HealthDisplay, ISerialisableDrawable + { + private const float curve_start = 280; + private const float curve_end = 310; + private const float curve_smoothness = 10; + + private const float bar_length = 350; + private const float bar_height = 32.5f; + + private BarPath healthBar = null!; + private BarPath missBar = null!; + + private SliderPath barPath = null!; + + private static readonly Colour4 health_bar_colour = Colour4.White; + + // the opacity isn't part of the design, it's only here to control glow intensity. + private static readonly Colour4 health_bar_glow_colour = Color4Extensions.FromHex("#7ED7FD").Opacity(0.3f); + private static readonly Colour4 health_bar_flash_colour = Color4Extensions.FromHex("#7ED7FD").Opacity(0.4f); + + private static readonly Colour4 miss_bar_colour = Color4Extensions.FromHex("#FF9393"); + private static readonly Colour4 miss_bar_glow_colour = Color4Extensions.FromHex("#FD0000"); + + // the "flashed" glow colour is just a lightened version of the original one, not part of the design. + private static readonly Colour4 miss_bar_flash_colour = Color4Extensions.FromHex("#FF5D5D"); + + public bool UsesFixedAnchor { get; set; } + + [BackgroundDependencyLoader] + private void load() + { + Anchor = Anchor.TopLeft; + Origin = Anchor.TopLeft; + AutoSizeAxes = Axes.Both; + + Vector2 diagonalDir = (new Vector2(curve_end, bar_height) - new Vector2(curve_start, 0)).Normalized(); + + // todo: SliderPath or parts of it should be moved away to a utility class as they're useful for making curved paths in general, as done here. + barPath = new SliderPath(new[] + { + new PathControlPoint(new Vector2(0, 0), PathType.Linear), + new PathControlPoint(new Vector2(curve_start - curve_smoothness, 0), PathType.Bezier), + new PathControlPoint(new Vector2(curve_start, 0)), + new PathControlPoint(new Vector2(curve_start, 0) + diagonalDir * curve_smoothness, PathType.Linear), + new PathControlPoint(new Vector2(curve_end, bar_height) - diagonalDir * curve_smoothness, PathType.Bezier), + new PathControlPoint(new Vector2(curve_end, bar_height)), + new PathControlPoint(new Vector2(curve_end + curve_smoothness, bar_height), PathType.Linear), + new PathControlPoint(new Vector2(bar_length, bar_height)), + }); + + var vertices = new List(); + barPath.GetPathToProgress(vertices, 0.0, 1.0); + + InternalChild = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(4f, 0f), + Children = new Drawable[] + { + new Circle + { + Margin = new MarginPadding { Top = 10f - 3f / 2f, Left = -2f }, + Size = new Vector2(50f, 3f), + }, + new Container + { + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + new BackgroundPath + { + PathRadius = 10f, + Vertices = vertices, + }, + missBar = new BarPath + { + AutoSizeAxes = Axes.None, + RelativeSizeAxes = Axes.Both, + BarColour = miss_bar_colour, + GlowColour = miss_bar_glow_colour, + Alpha = 0f, + PathRadius = 10f, + Vertices = vertices + }, + healthBar = new BarPath + { + AutoSizeAxes = Axes.None, + RelativeSizeAxes = Axes.Both, + BarColour = health_bar_colour, + GlowColour = health_bar_glow_colour, + PathRadius = 10f, + Vertices = vertices + }, + } + } + }, + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + Current.BindValueChanged(v => + { + if (v.NewValue > MissBarValue) + { + missBar.FadeOut(300, Easing.OutQuint); + resetMissBarDelegate?.Cancel(); + resetMissBarDelegate = null; + } + + if (v.NewValue == 0) + healthBar.FadeOut(300, Easing.OutQuint); + else if (healthBar.Alpha < 1) + healthBar.FadeIn(300, Easing.OutQuint); + + this.TransformTo(nameof(HealthBarValue), v.NewValue, 300, Easing.OutQuint); + }, true); + } + + private ScheduledDelegate? resetMissBarDelegate; + + protected override void Miss(JudgementResult result) + { + base.Miss(result); + + if (resetMissBarDelegate != null) + resetMissBarDelegate.Cancel(); + else + this.TransformTo(nameof(MissBarValue), HealthBarValue); + + this.Delay(500).Schedule(() => + { + this.TransformTo(nameof(MissBarValue), Current.Value, 300, Easing.OutQuint); + resetMissBarDelegate = null; + }, out resetMissBarDelegate); + + missBar.FadeIn(120, Easing.OutQuint); + missBar.Delay(500).FadeOut(300, Easing.InQuint); + + missBar.TransformTo(nameof(BarPath.BarColour), miss_bar_colour.Lighten(0.1f)) + .TransformTo(nameof(BarPath.BarColour), miss_bar_colour, 300, Easing.OutQuint); + + missBar.TransformTo(nameof(BarPath.GlowColour), miss_bar_flash_colour) + .TransformTo(nameof(BarPath.GlowColour), miss_bar_glow_colour, 300, Easing.OutQuint); + } + + protected override void Flash(JudgementResult result) + { + base.Flash(result); + + healthBar.TransformTo(nameof(BarPath.GlowColour), health_bar_flash_colour) + .TransformTo(nameof(BarPath.GlowColour), health_bar_glow_colour, 300, Easing.OutQuint); + } + + private double missBarValue = 1.0; + private readonly List missBarVertices = new List(); + + public double MissBarValue + { + get => missBarValue; + set + { + if (missBarValue == value) + return; + + missBarValue = value; + updatePathVertices(); + } + } + + private double healthBarValue = 1.0; + private readonly List healthBarVertices = new List(); + + public double HealthBarValue + { + get => healthBarValue; + set + { + if (healthBarValue == value) + return; + + healthBarValue = value; + updatePathVertices(); + } + } + + private void updatePathVertices() + { + barPath.GetPathToProgress(healthBarVertices, 0.0, healthBarValue); + barPath.GetPathToProgress(missBarVertices, healthBarValue, Math.Max(missBarValue, healthBarValue)); + + if (healthBarVertices.Count == 0) + healthBarVertices.Add(Vector2.Zero); + + if (missBarVertices.Count == 0) + missBarVertices.Add(Vector2.Zero); + + missBar.Vertices = missBarVertices.Select(v => v - missBarVertices[0]).ToList(); + missBar.Position = missBarVertices[0]; + + healthBar.Vertices = healthBarVertices.Select(v => v - healthBarVertices[0]).ToList(); + healthBar.Position = healthBarVertices[0]; + } + + private partial class BackgroundPath : SmoothPath + { + protected override Color4 ColourAt(float position) + { + if (position <= 0.128f) + return Color4.White.Opacity(0.3f); + + position -= 0.128f; + return Interpolation.ValueAt(Math.Clamp(position, 0f, 1f), Color4.White.Opacity(0.5f), Color4.Black.Opacity(0.5f), -0.75f, 1f, Easing.OutQuart); + } + } + + private partial class BarPath : SmoothPath + { + private Colour4 barColour; + + public Colour4 BarColour + { + get => barColour; + set + { + if (barColour == value) + return; + + barColour = value; + InvalidateTexture(); + } + } + + private Colour4 glowColour; + + public Colour4 GlowColour + { + get => glowColour; + set + { + if (glowColour == value) + return; + + glowColour = value; + InvalidateTexture(); + } + } + + protected override Color4 ColourAt(float position) + { + if (position >= 0.6f) + return BarColour; + + return Interpolation.ValueAt(position, Colour4.Black.Opacity(0.0f), GlowColour, 0.0, 0.6); + } + } + } +} From 319208ca3d985b1e733adc39c0be321e09f26f67 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 1 Oct 2023 01:18:05 +0300 Subject: [PATCH 04/21] Adjust health bar glow intensity --- osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs index ca7a4a6cf7..5035571820 100644 --- a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs @@ -38,8 +38,8 @@ namespace osu.Game.Screens.Play.HUD private static readonly Colour4 health_bar_colour = Colour4.White; // the opacity isn't part of the design, it's only here to control glow intensity. - private static readonly Colour4 health_bar_glow_colour = Color4Extensions.FromHex("#7ED7FD").Opacity(0.3f); - private static readonly Colour4 health_bar_flash_colour = Color4Extensions.FromHex("#7ED7FD").Opacity(0.4f); + private static readonly Colour4 health_bar_glow_colour = Color4Extensions.FromHex("#7ED7FD").Opacity(0.5f); + private static readonly Colour4 health_bar_flash_colour = Color4Extensions.FromHex("#7ED7FD").Opacity(0.6f); private static readonly Colour4 miss_bar_colour = Color4Extensions.FromHex("#FF9393"); private static readonly Colour4 miss_bar_glow_colour = Color4Extensions.FromHex("#FD0000"); From a331fb993ae5dbc94b50283ffb7577d7efb08332 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 1 Oct 2023 01:21:37 +0300 Subject: [PATCH 05/21] Adjust health bar outer stroke colour --- osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs index 5035571820..ed141a9a26 100644 --- a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs @@ -233,7 +233,7 @@ namespace osu.Game.Screens.Play.HUD protected override Color4 ColourAt(float position) { if (position <= 0.128f) - return Color4.White.Opacity(0.3f); + return Color4.White.Opacity(0.5f); position -= 0.128f; return Interpolation.ValueAt(Math.Clamp(position, 0f, 1f), Color4.White.Opacity(0.5f), Color4.Black.Opacity(0.5f), -0.75f, 1f, Easing.OutQuart); From 9e2b8254d9fc95986c1c3a7eebffe91d8b4f4b0b Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 1 Oct 2023 13:26:43 +0300 Subject: [PATCH 06/21] Add argon-specific health display test scene --- .../Gameplay/TestSceneArgonHealthDisplay.cs | 78 +++++++++++++++++++ .../Screens/Play/HUD/ArgonHealthDisplay.cs | 2 - 2 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 osu.Game.Tests/Visual/Gameplay/TestSceneArgonHealthDisplay.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneArgonHealthDisplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneArgonHealthDisplay.cs new file mode 100644 index 0000000000..12a2611a76 --- /dev/null +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneArgonHealthDisplay.cs @@ -0,0 +1,78 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Testing; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Osu.Judgements; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Scoring; +using osu.Game.Screens.Play.HUD; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Tests.Visual.Gameplay +{ + public partial class TestSceneArgonHealthDisplay : OsuTestScene + { + [Cached(typeof(HealthProcessor))] + private HealthProcessor healthProcessor = new DrainingHealthProcessor(0); + + [SetUpSteps] + public void SetUpSteps() + { + AddStep(@"Reset all", delegate + { + healthProcessor.Health.Value = 1; + healthProcessor.Failed += () => false; // health won't be updated if the processor gets into a "fail" state. + + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + }, + new ArgonHealthDisplay + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Scale = new Vector2(2f), + }, + }; + }); + } + + [Test] + public void TestHealthDisplayIncrementing() + { + AddRepeatStep("apply miss judgement", delegate + { + healthProcessor.ApplyResult(new JudgementResult(new HitObject(), new Judgement()) { Type = HitResult.Miss }); + }, 5); + + AddRepeatStep(@"decrease hp slightly", delegate + { + healthProcessor.Health.Value -= 0.01f; + }, 10); + + AddRepeatStep(@"increase hp without flash", delegate + { + healthProcessor.Health.Value += 0.1f; + }, 3); + + AddRepeatStep(@"increase hp with flash", delegate + { + healthProcessor.Health.Value += 0.1f; + healthProcessor.ApplyResult(new JudgementResult(new HitCircle(), new OsuJudgement()) + { + Type = HitResult.Perfect + }); + }, 3); + } + } +} diff --git a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs index ed141a9a26..2db8e9d641 100644 --- a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs @@ -52,8 +52,6 @@ namespace osu.Game.Screens.Play.HUD [BackgroundDependencyLoader] private void load() { - Anchor = Anchor.TopLeft; - Origin = Anchor.TopLeft; AutoSizeAxes = Axes.Both; Vector2 diagonalDir = (new Vector2(curve_end, bar_height) - new Vector2(curve_start, 0)).Normalized(); From 446c9c2efefa819fc835cc8a2bb266311f40babf Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 1 Oct 2023 13:39:36 +0300 Subject: [PATCH 07/21] Apply adjustments on the "miss" bar display --- osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs index 2db8e9d641..aeaaa19f33 100644 --- a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs @@ -96,21 +96,20 @@ namespace osu.Game.Screens.Play.HUD }, missBar = new BarPath { - AutoSizeAxes = Axes.None, - RelativeSizeAxes = Axes.Both, BarColour = miss_bar_colour, GlowColour = miss_bar_glow_colour, Alpha = 0f, - PathRadius = 10f, + PathRadius = 20f, + GlowPortion = 0.75f, + Margin = new MarginPadding(-10f), Vertices = vertices }, healthBar = new BarPath { - AutoSizeAxes = Axes.None, - RelativeSizeAxes = Axes.Both, BarColour = health_bar_colour, GlowColour = health_bar_glow_colour, PathRadius = 10f, + GlowPortion = 0.6f, Vertices = vertices }, } @@ -270,9 +269,11 @@ namespace osu.Game.Screens.Play.HUD } } + public float GlowPortion { get; init; } + protected override Color4 ColourAt(float position) { - if (position >= 0.6f) + if (position >= GlowPortion) return BarColour; return Interpolation.ValueAt(position, Colour4.Black.Opacity(0.0f), GlowColour, 0.0, 0.6); From 30d9004ef9bc089f543bdbb68f3ac6ea7dbb99f8 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 1 Oct 2023 13:41:11 +0300 Subject: [PATCH 08/21] Fix small mistake --- osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs index aeaaa19f33..434736d42a 100644 --- a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs @@ -276,7 +276,7 @@ namespace osu.Game.Screens.Play.HUD if (position >= GlowPortion) return BarColour; - return Interpolation.ValueAt(position, Colour4.Black.Opacity(0.0f), GlowColour, 0.0, 0.6); + return Interpolation.ValueAt(position, Colour4.Black.Opacity(0.0f), GlowColour, 0.0, GlowPortion); } } } From 8d389accf81ceb8b77eb6a9287419d1ffd689ab0 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 1 Oct 2023 15:12:24 +0300 Subject: [PATCH 09/21] Cover "Argon" helath display in skin deserialisation tests --- .../Archives/modified-argon-pro-20231001.osk | Bin 0 -> 1834 bytes osu.Game.Tests/Skins/SkinDeserialisationTest.cs | 4 +++- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Tests/Resources/Archives/modified-argon-pro-20231001.osk diff --git a/osu.Game.Tests/Resources/Archives/modified-argon-pro-20231001.osk b/osu.Game.Tests/Resources/Archives/modified-argon-pro-20231001.osk new file mode 100644 index 0000000000000000000000000000000000000000..081bb73b9ef7bd85d763007117d4f18fe4046fa4 GIT binary patch literal 1834 zcmZ{k3pA8z7{@<%)ey@Fsfdu68N@O+iKb-6WyVab%KbJjGni2(8%CSUG(_(A+me+_ ziILp0V%-gPkc@<|xh7Ji-KlN2V|Mp@&vV}MzTf+Q&htFye|}a-K7L660E7WK$|)PI zcV5S;IHz!)Pd5NS^2QS&cmlqs@4hI{DKWu`ketaohy7y{qUNx0aFS|7mW#`kGjHDp zy!P3BYZ@$Smo^f2!b!H7i0*HOnLKal1odvLdfaWum7i11S|deZ`$cdw-`G`MP+Z^@!Tl z)?(GoIf3eOvd@+~`c6WdzHWe&?~~M%hv&5c$#>p5RV|c#(*NyE7Oot5syTIj$08)d_{*uu*6;b+f*{n`n%xYNrhorUla) zz%tu=EIUwLDD!@7RD@<=^D8p7giNK;MY=&6&PimW8U1~Q%E{CFsB}z@?GE?}{M1w^Vf*V2g478z8ZRn*waaV#7+R)VKERS-<6WktPXW5mv zG7d)b0)QD90Hio&n>*nNrnu84L|;E5!HqyBeXf7e22IR>iG?gz7*Q0u>%5FXW*!V1X|bChMk_R%Vx1*oSP-6C>7=Bjg%s zNekEREs3}@Q@i2k!bTgU3M1q!qliJezj4j&$u_A7?;y=OziC8srup25=RJl zQ2Cdl@!d_@VcG%hOvWO*iO><#x*pZgJXGy>2Q#R45#5{MB#ss>JNJr!3z~)Y-$Eps zs>`+MtO-@7f@M^6RxVOEyO$hmDej2c@T-Vi9f|vDv=WsxWja)x7Pc=%sE;-hQHM|x zzuc3>t}HEQBZg!>BRvgb^FjE;<@DO-CS`+RcKYM10#$a)jvc>MzsL_t849q^`duRT zqRNBFs$kq)wg4PoP~&}RUE1ZS6y^yjQ8OG9?B+93f6zlWtv>TX9{Y?PAKN}bExzUy zeGRTD6(duhCy%rjf#RCj)p92W$p?PT3JS$6ymxgDDQIAfJI&XSMl}7iVcWaVlUHDp zYOC?ie3ZT(79L#k25!8aq~T(EYA#HhhiYL#PsapoOLG=p$+j+y6mGqU$r*1vlSc&x{ zZx7*_%hE9~Yby;D$Mep%Wlzx?u3>6gbB7lmLZ`|;H2tvhDlN9%6JHLPv=wY@I&SaZ zY2K`8w3Q5pB-$JU@8y`+nn>`lcJpy_A%AwQZ@i^<3k=k{ye-)_>v&$5p*82^8Y*p2 zTFQpF38~;DtZ};;Ep}#&TMKb+_+5sn8wu-cah4Ja(*>-PaFd`yjjmw--RewU{Xyxq zN38rQU*Et|d8|^MUBldo;+MT*GHTe)E!wVjgX-|>p~fRZ@lj1F(eHTYL4zO6s#V1C zF^vqEN^t`#H42fH*YSMf;p72krq}7T4|^T%X&dUTp$$TWmYTlcFieh&Yg2zDh zh9mR6^QAZlDF&wN1lLlyhu#qCL^57Cv%?xMSW7?pDMxhdf&Swn;;0uHM&}=o1lM(8 z4Hxu7&fI`U-uCA^A0!11zbyZq-tzSK(;C)3sj==B$m{#}Xg=SpYcUT#%R;3)?3|)p zlJiw%&h(CQLX;C$K28*Oyqk~fS9Ap&HB+}lb)H-AMt0d$Vu}T6Jcu_pk<`pNTltFQ zyHXse@bF3k|Ic|&+P^;Pr|oa*bE~)+`b7f()X^`he~8L0<>uH|X*|au|4lXS9Nc#L mn!|$sU*_T#b5HTBI8lImrdCJ+!B77MI19olZ-(;%0R99!8uHBm literal 0 HcmV?d00001 diff --git a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs index 82d204f134..98008a003d 100644 --- a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs +++ b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs @@ -52,7 +52,9 @@ namespace osu.Game.Tests.Skins // Covers player avatar and flag. "Archives/modified-argon-20230305.osk", // Covers key counters - "Archives/modified-argon-pro-20230618.osk" + "Archives/modified-argon-pro-20230618.osk", + // Covers "Argon" health display + "Archives/modified-argon-pro-20231001.osk" }; /// From 7825bea959f41e6e1df8f14ed32eacd124ba0a20 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 1 Oct 2023 15:25:23 +0300 Subject: [PATCH 10/21] Use interpolation for health bar opacity instead of transforms --- osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs index 434736d42a..c6c64ebcad 100644 --- a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs @@ -131,15 +131,18 @@ namespace osu.Game.Screens.Play.HUD resetMissBarDelegate = null; } - if (v.NewValue == 0) - healthBar.FadeOut(300, Easing.OutQuint); - else if (healthBar.Alpha < 1) - healthBar.FadeIn(300, Easing.OutQuint); - this.TransformTo(nameof(HealthBarValue), v.NewValue, 300, Easing.OutQuint); }, true); } + protected override void Update() + { + base.Update(); + + float targetAlpha = Current.Value > 0 ? 1 : 0; + healthBar.Alpha = (float)Interpolation.DampContinuously(healthBar.Alpha, targetAlpha, 50.0, Time.Elapsed); + } + private ScheduledDelegate? resetMissBarDelegate; protected override void Miss(JudgementResult result) From eef099e69d347e9502d63142d8920f3edf74e332 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 1 Oct 2023 15:25:34 +0300 Subject: [PATCH 11/21] Do not display "miss" bar if health is already zero --- osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs index c6c64ebcad..50ac100ed2 100644 --- a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs @@ -149,6 +149,10 @@ namespace osu.Game.Screens.Play.HUD { base.Miss(result); + if (result.HealthAtJudgement == 0.0) + // health is already empty, nothing should be displayed here. + return; + if (resetMissBarDelegate != null) resetMissBarDelegate.Cancel(); else From 22aa7ffd06af80f021023d5a97162d6f06adc7a0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 1 Oct 2023 13:45:16 +0900 Subject: [PATCH 12/21] Use additive colour --- osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs index 50ac100ed2..023c5e47da 100644 --- a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs @@ -98,6 +98,7 @@ namespace osu.Game.Screens.Play.HUD { BarColour = miss_bar_colour, GlowColour = miss_bar_glow_colour, + Blending = BlendingParameters.Additive, Alpha = 0f, PathRadius = 20f, GlowPortion = 0.75f, @@ -106,6 +107,9 @@ namespace osu.Game.Screens.Play.HUD }, healthBar = new BarPath { + AutoSizeAxes = Axes.None, + RelativeSizeAxes = Axes.Both, + Blending = BlendingParameters.Additive, BarColour = health_bar_colour, GlowColour = health_bar_glow_colour, PathRadius = 10f, From df51e612342a0aadecc86267df90c9e641a694de Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 1 Oct 2023 21:20:03 +0900 Subject: [PATCH 13/21] Improve animation --- .../Screens/Play/HUD/ArgonHealthDisplay.cs | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs index 023c5e47da..1419ab1b43 100644 --- a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs @@ -7,11 +7,13 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Lines; using osu.Framework.Graphics.Shapes; using osu.Framework.Threading; using osu.Framework.Utils; +using osu.Game.Graphics; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; @@ -96,13 +98,13 @@ namespace osu.Game.Screens.Play.HUD }, missBar = new BarPath { - BarColour = miss_bar_colour, - GlowColour = miss_bar_glow_colour, + BarColour = Color4.White, + GlowColour = OsuColour.Gray(0.5f), Blending = BlendingParameters.Additive, - Alpha = 0f, - PathRadius = 20f, - GlowPortion = 0.75f, - Margin = new MarginPadding(-10f), + Colour = ColourInfo.GradientHorizontal(Color4.White.Opacity(0.8f), Color4.White), + PathRadius = 40f, + GlowPortion = 0.9f, + Margin = new MarginPadding(-30f), Vertices = vertices }, healthBar = new BarPath @@ -130,7 +132,8 @@ namespace osu.Game.Screens.Play.HUD { if (v.NewValue > MissBarValue) { - missBar.FadeOut(300, Easing.OutQuint); + missBar.TransformTo(nameof(BarPath.BarColour), Colour4.White, 300, Easing.OutQuint); + missBar.TransformTo(nameof(BarPath.GlowColour), Colour4.White, 300, Easing.OutQuint); resetMissBarDelegate?.Cancel(); resetMissBarDelegate = null; } @@ -158,19 +161,23 @@ namespace osu.Game.Screens.Play.HUD return; if (resetMissBarDelegate != null) + { resetMissBarDelegate.Cancel(); + resetMissBarDelegate = null; + } else this.TransformTo(nameof(MissBarValue), HealthBarValue); this.Delay(500).Schedule(() => { this.TransformTo(nameof(MissBarValue), Current.Value, 300, Easing.OutQuint); + + missBar.TransformTo(nameof(BarPath.BarColour), Colour4.White, 300, Easing.OutQuint); + missBar.TransformTo(nameof(BarPath.GlowColour), Colour4.White, 300, Easing.OutQuint); + resetMissBarDelegate = null; }, out resetMissBarDelegate); - missBar.FadeIn(120, Easing.OutQuint); - missBar.Delay(500).FadeOut(300, Easing.InQuint); - missBar.TransformTo(nameof(BarPath.BarColour), miss_bar_colour.Lighten(0.1f)) .TransformTo(nameof(BarPath.BarColour), miss_bar_colour, 300, Easing.OutQuint); @@ -287,7 +294,7 @@ namespace osu.Game.Screens.Play.HUD if (position >= GlowPortion) return BarColour; - return Interpolation.ValueAt(position, Colour4.Black.Opacity(0.0f), GlowColour, 0.0, GlowPortion); + return Interpolation.ValueAt(position, Colour4.Black.Opacity(0.0f), GlowColour, 0.0, GlowPortion, Easing.InQuart); } } } From 88d608e1fab112e12cb31660191df51c93f69fd4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Oct 2023 00:42:47 +0900 Subject: [PATCH 14/21] Tidy up common animation code --- .../Screens/Play/HUD/ArgonHealthDisplay.cs | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs index 1419ab1b43..c64d065e50 100644 --- a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs @@ -131,14 +131,11 @@ namespace osu.Game.Screens.Play.HUD Current.BindValueChanged(v => { if (v.NewValue > MissBarValue) - { - missBar.TransformTo(nameof(BarPath.BarColour), Colour4.White, 300, Easing.OutQuint); - missBar.TransformTo(nameof(BarPath.GlowColour), Colour4.White, 300, Easing.OutQuint); - resetMissBarDelegate?.Cancel(); - resetMissBarDelegate = null; - } + finishMissBarUsage(); this.TransformTo(nameof(HealthBarValue), v.NewValue, 300, Easing.OutQuint); + if (resetMissBarDelegate == null) + this.TransformTo(nameof(MissBarValue), v.NewValue, 300, Easing.OutQuint); }, true); } @@ -146,8 +143,8 @@ namespace osu.Game.Screens.Play.HUD { base.Update(); - float targetAlpha = Current.Value > 0 ? 1 : 0; - healthBar.Alpha = (float)Interpolation.DampContinuously(healthBar.Alpha, targetAlpha, 50.0, Time.Elapsed); + healthBar.Alpha = (float)Interpolation.DampContinuously(healthBar.Alpha, (float)(Current.Value > 0 ? 1 : 0), 40, Time.Elapsed); + missBar.Alpha = (float)Interpolation.DampContinuously(missBar.Alpha, (float)(MissBarValue > 0 ? 1 : 0), 40, Time.Elapsed); } private ScheduledDelegate? resetMissBarDelegate; @@ -172,10 +169,7 @@ namespace osu.Game.Screens.Play.HUD { this.TransformTo(nameof(MissBarValue), Current.Value, 300, Easing.OutQuint); - missBar.TransformTo(nameof(BarPath.BarColour), Colour4.White, 300, Easing.OutQuint); - missBar.TransformTo(nameof(BarPath.GlowColour), Colour4.White, 300, Easing.OutQuint); - - resetMissBarDelegate = null; + finishMissBarUsage(); }, out resetMissBarDelegate); missBar.TransformTo(nameof(BarPath.BarColour), miss_bar_colour.Lighten(0.1f)) @@ -185,6 +179,18 @@ namespace osu.Game.Screens.Play.HUD .TransformTo(nameof(BarPath.GlowColour), miss_bar_glow_colour, 300, Easing.OutQuint); } + private void finishMissBarUsage() + { + if (Current.Value > 0) + { + missBar.TransformTo(nameof(BarPath.BarColour), Colour4.Gray, 300, Easing.OutQuint); + missBar.TransformTo(nameof(BarPath.GlowColour), Colour4.Gray, 300, Easing.OutQuint); + } + + resetMissBarDelegate?.Cancel(); + resetMissBarDelegate = null; + } + protected override void Flash(JudgementResult result) { base.Flash(result); From c4f47974bc044a63ec393375b4de5c2cea4a4eb8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Oct 2023 00:56:29 +0900 Subject: [PATCH 15/21] Improve glow further --- osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs index c64d065e50..97ae2cc7ec 100644 --- a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs @@ -184,7 +184,7 @@ namespace osu.Game.Screens.Play.HUD if (Current.Value > 0) { missBar.TransformTo(nameof(BarPath.BarColour), Colour4.Gray, 300, Easing.OutQuint); - missBar.TransformTo(nameof(BarPath.GlowColour), Colour4.Gray, 300, Easing.OutQuint); + missBar.TransformTo(nameof(BarPath.GlowColour), health_bar_glow_colour, 300, Easing.OutQuint); } resetMissBarDelegate?.Cancel(); @@ -300,7 +300,7 @@ namespace osu.Game.Screens.Play.HUD if (position >= GlowPortion) return BarColour; - return Interpolation.ValueAt(position, Colour4.Black.Opacity(0.0f), GlowColour, 0.0, GlowPortion, Easing.InQuart); + return Interpolation.ValueAt(position, Colour4.Black.Opacity(0.0f), GlowColour, 0.0, GlowPortion, Easing.InQuint); } } } From 3a45bcad15857029647b56a462b7de21522e25fd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Oct 2023 02:03:45 +0900 Subject: [PATCH 16/21] Improve flash and glow further --- .../Screens/Play/HUD/ArgonHealthDisplay.cs | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs index 97ae2cc7ec..6cf1daa102 100644 --- a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs @@ -41,7 +41,7 @@ namespace osu.Game.Screens.Play.HUD // the opacity isn't part of the design, it's only here to control glow intensity. private static readonly Colour4 health_bar_glow_colour = Color4Extensions.FromHex("#7ED7FD").Opacity(0.5f); - private static readonly Colour4 health_bar_flash_colour = Color4Extensions.FromHex("#7ED7FD").Opacity(0.6f); + private static readonly Colour4 health_bar_flash_colour = Color4Extensions.FromHex("#7ED7FD").Opacity(0.8f); private static readonly Colour4 miss_bar_colour = Color4Extensions.FromHex("#FF9393"); private static readonly Colour4 miss_bar_glow_colour = Color4Extensions.FromHex("#FD0000"); @@ -130,13 +130,15 @@ namespace osu.Game.Screens.Play.HUD Current.BindValueChanged(v => { - if (v.NewValue > MissBarValue) + if (v.NewValue >= MissBarValue) finishMissBarUsage(); this.TransformTo(nameof(HealthBarValue), v.NewValue, 300, Easing.OutQuint); if (resetMissBarDelegate == null) this.TransformTo(nameof(MissBarValue), v.NewValue, 300, Easing.OutQuint); }, true); + + updatePathVertices(); } protected override void Update() @@ -172,19 +174,20 @@ namespace osu.Game.Screens.Play.HUD finishMissBarUsage(); }, out resetMissBarDelegate); - missBar.TransformTo(nameof(BarPath.BarColour), miss_bar_colour.Lighten(0.1f)) - .TransformTo(nameof(BarPath.BarColour), miss_bar_colour, 300, Easing.OutQuint); + missBar.TransformTo(nameof(BarPath.BarColour), miss_bar_colour, 100, Easing.OutQuint) + .Then() + .TransformTo(nameof(BarPath.BarColour), miss_bar_flash_colour, 800, Easing.OutQuint); - missBar.TransformTo(nameof(BarPath.GlowColour), miss_bar_flash_colour) - .TransformTo(nameof(BarPath.GlowColour), miss_bar_glow_colour, 300, Easing.OutQuint); + missBar.TransformTo(nameof(BarPath.GlowColour), miss_bar_glow_colour.Lighten(0.2f)) + .TransformTo(nameof(BarPath.GlowColour), miss_bar_glow_colour, 800, Easing.OutQuint); } private void finishMissBarUsage() { if (Current.Value > 0) { - missBar.TransformTo(nameof(BarPath.BarColour), Colour4.Gray, 300, Easing.OutQuint); - missBar.TransformTo(nameof(BarPath.GlowColour), health_bar_glow_colour, 300, Easing.OutQuint); + missBar.TransformTo(nameof(BarPath.BarColour), health_bar_colour, 300, Easing.In); + missBar.TransformTo(nameof(BarPath.GlowColour), health_bar_glow_colour, 300, Easing.In); } resetMissBarDelegate?.Cancel(); @@ -197,6 +200,16 @@ namespace osu.Game.Screens.Play.HUD healthBar.TransformTo(nameof(BarPath.GlowColour), health_bar_flash_colour) .TransformTo(nameof(BarPath.GlowColour), health_bar_glow_colour, 300, Easing.OutQuint); + + if (resetMissBarDelegate == null) + { + missBar.TransformTo(nameof(BarPath.BarColour), Colour4.White, 100, Easing.OutQuint) + .Then() + .TransformTo(nameof(BarPath.BarColour), health_bar_colour, 800, Easing.OutQuint); + + missBar.TransformTo(nameof(BarPath.GlowColour), Colour4.White) + .TransformTo(nameof(BarPath.GlowColour), health_bar_glow_colour, 800, Easing.OutQuint); + } } private double missBarValue = 1.0; From 8178cf3a8dce61729699668898bd61b6b80ee5b8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 3 Oct 2023 17:17:11 +0900 Subject: [PATCH 17/21] Tidy up background colour gradient logic This changes things visually a touch, but I think it feels better. And reads better. --- osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs index 6cf1daa102..f2f71ab64d 100644 --- a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs @@ -267,10 +267,12 @@ namespace osu.Game.Screens.Play.HUD protected override Color4 ColourAt(float position) { if (position <= 0.128f) - return Color4.White.Opacity(0.5f); + return Color4.White.Opacity(0.8f); - position -= 0.128f; - return Interpolation.ValueAt(Math.Clamp(position, 0f, 1f), Color4.White.Opacity(0.5f), Color4.Black.Opacity(0.5f), -0.75f, 1f, Easing.OutQuart); + return Interpolation.ValueAt(position, + Color4.White.Opacity(0.8f), + Color4.Black.Opacity(0.2f), + -0.5f, 1f, Easing.OutQuint); } } From e1445fcc65cf60800fd6f86785db051d821b5f64 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 3 Oct 2023 17:17:42 +0900 Subject: [PATCH 18/21] Adjust health display test scene's background colour to better visualise background fill --- osu.Game.Tests/Visual/Gameplay/TestSceneArgonHealthDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneArgonHealthDisplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneArgonHealthDisplay.cs index 12a2611a76..06a7763711 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneArgonHealthDisplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneArgonHealthDisplay.cs @@ -35,7 +35,7 @@ namespace osu.Game.Tests.Visual.Gameplay new Box { RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, + Colour = Color4.Gray, }, new ArgonHealthDisplay { From 4f9daa1c14eda97baf27a5ab547add008fe46171 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 3 Oct 2023 17:31:50 +0900 Subject: [PATCH 19/21] Tidy up `ArgonHealthDisplay` code quality --- .../Screens/Play/HUD/ArgonHealthDisplay.cs | 183 +++++++++--------- 1 file changed, 88 insertions(+), 95 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs index f2f71ab64d..6d16915576 100644 --- a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs @@ -25,55 +25,64 @@ namespace osu.Game.Screens.Play.HUD { public partial class ArgonHealthDisplay : HealthDisplay, ISerialisableDrawable { + public bool UsesFixedAnchor { get; set; } + private const float curve_start = 280; private const float curve_end = 310; private const float curve_smoothness = 10; private const float bar_length = 350; - private const float bar_height = 32.5f; + private const float bar_verticality = 32.5f; private BarPath healthBar = null!; private BarPath missBar = null!; + private BackgroundPath background = null!; private SliderPath barPath = null!; - private static readonly Colour4 health_bar_colour = Colour4.White; + private static readonly Colour4 main_bar_colour = Colour4.White; + private static readonly Colour4 main_bar_glow_colour = Color4Extensions.FromHex("#7ED7FD").Opacity(0.5f); - // the opacity isn't part of the design, it's only here to control glow intensity. - private static readonly Colour4 health_bar_glow_colour = Color4Extensions.FromHex("#7ED7FD").Opacity(0.5f); - private static readonly Colour4 health_bar_flash_colour = Color4Extensions.FromHex("#7ED7FD").Opacity(0.8f); + private ScheduledDelegate? resetMissBarDelegate; - private static readonly Colour4 miss_bar_colour = Color4Extensions.FromHex("#FF9393"); - private static readonly Colour4 miss_bar_glow_colour = Color4Extensions.FromHex("#FD0000"); + private readonly List missBarVertices = new List(); + private readonly List healthBarVertices = new List(); - // the "flashed" glow colour is just a lightened version of the original one, not part of the design. - private static readonly Colour4 miss_bar_flash_colour = Color4Extensions.FromHex("#FF5D5D"); + private double missBarValue = 1; - public bool UsesFixedAnchor { get; set; } + public double MissBarValue + { + get => missBarValue; + set + { + if (missBarValue == value) + return; + + missBarValue = value; + updatePathVertices(); + } + } + + private double healthBarValue = 1; + + public double HealthBarValue + { + get => healthBarValue; + set + { + if (healthBarValue == value) + return; + + healthBarValue = value; + updatePathVertices(); + } + } [BackgroundDependencyLoader] private void load() { AutoSizeAxes = Axes.Both; - Vector2 diagonalDir = (new Vector2(curve_end, bar_height) - new Vector2(curve_start, 0)).Normalized(); - - // todo: SliderPath or parts of it should be moved away to a utility class as they're useful for making curved paths in general, as done here. - barPath = new SliderPath(new[] - { - new PathControlPoint(new Vector2(0, 0), PathType.Linear), - new PathControlPoint(new Vector2(curve_start - curve_smoothness, 0), PathType.Bezier), - new PathControlPoint(new Vector2(curve_start, 0)), - new PathControlPoint(new Vector2(curve_start, 0) + diagonalDir * curve_smoothness, PathType.Linear), - new PathControlPoint(new Vector2(curve_end, bar_height) - diagonalDir * curve_smoothness, PathType.Bezier), - new PathControlPoint(new Vector2(curve_end, bar_height)), - new PathControlPoint(new Vector2(curve_end + curve_smoothness, bar_height), PathType.Linear), - new PathControlPoint(new Vector2(bar_length, bar_height)), - }); - - var vertices = new List(); - barPath.GetPathToProgress(vertices, 0.0, 1.0); - InternalChild = new FillFlowContainer { AutoSizeAxes = Axes.Both, @@ -83,7 +92,7 @@ namespace osu.Game.Screens.Play.HUD { new Circle { - Margin = new MarginPadding { Top = 10f - 3f / 2f, Left = -2f }, + Margin = new MarginPadding { Top = 8.5f, Left = -2 }, Size = new Vector2(50f, 3f), }, new Container @@ -91,10 +100,9 @@ namespace osu.Game.Screens.Play.HUD AutoSizeAxes = Axes.Both, Children = new Drawable[] { - new BackgroundPath + background = new BackgroundPath { PathRadius = 10f, - Vertices = vertices, }, missBar = new BarPath { @@ -103,25 +111,26 @@ namespace osu.Game.Screens.Play.HUD Blending = BlendingParameters.Additive, Colour = ColourInfo.GradientHorizontal(Color4.White.Opacity(0.8f), Color4.White), PathRadius = 40f, - GlowPortion = 0.9f, + // Kinda hacky, but results in correct positioning with increased path radius. Margin = new MarginPadding(-30f), - Vertices = vertices + GlowPortion = 0.9f, }, healthBar = new BarPath { AutoSizeAxes = Axes.None, RelativeSizeAxes = Axes.Both, Blending = BlendingParameters.Additive, - BarColour = health_bar_colour, - GlowColour = health_bar_glow_colour, + BarColour = main_bar_colour, + GlowColour = main_bar_glow_colour, PathRadius = 10f, GlowPortion = 0.6f, - Vertices = vertices }, } } }, }; + + updatePath(); } protected override void LoadComplete() @@ -137,28 +146,38 @@ namespace osu.Game.Screens.Play.HUD if (resetMissBarDelegate == null) this.TransformTo(nameof(MissBarValue), v.NewValue, 300, Easing.OutQuint); }, true); - - updatePathVertices(); } protected override void Update() { base.Update(); - healthBar.Alpha = (float)Interpolation.DampContinuously(healthBar.Alpha, (float)(Current.Value > 0 ? 1 : 0), 40, Time.Elapsed); - missBar.Alpha = (float)Interpolation.DampContinuously(missBar.Alpha, (float)(MissBarValue > 0 ? 1 : 0), 40, Time.Elapsed); + healthBar.Alpha = (float)Interpolation.DampContinuously(healthBar.Alpha, Current.Value > 0 ? 1 : 0, 40, Time.Elapsed); + missBar.Alpha = (float)Interpolation.DampContinuously(missBar.Alpha, MissBarValue > 0 ? 1 : 0, 40, Time.Elapsed); } - private ScheduledDelegate? resetMissBarDelegate; + protected override void Flash(JudgementResult result) + { + base.Flash(result); + + healthBar.TransformTo(nameof(BarPath.GlowColour), main_bar_glow_colour.Opacity(0.8f)) + .TransformTo(nameof(BarPath.GlowColour), main_bar_glow_colour, 300, Easing.OutQuint); + + if (resetMissBarDelegate == null) + { + missBar.TransformTo(nameof(BarPath.BarColour), Colour4.White, 100, Easing.OutQuint) + .Then() + .TransformTo(nameof(BarPath.BarColour), main_bar_colour, 800, Easing.OutQuint); + + missBar.TransformTo(nameof(BarPath.GlowColour), Colour4.White) + .TransformTo(nameof(BarPath.GlowColour), main_bar_glow_colour, 800, Easing.OutQuint); + } + } protected override void Miss(JudgementResult result) { base.Miss(result); - if (result.HealthAtJudgement == 0.0) - // health is already empty, nothing should be displayed here. - return; - if (resetMissBarDelegate != null) { resetMissBarDelegate.Cancel(); @@ -170,78 +189,52 @@ namespace osu.Game.Screens.Play.HUD this.Delay(500).Schedule(() => { this.TransformTo(nameof(MissBarValue), Current.Value, 300, Easing.OutQuint); - finishMissBarUsage(); }, out resetMissBarDelegate); - missBar.TransformTo(nameof(BarPath.BarColour), miss_bar_colour, 100, Easing.OutQuint) - .Then() - .TransformTo(nameof(BarPath.BarColour), miss_bar_flash_colour, 800, Easing.OutQuint); + missBar.TransformTo(nameof(BarPath.BarColour), new Colour4(255, 147, 147, 255), 100, Easing.OutQuint).Then() + .TransformTo(nameof(BarPath.BarColour), new Colour4(255, 93, 93, 255), 800, Easing.OutQuint); - missBar.TransformTo(nameof(BarPath.GlowColour), miss_bar_glow_colour.Lighten(0.2f)) - .TransformTo(nameof(BarPath.GlowColour), miss_bar_glow_colour, 800, Easing.OutQuint); + missBar.TransformTo(nameof(BarPath.GlowColour), new Colour4(253, 0, 0, 255).Lighten(0.2f)) + .TransformTo(nameof(BarPath.GlowColour), new Colour4(253, 0, 0, 255), 800, Easing.OutQuint); } private void finishMissBarUsage() { if (Current.Value > 0) { - missBar.TransformTo(nameof(BarPath.BarColour), health_bar_colour, 300, Easing.In); - missBar.TransformTo(nameof(BarPath.GlowColour), health_bar_glow_colour, 300, Easing.In); + missBar.TransformTo(nameof(BarPath.BarColour), main_bar_colour, 300, Easing.In); + missBar.TransformTo(nameof(BarPath.GlowColour), main_bar_glow_colour, 300, Easing.In); } resetMissBarDelegate?.Cancel(); resetMissBarDelegate = null; } - protected override void Flash(JudgementResult result) + private void updatePath() { - base.Flash(result); + Vector2 diagonalDir = (new Vector2(curve_end, bar_verticality) - new Vector2(curve_start, 0)).Normalized(); - healthBar.TransformTo(nameof(BarPath.GlowColour), health_bar_flash_colour) - .TransformTo(nameof(BarPath.GlowColour), health_bar_glow_colour, 300, Easing.OutQuint); - - if (resetMissBarDelegate == null) + barPath = new SliderPath(new[] { - missBar.TransformTo(nameof(BarPath.BarColour), Colour4.White, 100, Easing.OutQuint) - .Then() - .TransformTo(nameof(BarPath.BarColour), health_bar_colour, 800, Easing.OutQuint); + new PathControlPoint(new Vector2(0, 0), PathType.Linear), + new PathControlPoint(new Vector2(curve_start - curve_smoothness, 0), PathType.Bezier), + new PathControlPoint(new Vector2(curve_start, 0)), + new PathControlPoint(new Vector2(curve_start, 0) + diagonalDir * curve_smoothness, PathType.Linear), + new PathControlPoint(new Vector2(curve_end, bar_verticality) - diagonalDir * curve_smoothness, PathType.Bezier), + new PathControlPoint(new Vector2(curve_end, bar_verticality)), + new PathControlPoint(new Vector2(curve_end + curve_smoothness, bar_verticality), PathType.Linear), + new PathControlPoint(new Vector2(bar_length, bar_verticality)), + }); - missBar.TransformTo(nameof(BarPath.GlowColour), Colour4.White) - .TransformTo(nameof(BarPath.GlowColour), health_bar_glow_colour, 800, Easing.OutQuint); - } - } + List vertices = new List(); + barPath.GetPathToProgress(vertices, 0.0, 1.0); - private double missBarValue = 1.0; - private readonly List missBarVertices = new List(); + background.Vertices = vertices; + healthBar.Vertices = vertices; + missBar.Vertices = vertices; - public double MissBarValue - { - get => missBarValue; - set - { - if (missBarValue == value) - return; - - missBarValue = value; - updatePathVertices(); - } - } - - private double healthBarValue = 1.0; - private readonly List healthBarVertices = new List(); - - public double HealthBarValue - { - get => healthBarValue; - set - { - if (healthBarValue == value) - return; - - healthBarValue = value; - updatePathVertices(); - } + updatePathVertices(); } private void updatePathVertices() From 32b2ac4974d13d98f9abf73f47b6c72a12cd65a1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 3 Oct 2023 17:41:10 +0900 Subject: [PATCH 20/21] Rename and refactor glow/miss bars to hopefully make more sense --- .../Screens/Play/HUD/ArgonHealthDisplay.cs | 74 ++++++++++--------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs index 6d16915576..f7b90fe563 100644 --- a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs @@ -34,8 +34,13 @@ namespace osu.Game.Screens.Play.HUD private const float bar_length = 350; private const float bar_verticality = 32.5f; - private BarPath healthBar = null!; - private BarPath missBar = null!; + private BarPath mainBar = null!; + + /// + /// Used to show a glow at the end of the main bar, or red "damage" area when missing. + /// + private BarPath glowBar = null!; + private BackgroundPath background = null!; private SliderPath barPath = null!; @@ -48,17 +53,17 @@ namespace osu.Game.Screens.Play.HUD private readonly List missBarVertices = new List(); private readonly List healthBarVertices = new List(); - private double missBarValue = 1; + private double glowBarValue = 1; - public double MissBarValue + public double GlowBarValue { - get => missBarValue; + get => glowBarValue; set { - if (missBarValue == value) + if (glowBarValue == value) return; - missBarValue = value; + glowBarValue = value; updatePathVertices(); } } @@ -104,7 +109,7 @@ namespace osu.Game.Screens.Play.HUD { PathRadius = 10f, }, - missBar = new BarPath + glowBar = new BarPath { BarColour = Color4.White, GlowColour = OsuColour.Gray(0.5f), @@ -115,7 +120,7 @@ namespace osu.Game.Screens.Play.HUD Margin = new MarginPadding(-30f), GlowPortion = 0.9f, }, - healthBar = new BarPath + mainBar = new BarPath { AutoSizeAxes = Axes.None, RelativeSizeAxes = Axes.Both, @@ -139,12 +144,12 @@ namespace osu.Game.Screens.Play.HUD Current.BindValueChanged(v => { - if (v.NewValue >= MissBarValue) - finishMissBarUsage(); + if (v.NewValue >= GlowBarValue) + finishMissDisplay(); this.TransformTo(nameof(HealthBarValue), v.NewValue, 300, Easing.OutQuint); if (resetMissBarDelegate == null) - this.TransformTo(nameof(MissBarValue), v.NewValue, 300, Easing.OutQuint); + this.TransformTo(nameof(GlowBarValue), v.NewValue, 300, Easing.OutQuint); }, true); } @@ -152,24 +157,24 @@ namespace osu.Game.Screens.Play.HUD { base.Update(); - healthBar.Alpha = (float)Interpolation.DampContinuously(healthBar.Alpha, Current.Value > 0 ? 1 : 0, 40, Time.Elapsed); - missBar.Alpha = (float)Interpolation.DampContinuously(missBar.Alpha, MissBarValue > 0 ? 1 : 0, 40, Time.Elapsed); + mainBar.Alpha = (float)Interpolation.DampContinuously(mainBar.Alpha, Current.Value > 0 ? 1 : 0, 40, Time.Elapsed); + glowBar.Alpha = (float)Interpolation.DampContinuously(glowBar.Alpha, GlowBarValue > 0 ? 1 : 0, 40, Time.Elapsed); } protected override void Flash(JudgementResult result) { base.Flash(result); - healthBar.TransformTo(nameof(BarPath.GlowColour), main_bar_glow_colour.Opacity(0.8f)) - .TransformTo(nameof(BarPath.GlowColour), main_bar_glow_colour, 300, Easing.OutQuint); + mainBar.TransformTo(nameof(BarPath.GlowColour), main_bar_glow_colour.Opacity(0.8f)) + .TransformTo(nameof(BarPath.GlowColour), main_bar_glow_colour, 300, Easing.OutQuint); if (resetMissBarDelegate == null) { - missBar.TransformTo(nameof(BarPath.BarColour), Colour4.White, 100, Easing.OutQuint) + glowBar.TransformTo(nameof(BarPath.BarColour), Colour4.White, 100, Easing.OutQuint) .Then() .TransformTo(nameof(BarPath.BarColour), main_bar_colour, 800, Easing.OutQuint); - missBar.TransformTo(nameof(BarPath.GlowColour), Colour4.White) + glowBar.TransformTo(nameof(BarPath.GlowColour), Colour4.White) .TransformTo(nameof(BarPath.GlowColour), main_bar_glow_colour, 800, Easing.OutQuint); } } @@ -184,27 +189,30 @@ namespace osu.Game.Screens.Play.HUD resetMissBarDelegate = null; } else - this.TransformTo(nameof(MissBarValue), HealthBarValue); + { + // Reset any ongoing animation immediately, else things get weird. + this.TransformTo(nameof(GlowBarValue), HealthBarValue); + } this.Delay(500).Schedule(() => { - this.TransformTo(nameof(MissBarValue), Current.Value, 300, Easing.OutQuint); - finishMissBarUsage(); + this.TransformTo(nameof(GlowBarValue), Current.Value, 300, Easing.OutQuint); + finishMissDisplay(); }, out resetMissBarDelegate); - missBar.TransformTo(nameof(BarPath.BarColour), new Colour4(255, 147, 147, 255), 100, Easing.OutQuint).Then() + glowBar.TransformTo(nameof(BarPath.BarColour), new Colour4(255, 147, 147, 255), 100, Easing.OutQuint).Then() .TransformTo(nameof(BarPath.BarColour), new Colour4(255, 93, 93, 255), 800, Easing.OutQuint); - missBar.TransformTo(nameof(BarPath.GlowColour), new Colour4(253, 0, 0, 255).Lighten(0.2f)) + glowBar.TransformTo(nameof(BarPath.GlowColour), new Colour4(253, 0, 0, 255).Lighten(0.2f)) .TransformTo(nameof(BarPath.GlowColour), new Colour4(253, 0, 0, 255), 800, Easing.OutQuint); } - private void finishMissBarUsage() + private void finishMissDisplay() { if (Current.Value > 0) { - missBar.TransformTo(nameof(BarPath.BarColour), main_bar_colour, 300, Easing.In); - missBar.TransformTo(nameof(BarPath.GlowColour), main_bar_glow_colour, 300, Easing.In); + glowBar.TransformTo(nameof(BarPath.BarColour), main_bar_colour, 300, Easing.In); + glowBar.TransformTo(nameof(BarPath.GlowColour), main_bar_glow_colour, 300, Easing.In); } resetMissBarDelegate?.Cancel(); @@ -231,8 +239,8 @@ namespace osu.Game.Screens.Play.HUD barPath.GetPathToProgress(vertices, 0.0, 1.0); background.Vertices = vertices; - healthBar.Vertices = vertices; - missBar.Vertices = vertices; + mainBar.Vertices = vertices; + glowBar.Vertices = vertices; updatePathVertices(); } @@ -240,7 +248,7 @@ namespace osu.Game.Screens.Play.HUD private void updatePathVertices() { barPath.GetPathToProgress(healthBarVertices, 0.0, healthBarValue); - barPath.GetPathToProgress(missBarVertices, healthBarValue, Math.Max(missBarValue, healthBarValue)); + barPath.GetPathToProgress(missBarVertices, healthBarValue, Math.Max(glowBarValue, healthBarValue)); if (healthBarVertices.Count == 0) healthBarVertices.Add(Vector2.Zero); @@ -248,11 +256,11 @@ namespace osu.Game.Screens.Play.HUD if (missBarVertices.Count == 0) missBarVertices.Add(Vector2.Zero); - missBar.Vertices = missBarVertices.Select(v => v - missBarVertices[0]).ToList(); - missBar.Position = missBarVertices[0]; + glowBar.Vertices = missBarVertices.Select(v => v - missBarVertices[0]).ToList(); + glowBar.Position = missBarVertices[0]; - healthBar.Vertices = healthBarVertices.Select(v => v - healthBarVertices[0]).ToList(); - healthBar.Position = healthBarVertices[0]; + mainBar.Vertices = healthBarVertices.Select(v => v - healthBarVertices[0]).ToList(); + mainBar.Position = healthBarVertices[0]; } private partial class BackgroundPath : SmoothPath From 4f3c433946173001e90f6768e9a06bc510c04f1b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 3 Oct 2023 17:41:52 +0900 Subject: [PATCH 21/21] Move vertex related constants local to method --- osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs index f7b90fe563..62a4b958c2 100644 --- a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs @@ -27,13 +27,6 @@ namespace osu.Game.Screens.Play.HUD { public bool UsesFixedAnchor { get; set; } - private const float curve_start = 280; - private const float curve_end = 310; - private const float curve_smoothness = 10; - - private const float bar_length = 350; - private const float bar_verticality = 32.5f; - private BarPath mainBar = null!; /// @@ -221,6 +214,13 @@ namespace osu.Game.Screens.Play.HUD private void updatePath() { + const float curve_start = 280; + const float curve_end = 310; + const float curve_smoothness = 10; + + const float bar_length = 350; + const float bar_verticality = 32.5f; + Vector2 diagonalDir = (new Vector2(curve_end, bar_verticality) - new Vector2(curve_start, 0)).Normalized(); barPath = new SliderPath(new[]