mirror of
https://github.com/ppy/osu.git
synced 2025-03-24 11:07:20 +08:00
Add Display, Counter, Tests
This commit is contained in:
parent
f798951f09
commit
4c17b27273
136
osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs
Normal file
136
osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs
Normal file
@ -0,0 +1,136 @@
|
||||
// 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;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Mania;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Osu.Judgements;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.Play.HUD.JudgementCounter;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
public partial class TestSceneJudgementCounter : OsuTestScene
|
||||
{
|
||||
private ScoreProcessor scoreProcessor = null!;
|
||||
private JudgementTally judgementTally = null!;
|
||||
private TestJudgementCounterDisplay counter = null!;
|
||||
|
||||
private readonly Bindable<JudgementResult> lastJudgementResult = new Bindable<JudgementResult>();
|
||||
|
||||
private int iteration;
|
||||
|
||||
[SetUpSteps]
|
||||
public void SetupSteps() => AddStep("Create components", () =>
|
||||
{
|
||||
var ruleset = CreateRuleset();
|
||||
|
||||
Debug.Assert(ruleset != null);
|
||||
|
||||
scoreProcessor = new ScoreProcessor(ruleset);
|
||||
Child = new DependencyProvidingContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
CachedDependencies = new (Type, object)[] { (typeof(ScoreProcessor), scoreProcessor), (typeof(Ruleset), ruleset) },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
judgementTally = new JudgementTally(),
|
||||
new DependencyProvidingContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
CachedDependencies = new (Type, object)[] { (typeof(JudgementTally), judgementTally) },
|
||||
Child = counter = new TestJudgementCounterDisplay
|
||||
{
|
||||
Margin = new MarginPadding { Top = 100 },
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
protected override Ruleset CreateRuleset() => new ManiaRuleset();
|
||||
|
||||
private void applyOneJudgement(HitResult result)
|
||||
{
|
||||
lastJudgementResult.Value = new OsuJudgementResult(new HitObject
|
||||
{
|
||||
StartTime = iteration * 10000
|
||||
}, new OsuJudgement())
|
||||
{
|
||||
Type = result,
|
||||
};
|
||||
scoreProcessor.ApplyResult(lastJudgementResult.Value);
|
||||
|
||||
iteration++;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddJudgementsToCounters()
|
||||
{
|
||||
AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.Great), 2);
|
||||
AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.Miss), 2);
|
||||
AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.Meh), 2);
|
||||
AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.LargeTickHit), 2);
|
||||
AddStep("Show all judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.All);
|
||||
AddAssert("Check value added whilst hidden", () => hiddenCount() == 2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddWhilstHidden()
|
||||
{
|
||||
AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.LargeTickHit), 2);
|
||||
AddAssert("Check value added whilst hidden", () => hiddenCount() == 2);
|
||||
AddStep("Show all judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.All);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestChangeFlowDirection()
|
||||
{
|
||||
AddStep("Set direction vertical", () => counter.Direction.Value = FillDirection.Vertical);
|
||||
AddStep("Set direction horizontal", () => counter.Direction.Value = FillDirection.Vertical);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestHideJudgementNames()
|
||||
{
|
||||
AddStep("Hide judgement names", () => counter.ShowName.Value = false);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestHideMaxValue()
|
||||
{
|
||||
AddStep("Hide max judgement", () => counter.ShowMax.Value = false);
|
||||
AddStep("Show max judgement", () => counter.ShowMax.Value = true);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCycleDisplayModes()
|
||||
{
|
||||
AddStep("Show all judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.All);
|
||||
AddStep("Show normal judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.Normal);
|
||||
AddStep("Show basic judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.Simple);
|
||||
}
|
||||
|
||||
private int hiddenCount()
|
||||
{
|
||||
var num = counter.JudgementContainer.Children.OfType<JudgementCounter>().First(child => child.Result.ResultInfo.Type == HitResult.LargeTickHit);
|
||||
return num.Result.ResultCount.Value;
|
||||
}
|
||||
|
||||
private partial class TestJudgementCounterDisplay : JudgementCounterDisplay
|
||||
{
|
||||
public new FillFlowContainer JudgementContainer => base.JudgementContainer;
|
||||
}
|
||||
}
|
||||
}
|
118
osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs
Normal file
118
osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs
Normal file
@ -0,0 +1,118 @@
|
||||
// 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.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD.JudgementCounter
|
||||
{
|
||||
public partial class JudgementCounter : OverlayContainer
|
||||
{
|
||||
public BindableBool ShowName = new BindableBool();
|
||||
public Bindable<FillDirection> Direction = new Bindable<FillDirection>();
|
||||
|
||||
public readonly JudgementCounterInfo Result;
|
||||
|
||||
public JudgementCounter(JudgementCounterInfo result)
|
||||
{
|
||||
Result = result;
|
||||
}
|
||||
|
||||
private OsuSpriteText resultName = null!;
|
||||
private FillFlowContainer flowContainer = null!;
|
||||
private JudgementRollingCounter counter = null!;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
InternalChild = flowContainer = new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
counter = new JudgementRollingCounter
|
||||
{
|
||||
Current = Result.ResultCount
|
||||
},
|
||||
resultName = new OsuSpriteText
|
||||
{
|
||||
Font = OsuFont.Numeric.With(size: 8),
|
||||
Text = Result.ResultInfo.Displayname
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var result = Result.ResultInfo.Type;
|
||||
|
||||
if (result.IsBasic())
|
||||
{
|
||||
Colour = colours.ForHitResult(Result.ResultInfo.Type);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!result.IsBonus())
|
||||
{
|
||||
Colour = colours.PurpleLight;
|
||||
return;
|
||||
}
|
||||
|
||||
Colour = colours.PurpleLighter;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
ShowName.BindValueChanged(value =>
|
||||
{
|
||||
if (value.NewValue)
|
||||
{
|
||||
resultName.Show();
|
||||
return;
|
||||
}
|
||||
|
||||
resultName.Hide();
|
||||
}, true);
|
||||
|
||||
Direction.BindValueChanged(direction =>
|
||||
{
|
||||
flowContainer.Direction = direction.NewValue;
|
||||
|
||||
if (direction.NewValue == FillDirection.Vertical)
|
||||
{
|
||||
changeAnchor(Anchor.TopLeft);
|
||||
return;
|
||||
}
|
||||
|
||||
changeAnchor(Anchor.BottomLeft);
|
||||
|
||||
void changeAnchor(Anchor anchor) => counter.Anchor = resultName.Anchor = counter.Origin = resultName.Origin = anchor;
|
||||
}, true);
|
||||
|
||||
base.LoadComplete();
|
||||
}
|
||||
|
||||
protected override void PopIn()
|
||||
{
|
||||
this.FadeInFromZero(500, Easing.OutQuint);
|
||||
}
|
||||
|
||||
protected override void PopOut()
|
||||
{
|
||||
this.FadeOut(100);
|
||||
}
|
||||
|
||||
private sealed partial class JudgementRollingCounter : RollingCounter<int>
|
||||
{
|
||||
protected override OsuSpriteText CreateSpriteText()
|
||||
=> base.CreateSpriteText().With(s => s.Font = s.Font.With(fixedWidth: true, size: 16));
|
||||
|
||||
protected override double RollingDuration => 750;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,133 @@
|
||||
// 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;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Skinning;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD.JudgementCounter
|
||||
{
|
||||
public partial class JudgementCounterDisplay : CompositeDrawable, ISkinnableDrawable
|
||||
{
|
||||
public bool UsesFixedAnchor { get; set; }
|
||||
|
||||
[SettingSource("Counter direction")]
|
||||
public Bindable<FillDirection> Direction { get; set; } = new Bindable<FillDirection>();
|
||||
|
||||
[SettingSource("Show judgement names")]
|
||||
public BindableBool ShowName { get; set; } = new BindableBool(true);
|
||||
|
||||
[SettingSource("Show max judgement")]
|
||||
public BindableBool ShowMax { get; set; } = new BindableBool(true);
|
||||
|
||||
[SettingSource("Display mode")]
|
||||
public Bindable<DisplayMode> Mode { get; set; } = new Bindable<DisplayMode>();
|
||||
|
||||
[Resolved]
|
||||
private JudgementTally tally { get; set; } = null!;
|
||||
|
||||
protected FillFlowContainer JudgementContainer = null!;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
InternalChild = JudgementContainer = new FillFlowContainer
|
||||
{
|
||||
Direction = Direction.Value,
|
||||
Spacing = new Vector2(10),
|
||||
AutoSizeAxes = Axes.Both
|
||||
};
|
||||
|
||||
foreach (var result in tally.Results)
|
||||
{
|
||||
JudgementContainer.Add(createCounter(result));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
Size = JudgementContainer.Size;
|
||||
base.Update();
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
Direction.BindValueChanged(direction => JudgementContainer.Direction = direction.NewValue);
|
||||
Mode.BindValueChanged(_ => updateCounter(), true);
|
||||
|
||||
ShowMax.BindValueChanged(value =>
|
||||
{
|
||||
var firstChild = JudgementContainer.Children.FirstOrDefault();
|
||||
|
||||
if (value.NewValue)
|
||||
{
|
||||
firstChild?.Show();
|
||||
return;
|
||||
}
|
||||
|
||||
firstChild?.Hide();
|
||||
}, true);
|
||||
}
|
||||
|
||||
private void updateCounter()
|
||||
{
|
||||
var counters = JudgementContainer.Children.OfType<JudgementCounter>().ToList();
|
||||
|
||||
switch (Mode.Value)
|
||||
{
|
||||
case DisplayMode.Simple:
|
||||
foreach (var counter in counters.Where(counter => counter.Result.ResultInfo.Type.IsBasic()))
|
||||
counter.Show();
|
||||
|
||||
foreach (var counter in counters.Where(counter => !counter.Result.ResultInfo.Type.IsBasic()))
|
||||
counter.Hide();
|
||||
|
||||
break;
|
||||
|
||||
case DisplayMode.Normal:
|
||||
foreach (var counter in counters.Where(counter => !counter.Result.ResultInfo.Type.IsBonus()))
|
||||
counter.Show();
|
||||
|
||||
foreach (var counter in counters.Where(counter => counter.Result.ResultInfo.Type.IsBonus()))
|
||||
counter.Hide();
|
||||
|
||||
break;
|
||||
|
||||
case DisplayMode.All:
|
||||
foreach (JudgementCounter counter in counters.Where(counter => !counter.IsPresent))
|
||||
counter.Show();
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public enum DisplayMode
|
||||
{
|
||||
Simple,
|
||||
Normal,
|
||||
All
|
||||
}
|
||||
|
||||
private JudgementCounter createCounter(JudgementCounterInfo info)
|
||||
{
|
||||
JudgementCounter counter = new JudgementCounter(info)
|
||||
{
|
||||
ShowName = { BindTarget = ShowName },
|
||||
Direction = { BindTarget = Direction }
|
||||
};
|
||||
return counter;
|
||||
}
|
||||
}
|
||||
}
|
@ -9,8 +9,8 @@ using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD.JudgementCounter
|
||||
{
|
||||
@ -22,14 +22,14 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter
|
||||
public List<JudgementCounterInfo> Results = new List<JudgementCounterInfo>();
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(DrawableRuleset ruleset)
|
||||
private void load(IBindable<WorkingBeatmap> working)
|
||||
{
|
||||
foreach (var result in ruleset.Ruleset.GetHitResults())
|
||||
foreach (var result in working.Value.BeatmapInfo.Ruleset.CreateInstance().GetHitResults())
|
||||
{
|
||||
Results.Add(new JudgementCounterInfo
|
||||
{
|
||||
ResultInfo = (result.result, result.displayName),
|
||||
ResultCount = new BindableInt(),
|
||||
ResultCount = new BindableInt()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user