Merge pull request #7317 from EVAST9919/colour-score-meter

Implement ColourHitErrorMeter
This commit is contained in:
Dean Herbert 2020-01-24 12:28:03 +09:00 committed by GitHub
commit 8122bdf2d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 192 additions and 31 deletions

View File

@ -19,18 +19,22 @@ using osu.Game.Screens.Play.HUD.HitErrorMeters;
namespace osu.Game.Tests.Visual.Gameplay
{
public class TestSceneBarHitErrorMeter : OsuTestScene
public class TestSceneHitErrorMeter : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(HitErrorMeter),
typeof(BarHitErrorMeter),
typeof(ColourHitErrorMeter)
};
private HitErrorMeter meter;
private HitErrorMeter meter2;
private BarHitErrorMeter barMeter;
private BarHitErrorMeter barMeter2;
private ColourHitErrorMeter colourMeter;
private ColourHitErrorMeter colourMeter2;
private HitWindows hitWindows;
public TestSceneBarHitErrorMeter()
public TestSceneHitErrorMeter()
{
recreateDisplay(new OsuHitWindows(), 5);
@ -91,17 +95,31 @@ namespace osu.Game.Tests.Visual.Gameplay
}
});
Add(meter = new BarHitErrorMeter(hitWindows, true)
Add(barMeter = new BarHitErrorMeter(hitWindows, true)
{
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
});
Add(meter2 = new BarHitErrorMeter(hitWindows, false)
Add(barMeter2 = new BarHitErrorMeter(hitWindows, false)
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
});
Add(colourMeter = new ColourHitErrorMeter(hitWindows)
{
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
Margin = new MarginPadding { Right = 50 }
});
Add(colourMeter2 = new ColourHitErrorMeter(hitWindows)
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Margin = new MarginPadding { Left = 50 }
});
}
private void newJudgement(double offset = 0)
@ -112,8 +130,10 @@ namespace osu.Game.Tests.Visual.Gameplay
Type = HitResult.Perfect,
};
meter.OnNewJudgement(judgement);
meter2.OnNewJudgement(judgement);
barMeter.OnNewJudgement(judgement);
barMeter2.OnNewJudgement(judgement);
colourMeter.OnNewJudgement(judgement);
colourMeter2.OnNewJudgement(judgement);
}
}
}

View File

@ -18,5 +18,14 @@ namespace osu.Game.Configuration
[Description("Hit Error (both)")]
HitErrorBoth,
[Description("Colour (left)")]
ColourLeft,
[Description("Colour (right)")]
ColourRight,
[Description("Colour (both)")]
ColourBoth,
}
}

View File

@ -77,6 +77,19 @@ namespace osu.Game.Screens.Play.HUD
case ScoreMeterType.HitErrorRight:
createBar(true);
break;
case ScoreMeterType.ColourBoth:
createColour(false);
createColour(true);
break;
case ScoreMeterType.ColourLeft:
createColour(false);
break;
case ScoreMeterType.ColourRight:
createColour(true);
break;
}
}
@ -90,6 +103,24 @@ namespace osu.Game.Screens.Play.HUD
Alpha = 0,
};
completeDisplayLoading(display);
}
private void createColour(bool rightAligned)
{
var display = new ColourHitErrorMeter(hitWindows)
{
Margin = new MarginPadding(margin),
Anchor = rightAligned ? Anchor.CentreRight : Anchor.CentreLeft,
Origin = rightAligned ? Anchor.CentreRight : Anchor.CentreLeft,
Alpha = 0,
};
completeDisplayLoading(display);
}
private void completeDisplayLoading(HitErrorMeter display)
{
Add(display);
display.FadeInFromZero(fade_duration, Easing.OutQuint);
}

View File

@ -163,30 +163,9 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
centre.Width = 2.5f;
colourBars.Add(centre);
Color4 getColour(HitResult result)
{
switch (result)
{
case HitResult.Meh:
return colours.Yellow;
case HitResult.Ok:
return colours.Green;
case HitResult.Good:
return colours.GreenLight;
case HitResult.Great:
return colours.Blue;
default:
return colours.BlueLight;
}
}
Drawable createColourBar(HitResult result, float height, bool first = false)
{
var colour = getColour(result);
var colour = GetColourForHitResult(result);
if (first)
{
@ -201,7 +180,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = getColour(result),
Colour = colour,
Height = height * gradient_start
},
new Box

View File

@ -0,0 +1,92 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Scoring;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Screens.Play.HUD.HitErrorMeters
{
public class ColourHitErrorMeter : HitErrorMeter
{
private const int animation_duration = 200;
private readonly JudgementFlow judgementsFlow;
public ColourHitErrorMeter(HitWindows hitWindows)
: base(hitWindows)
{
AutoSizeAxes = Axes.Both;
InternalChild = judgementsFlow = new JudgementFlow();
}
public override void OnNewJudgement(JudgementResult judgement) => judgementsFlow.Push(GetColourForHitResult(HitWindows.ResultFor(judgement.TimeOffset)));
private class JudgementFlow : FillFlowContainer<HitErrorCircle>
{
private const int max_available_judgements = 20;
private const int drawable_judgement_size = 8;
private const int spacing = 2;
public override IEnumerable<Drawable> FlowingChildren => base.FlowingChildren.Reverse();
public JudgementFlow()
{
AutoSizeAxes = Axes.X;
Height = max_available_judgements * (drawable_judgement_size + spacing) - spacing;
Spacing = new Vector2(0, spacing);
Direction = FillDirection.Vertical;
LayoutDuration = animation_duration;
LayoutEasing = Easing.OutQuint;
}
public void Push(Color4 colour)
{
Add(new HitErrorCircle(colour, drawable_judgement_size));
if (Children.Count > max_available_judgements)
Children.FirstOrDefault(c => !c.IsRemoved)?.Remove();
}
}
private class HitErrorCircle : Container
{
public bool IsRemoved { get; private set; }
private readonly Circle circle;
public HitErrorCircle(Color4 colour, int size)
{
Size = new Vector2(size);
Child = circle = new Circle
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
Colour = colour
};
}
protected override void LoadComplete()
{
base.LoadComplete();
circle.FadeInFromZero(animation_duration, Easing.OutQuint);
circle.MoveToY(-DrawSize.Y);
circle.MoveToY(0, animation_duration, Easing.OutQuint);
}
public void Remove()
{
IsRemoved = true;
this.FadeOut(animation_duration, Easing.OutQuint).Expire();
}
}
}
}

View File

@ -1,9 +1,12 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Scoring;
using osuTK.Graphics;
namespace osu.Game.Screens.Play.HUD.HitErrorMeters
{
@ -11,11 +14,38 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
{
protected readonly HitWindows HitWindows;
[Resolved]
private OsuColour colours { get; set; }
protected HitErrorMeter(HitWindows hitWindows)
{
HitWindows = hitWindows;
}
public abstract void OnNewJudgement(JudgementResult judgement);
protected Color4 GetColourForHitResult(HitResult result)
{
switch (result)
{
case HitResult.Miss:
return colours.Red;
case HitResult.Meh:
return colours.Yellow;
case HitResult.Ok:
return colours.Green;
case HitResult.Good:
return colours.GreenLight;
case HitResult.Great:
return colours.Blue;
default:
return colours.BlueLight;
}
}
}
}