diff --git a/osu.Game/Modes/Score.cs b/osu.Game/Modes/Score.cs index 88d79f94dd..ee90a9a0f9 100644 --- a/osu.Game/Modes/Score.cs +++ b/osu.Game/Modes/Score.cs @@ -11,7 +11,9 @@ namespace osu.Game.Modes { public class Score { - public double TotalScore { get; } - public double Accuracy { get; } + public double TotalScore { get; set; } + public double Accuracy { get; set; } + public double Combo { get; set; } + public double MaxCombo { get; set; } } } diff --git a/osu.Game/Modes/ScoreProcesssor.cs b/osu.Game/Modes/ScoreProcesssor.cs index d94a424098..a34915eaef 100644 --- a/osu.Game/Modes/ScoreProcesssor.cs +++ b/osu.Game/Modes/ScoreProcesssor.cs @@ -13,7 +13,13 @@ namespace osu.Game.Modes { public abstract class ScoreProcessor { - public virtual Score GetScore() => new Score(); + public virtual Score GetScore() => new Score() + { + TotalScore = TotalScore, + Combo = Combo, + MaxCombo = HighestCombo, + Accuracy = Accuracy + }; public readonly BindableDouble TotalScore = new BindableDouble { MinValue = 0 }; diff --git a/osu.Game/Modes/UI/HitRenderer.cs b/osu.Game/Modes/UI/HitRenderer.cs index 5d70fd71a0..bd191a47a3 100644 --- a/osu.Game/Modes/UI/HitRenderer.cs +++ b/osu.Game/Modes/UI/HitRenderer.cs @@ -16,10 +16,19 @@ namespace osu.Game.Modes.UI { public event Action OnJudgement; - protected void TriggerOnJudgement(JudgementInfo j) => OnJudgement?.Invoke(j); + public event Action OnAllJudged; + + protected void TriggerOnJudgement(JudgementInfo j) + { + OnJudgement?.Invoke(j); + if (AllObjectsJudged) + OnAllJudged?.Invoke(); + } protected Playfield Playfield; + public bool AllObjectsJudged => Playfield.HitObjects.Children.First()?.Judgement.Result != null; //reverse depth sort means First() instead of Last(). + public IEnumerable DrawableObjects => Playfield.HitObjects.Children; } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 1fa652afec..2f35f1b5d5 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -19,6 +19,7 @@ using OpenTK.Input; using MouseState = osu.Framework.Input.MouseState; using OpenTK; using osu.Framework.GameModes; +using osu.Game.Modes.UI; using osu.Game.Screens.Ranking; namespace osu.Game.Screens.Play @@ -40,6 +41,7 @@ namespace osu.Game.Screens.Play private Ruleset ruleset; private ScoreProcessor scoreProcessor; + private HitRenderer hitRenderer; [BackgroundDependencyLoader] private void load(AudioManager audio, BeatmapDatabase beatmaps, OsuGameBase game) @@ -89,9 +91,10 @@ namespace osu.Game.Screens.Play var scoreOverlay = ruleset.CreateScoreOverlay(); scoreOverlay.BindProcessor(scoreProcessor = ruleset.CreateScoreProcessor()); - var hitRenderer = ruleset.CreateHitRendererWith(beatmap.HitObjects); + hitRenderer = ruleset.CreateHitRendererWith(beatmap.HitObjects); hitRenderer.OnJudgement += scoreProcessor.AddJudgement; + hitRenderer.OnAllJudged += hitRenderer_OnAllJudged; if (Autoplay) hitRenderer.Schedule(() => hitRenderer.DrawableObjects.ForEach(h => h.State = ArmedState.Hit)); @@ -110,6 +113,18 @@ namespace osu.Game.Screens.Play }; } + private void hitRenderer_OnAllJudged() + { + Delay(1000); + Schedule(delegate + { + Push(new Results + { + Score = scoreProcessor.GetScore() + }); + }); + } + protected override void OnEntering(GameMode last) { base.OnEntering(last); @@ -121,12 +136,6 @@ namespace osu.Game.Screens.Play { base.Update(); Clock.ProcessFrame(); - - if (Beatmap.Track.HasCompleted) - Push(new Results - { - Score = scoreProcessor.GetScore() - }); } class PlayerInputManager : UserInputManager diff --git a/osu.Game/Screens/Ranking/Results.cs b/osu.Game/Screens/Ranking/Results.cs index 55f2d4fe2b..a4219daf54 100644 --- a/osu.Game/Screens/Ranking/Results.cs +++ b/osu.Game/Screens/Ranking/Results.cs @@ -2,20 +2,29 @@ //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.GameModes; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Transformations; using osu.Game.Modes; using osu.Game.Screens.Backgrounds; +using OpenTK; using OpenTK.Graphics; namespace osu.Game.Screens.Ranking { - class Results : GameModeWhiteBox + class Results : OsuGameMode { - protected override BackgroundMode CreateBackground() => new BackgroundModeCustom(@"Backgrounds/bg4"); + protected override BackgroundMode CreateBackground() => new BackgroundModeBeatmap(Beatmap); + + private static readonly Vector2 BACKGROUND_BLUR = new Vector2(20); + + ScoreDisplay scoreDisplay; protected override void OnEntering(GameMode last) { base.OnEntering(last); - Background.Schedule(() => Background.FadeColour(Color4.DarkGray, 500)); + Background.Schedule(() => (Background as BackgroundModeBeatmap)?.BlurTo(BACKGROUND_BLUR, 1000)); } protected override bool OnExiting(GameMode next) @@ -24,6 +33,62 @@ namespace osu.Game.Screens.Ranking return base.OnExiting(next); } - public Score Score { get; set; } + public Score Score + { + set + { + scoreDisplay?.FadeOut(500); + scoreDisplay?.Expire(); + + scoreDisplay = new ScoreDisplay(value) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }; + + Add(scoreDisplay); + + scoreDisplay.FadeIn(500); + scoreDisplay.ScaleTo(0.1f); + scoreDisplay.ScaleTo(1, 1000, EasingTypes.OutElastic); + scoreDisplay.RotateTo(360 * 5, 1000, EasingTypes.OutElastic); + + } + } + } + + class ScoreDisplay : Container + { + public ScoreDisplay(Score s) + { + AutoSizeAxes = Axes.Both; + + Children = new Drawable[] + { + new FlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FlowDirection.VerticalOnly, + Children = new Drawable[] + { + new SpriteText + { + TextSize = 40, + Text = $@"Accuracy: {s.Accuracy:#0.00%}", + }, + new SpriteText + { + TextSize = 40, + Text = $@"Score: {s.TotalScore}", + }, + new SpriteText + { + TextSize = 40, + Text = $@"MaxCombo: {s.MaxCombo}", + } + } + } + }; + } } }