From 46e163ec5e81c85c1f58a0129cdf144c327560ae Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 15 Nov 2018 21:28:42 +0900 Subject: [PATCH] Add score display --- .../TestCaseMatchScoreDisplay.cs | 40 +++++ osu.Game.Tournament/IPC/FileBasedIPC.cs | 25 +-- osu.Game.Tournament/IPC/MatchIPCInfo.cs | 19 +++ osu.Game.Tournament/IPC/TourneyState.cs | 14 ++ .../Screens/BeatmapInfoScreen.cs | 2 +- .../Gameplay/{ => Components}/MatchHeader.cs | 8 +- .../Gameplay/Components/MatchScoreDisplay.cs | 144 ++++++++++++++++++ .../Screens/Gameplay/GameplayScreen.cs | 57 ++++++- .../Screens/MapPool/MapPoolScreen.cs | 4 +- osu.Game.Tournament/TournamentGameBase.cs | 2 +- 10 files changed, 277 insertions(+), 38 deletions(-) create mode 100644 osu.Game.Tournament.Tests/TestCaseMatchScoreDisplay.cs create mode 100644 osu.Game.Tournament/IPC/MatchIPCInfo.cs create mode 100644 osu.Game.Tournament/IPC/TourneyState.cs rename osu.Game.Tournament/Screens/Gameplay/{ => Components}/MatchHeader.cs (96%) create mode 100644 osu.Game.Tournament/Screens/Gameplay/Components/MatchScoreDisplay.cs diff --git a/osu.Game.Tournament.Tests/TestCaseMatchScoreDisplay.cs b/osu.Game.Tournament.Tests/TestCaseMatchScoreDisplay.cs new file mode 100644 index 0000000000..62c5ca786b --- /dev/null +++ b/osu.Game.Tournament.Tests/TestCaseMatchScoreDisplay.cs @@ -0,0 +1,40 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.MathUtils; +using osu.Game.Tournament.IPC; +using osu.Game.Tournament.Screens.Gameplay.Components; + +namespace osu.Game.Tournament.Tests +{ + public class TestCaseMatchScoreDisplay : LadderTestCase + { + [Cached(Type = typeof(MatchIPCInfo))] + private MatchIPCInfo matchInfo = new MatchIPCInfo(); + + public TestCaseMatchScoreDisplay() + { + Add(new MatchScoreDisplay + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + Scheduler.AddDelayed(() => + { + int amount = (int)((RNG.NextDouble() - 0.5) * 10000); + if (amount < 0) + matchInfo.Score1.Value -= amount; + else + matchInfo.Score2.Value += amount; + }, 100, true); + } + } +} diff --git a/osu.Game.Tournament/IPC/FileBasedIPC.cs b/osu.Game.Tournament/IPC/FileBasedIPC.cs index 2ad30db748..6759122c16 100644 --- a/osu.Game.Tournament/IPC/FileBasedIPC.cs +++ b/osu.Game.Tournament/IPC/FileBasedIPC.cs @@ -4,8 +4,6 @@ using System; using System.IO; using osu.Framework.Allocation; -using osu.Framework.Configuration; -using osu.Framework.Graphics; using osu.Framework.Logging; using osu.Framework.Platform.Windows; using osu.Game.Beatmaps; @@ -16,16 +14,7 @@ using osu.Game.Rulesets; namespace osu.Game.Tournament.IPC { - public enum TourneyState - { - Initialising, - Idle, - WaitingForClients, - Playing, - Ranking - } - - public class FileBasedIPC : Component + public class FileBasedIPC : MatchIPCInfo { [Resolved] protected APIAccess API { get; private set; } @@ -33,15 +22,7 @@ namespace osu.Game.Tournament.IPC [Resolved] protected RulesetStore Rulesets { get; private set; } - public readonly Bindable Beatmap = new Bindable(); - - public readonly Bindable Mods = new Bindable(); - - public readonly Bindable State = new Bindable(); - private int lastBeatmapId; - public int Score1; - public int Score2; [BackgroundDependencyLoader] private void load() @@ -97,8 +78,8 @@ namespace osu.Game.Tournament.IPC using (var stream = stable.GetStream(file_ipc_scores_filename)) using (var sr = new StreamReader(stream)) { - Score1 = int.Parse(sr.ReadLine()); - Score2 = int.Parse(sr.ReadLine()); + Score1.Value = int.Parse(sr.ReadLine()); + Score2.Value = int.Parse(sr.ReadLine()); } } catch (Exception) diff --git a/osu.Game.Tournament/IPC/MatchIPCInfo.cs b/osu.Game.Tournament/IPC/MatchIPCInfo.cs new file mode 100644 index 0000000000..d40ec35808 --- /dev/null +++ b/osu.Game.Tournament/IPC/MatchIPCInfo.cs @@ -0,0 +1,19 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Legacy; + +namespace osu.Game.Tournament.IPC +{ + public class MatchIPCInfo : Component + { + public Bindable Beatmap { get; } = new Bindable(); + public Bindable Mods { get; } = new Bindable(); + public Bindable State { get; } = new Bindable(); + public BindableInt Score1 { get; } = new BindableInt(); + public BindableInt Score2 { get; } = new BindableInt(); + } +} diff --git a/osu.Game.Tournament/IPC/TourneyState.cs b/osu.Game.Tournament/IPC/TourneyState.cs new file mode 100644 index 0000000000..afa5b400ba --- /dev/null +++ b/osu.Game.Tournament/IPC/TourneyState.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Tournament.IPC +{ + public enum TourneyState + { + Initialising, + Idle, + WaitingForClients, + Playing, + Ranking + } +} diff --git a/osu.Game.Tournament/Screens/BeatmapInfoScreen.cs b/osu.Game.Tournament/Screens/BeatmapInfoScreen.cs index def9f228cf..b75456c1e9 100644 --- a/osu.Game.Tournament/Screens/BeatmapInfoScreen.cs +++ b/osu.Game.Tournament/Screens/BeatmapInfoScreen.cs @@ -24,7 +24,7 @@ namespace osu.Game.Tournament.Screens } [BackgroundDependencyLoader] - private void load(FileBasedIPC ipc) + private void load(MatchIPCInfo ipc) { ipc.Beatmap.BindValueChanged(beatmapChanged, true); ipc.Mods.BindValueChanged(modsChanged, true); diff --git a/osu.Game.Tournament/Screens/Gameplay/MatchHeader.cs b/osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs similarity index 96% rename from osu.Game.Tournament/Screens/Gameplay/MatchHeader.cs rename to osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs index c750694b87..9925f5ef74 100644 --- a/osu.Game.Tournament/Screens/Gameplay/MatchHeader.cs +++ b/osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs @@ -17,7 +17,7 @@ using OpenTK; using OpenTK.Graphics; using OpenTK.Input; -namespace osu.Game.Tournament.Screens.Gameplay +namespace osu.Game.Tournament.Screens.Gameplay.Components { public class MatchHeader : Container { @@ -113,7 +113,7 @@ namespace osu.Game.Tournament.Screens.Gameplay InternalChildren = new Drawable[] { new TeamDisplay(team, colour, flip), - new ScoreDisplay(currentTeamScore, flip, currentMatch.Value.PointsToWin) + new TeamScore(currentTeamScore, flip, currentMatch.Value.PointsToWin) { Colour = colour } @@ -121,12 +121,12 @@ namespace osu.Game.Tournament.Screens.Gameplay } } - private class ScoreDisplay : CompositeDrawable + private class TeamScore : CompositeDrawable { private readonly Bindable currentTeamScore = new Bindable(); private readonly StarCounter counter; - public ScoreDisplay(Bindable score, bool flip, int count) + public TeamScore(Bindable score, bool flip, int count) { var anchor = flip ? Anchor.CentreRight : Anchor.CentreLeft; diff --git a/osu.Game.Tournament/Screens/Gameplay/Components/MatchScoreDisplay.cs b/osu.Game.Tournament/Screens/Gameplay/Components/MatchScoreDisplay.cs new file mode 100644 index 0000000000..2c00c23d42 --- /dev/null +++ b/osu.Game.Tournament/Screens/Gameplay/Components/MatchScoreDisplay.cs @@ -0,0 +1,144 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics.UserInterface; +using osu.Game.Tournament.IPC; +using osu.Game.Tournament.Screens.Ladder.Components; +using OpenTK.Graphics; + +namespace osu.Game.Tournament.Screens.Gameplay.Components +{ + public class MatchScoreDisplay : CompositeDrawable + { + private readonly Color4 red = new Color4(186, 0, 18, 255); + private readonly Color4 blue = new Color4(17, 136, 170, 255); + + private const float bar_height = 20; + + private readonly Bindable currentMatch = new Bindable(); + + private readonly BindableInt score1 = new BindableInt(); + private readonly BindableInt score2 = new BindableInt(); + + private readonly MatchScoreCounter score1Text; + private readonly MatchScoreCounter score2Text; + + private readonly Circle score1Bar; + private readonly Circle score2Bar; + + public MatchScoreDisplay() + { + RelativeSizeAxes = Axes.X; + + InternalChildren = new Drawable[] + { + score1Bar = new Circle + { + Name = "top bar red", + RelativeSizeAxes = Axes.X, + Height = bar_height, + Width = 0, + Colour = red, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopRight + }, + score1Text = new MatchScoreCounter + { + Colour = red, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre + }, + score2Bar = new Circle + { + Name = "top bar blue", + RelativeSizeAxes = Axes.X, + Height = bar_height, + Width = 0, + Colour = blue, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopLeft + }, + score2Text = new MatchScoreCounter + { + Colour = blue, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre + }, + }; + } + + [BackgroundDependencyLoader] + private void load(LadderInfo ladder, MatchIPCInfo ipc) + { + currentMatch.BindTo(ladder.CurrentMatch); + + score1.BindValueChanged(_ => updateScores()); + score1.BindTo(ipc.Score1); + + score2.BindValueChanged(_ => updateScores()); + score2.BindTo(ipc.Score2); + } + + private void updateScores() + { + score1Text.Current.Value = score1.Value; + score2Text.Current.Value = score2.Value; + + var winningText = score1.Value > score2.Value ? score1Text : score2Text; + var losingText = score1.Value <= score2.Value ? score1Text : score2Text; + + winningText.Winning = true; + losingText.Winning = false; + + var winningBar = score1.Value > score2.Value ? score1Bar : score2Bar; + var losingBar = score1.Value <= score2.Value ? score1Bar : score2Bar; + + var diff = Math.Max(score1.Value, score2.Value) - Math.Min(score1.Value, score2.Value); + + losingBar.ResizeWidthTo(0, 400, Easing.OutQuint); + winningBar.ResizeWidthTo((float)Math.Pow(diff / 1000000f, 0.5), 400, Easing.OutQuint); + } + + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); + + score1Text.X = -Math.Max(score1Text.DrawWidth / 2, score1Bar.DrawWidth); + score2Text.X = Math.Max(score2Text.DrawWidth / 2, score2Bar.DrawWidth); + } + + private class MatchScoreCounter : ScoreCounter + { + public MatchScoreCounter() + { + Margin = new MarginPadding { Top = bar_height + 5, Horizontal = 10 }; + Winning = false; + + DisplayedCountSpriteText.FixedWidth = false; + } + + public bool Winning + { + set + { + if (value) + { + DisplayedCountSpriteText.Font = "Aquatico-Regular"; + DisplayedCountSpriteText.TextSize = 60; + } + else + { + DisplayedCountSpriteText.Font = "Aquatico-Light"; + DisplayedCountSpriteText.TextSize = 40; + } + } + } + } + } +} diff --git a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs index 99d996d138..a86c47839b 100644 --- a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs +++ b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs @@ -4,12 +4,14 @@ using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Textures; using osu.Framework.Threading; using osu.Game.Graphics.UserInterface; using osu.Game.Tournament.Components; using osu.Game.Tournament.IPC; +using osu.Game.Tournament.Screens.Gameplay.Components; using osu.Game.Tournament.Screens.Ladder.Components; using OpenTK.Graphics; @@ -23,23 +25,62 @@ namespace osu.Game.Tournament.Screens.Gameplay public readonly Bindable State = new Bindable(); private TriangleButton warmupButton; - private FileBasedIPC ipc; + private MatchIPCInfo ipc; + + private readonly Color4 red = new Color4(186, 0, 18, 255); + private readonly Color4 blue = new Color4(17, 136, 170, 255); [BackgroundDependencyLoader] - private void load(LadderInfo ladder, TextureStore textures, FileBasedIPC ipc) + private void load(LadderInfo ladder, TextureStore textures, MatchIPCInfo ipc) { this.ipc = ipc; AddRange(new Drawable[] { new MatchHeader(), - new Box + new FillFlowContainer { - RelativeSizeAxes = Axes.Both, - Height = 718 / 1080f, - Colour = new Color4(0, 255, 0, 255), - Y = 14, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, Anchor = Anchor.Centre, - Origin= Anchor.Centre, + Origin = Anchor.Centre, + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + new Circle + { + Name = "top bar red", + RelativeSizeAxes = Axes.X, + Height = 10, + Width = 0.5f, + Colour = red, + }, + new Circle + { + Name = "top bar blue", + RelativeSizeAxes = Axes.X, + Height = 10, + Width = 0.5f, + Colour = blue, + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + }, + } + }, + new Box + { + // chroma key area for stable gameplay + Name = "chroma", + RelativeSizeAxes = Axes.X, + Height = 480, + Colour = new Color4(0, 255, 0, 255), + }, + } }, new ControlPanel { diff --git a/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs b/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs index 5a463c6d5e..c2cefd8c41 100644 --- a/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs +++ b/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs @@ -12,7 +12,7 @@ using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Tournament.Components; using osu.Game.Tournament.IPC; -using osu.Game.Tournament.Screens.Gameplay; +using osu.Game.Tournament.Screens.Gameplay.Components; using osu.Game.Tournament.Screens.Ladder.Components; using OpenTK; using OpenTK.Graphics; @@ -92,7 +92,7 @@ namespace osu.Game.Tournament.Screens.MapPool } [BackgroundDependencyLoader] - private void load(LadderInfo ladder, FileBasedIPC ipc) + private void load(LadderInfo ladder, MatchIPCInfo ipc) { currentMatch.BindValueChanged(matchChanged); currentMatch.BindTo(ladder.CurrentMatch); diff --git a/osu.Game.Tournament/TournamentGameBase.cs b/osu.Game.Tournament/TournamentGameBase.cs index 8a2e6471c1..31a3c162f5 100644 --- a/osu.Game.Tournament/TournamentGameBase.cs +++ b/osu.Game.Tournament/TournamentGameBase.cs @@ -72,7 +72,7 @@ namespace osu.Game.Tournament dependencies.Cache(Ladder); - dependencies.Cache(ipc = new FileBasedIPC()); + dependencies.CacheAs(ipc = new FileBasedIPC()); Add(ipc); bool addedInfo = false;