diff --git a/osu-framework b/osu-framework index 9d142a8e00..5f19dd913d 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 9d142a8e009794dfee828392e36025d08577131d +Subproject commit 5f19dd913dfc69013a3b9cf30ccfd9c44881a321 diff --git a/osu.Game/Beatmaps/Timing/BreakPeriod.cs b/osu.Game/Beatmaps/Timing/BreakPeriod.cs index fb307b7144..0cf4a0c65b 100644 --- a/osu.Game/Beatmaps/Timing/BreakPeriod.cs +++ b/osu.Game/Beatmaps/Timing/BreakPeriod.cs @@ -8,7 +8,7 @@ namespace osu.Game.Beatmaps.Timing /// /// The minimum duration required for a break to have any effect. /// - private const double min_break_duration = 650; + public const double MIN_BREAK_DURATION = 650; /// /// The break start time. @@ -28,6 +28,6 @@ namespace osu.Game.Beatmaps.Timing /// /// Whether the break has any effect. Breaks that are too short are culled before they are added to the beatmap. /// - public bool HasEffect => Duration >= min_break_duration; + public bool HasEffect => Duration >= MIN_BREAK_DURATION; } -} +} \ No newline at end of file diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index deb87e92d8..0b631a7148 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -51,6 +51,11 @@ namespace osu.Game.Rulesets.Scoring /// public readonly BindableInt Combo = new BindableInt(); + /// + /// The current rank. + /// + public readonly Bindable Rank = new Bindable(ScoreRank.X); + /// /// THe highest combo achieved by this score. /// @@ -74,6 +79,7 @@ namespace osu.Game.Rulesets.Scoring protected ScoreProcessor() { Combo.ValueChanged += delegate { HighestCombo.Value = Math.Max(HighestCombo.Value, Combo.Value); }; + Accuracy.ValueChanged += delegate { Rank.Value = rankFrom(Accuracy.Value); }; } private ScoreRank rankFrom(double acc) @@ -101,6 +107,7 @@ namespace osu.Game.Rulesets.Scoring Accuracy.Value = 1; Health.Value = 1; Combo.Value = 0; + Rank.Value = ScoreRank.X; HighestCombo.Value = 0; alreadyFailed = false; @@ -142,7 +149,7 @@ namespace osu.Game.Rulesets.Scoring score.Combo = Combo; score.MaxCombo = HighestCombo; score.Accuracy = Accuracy; - score.Rank = rankFrom(Accuracy); + score.Rank = Rank; score.Date = DateTimeOffset.Now; score.Health = Health; } diff --git a/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs new file mode 100644 index 0000000000..0b775d5c35 --- /dev/null +++ b/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs @@ -0,0 +1,103 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; +using OpenTK; +using osu.Game.Graphics.Containers; +using osu.Game.Beatmaps.Timing; + +namespace osu.Game.Screens.Play.BreaksOverlay +{ + public class ArrowsOverlay : VisibilityContainer + { + private const double fade_duration = BreakPeriod.MIN_BREAK_DURATION / 2; + + private const int glow_icon_size = 60; + private const int glow_icon_blur_sigma = 10; + private const float glow_icon_final_offset = 0.22f; + private const float glow_icon_offscreen_offset = 0.6f; + + private const int blurred_icon_blur_sigma = 20; + private const int blurred_icon_size = 130; + private const float blurred_icon_final_offset = 0.35f; + private const float blurred_icon_offscreen_offset = 0.7f; + + private readonly GlowIcon leftGlowIcon; + private readonly GlowIcon rightGlowIcon; + + private readonly BlurredIcon leftBlurredIcon; + private readonly BlurredIcon rightBlurredIcon; + + public ArrowsOverlay() + { + RelativeSizeAxes = Axes.Both; + Children = new Drawable[] + { + leftGlowIcon = new GlowIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.CentreRight, + X = -glow_icon_offscreen_offset, + Icon = Graphics.FontAwesome.fa_chevron_right, + BlurSigma = new Vector2(glow_icon_blur_sigma), + Size = new Vector2(glow_icon_size), + }, + rightGlowIcon = new GlowIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.CentreLeft, + X = glow_icon_offscreen_offset, + Icon = Graphics.FontAwesome.fa_chevron_left, + BlurSigma = new Vector2(glow_icon_blur_sigma), + Size = new Vector2(glow_icon_size), + }, + new ParallaxContainer + { + ParallaxAmount = -0.02f, + Children = new Drawable[] + { + leftBlurredIcon = new BlurredIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.CentreRight, + Alpha = 0.7f, + X = -blurred_icon_offscreen_offset, + Icon = Graphics.FontAwesome.fa_chevron_right, + BlurSigma = new Vector2(blurred_icon_blur_sigma), + Size = new Vector2(blurred_icon_size), + }, + rightBlurredIcon = new BlurredIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.CentreLeft, + Alpha = 0.7f, + X = blurred_icon_offscreen_offset, + Icon = Graphics.FontAwesome.fa_chevron_left, + BlurSigma = new Vector2(blurred_icon_blur_sigma), + Size = new Vector2(blurred_icon_size), + }, + } + } + }; + } + + protected override void PopIn() + { + leftGlowIcon.MoveToX(-glow_icon_final_offset, fade_duration, Easing.OutQuint); + rightGlowIcon.MoveToX(glow_icon_final_offset, fade_duration, Easing.OutQuint); + + leftBlurredIcon.MoveToX(-blurred_icon_final_offset, fade_duration, Easing.OutQuint); + rightBlurredIcon.MoveToX(blurred_icon_final_offset, fade_duration, Easing.OutQuint); + } + + protected override void PopOut() + { + leftGlowIcon.MoveToX(-glow_icon_offscreen_offset, fade_duration, Easing.OutQuint); + rightGlowIcon.MoveToX(glow_icon_offscreen_offset, fade_duration, Easing.OutQuint); + + leftBlurredIcon.MoveToX(-blurred_icon_offscreen_offset, fade_duration, Easing.OutQuint); + rightBlurredIcon.MoveToX(blurred_icon_offscreen_offset, fade_duration, Easing.OutQuint); + } + } +} diff --git a/osu.Game/Screens/Play/BreaksOverlay/BlurredIcon.cs b/osu.Game/Screens/Play/BreaksOverlay/BlurredIcon.cs new file mode 100644 index 0000000000..f16e7c7b96 --- /dev/null +++ b/osu.Game/Screens/Play/BreaksOverlay/BlurredIcon.cs @@ -0,0 +1,51 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; +using osu.Game.Graphics; +using osu.Framework.Allocation; + +namespace osu.Game.Screens.Play.BreaksOverlay +{ + public class BlurredIcon : BufferedContainer + { + private readonly SpriteIcon icon; + + public FontAwesome Icon + { + set { icon.Icon = value; } + get { return icon.Icon; } + } + + public override Vector2 Size + { + set + { + icon.Size = value; + base.Size = value + BlurSigma * 2.5f; + ForceRedraw(); + } + get { return base.Size; } + } + + public BlurredIcon() + { + RelativePositionAxes = Axes.X; + CacheDrawnFrameBuffer = true; + Child = icon = new SpriteIcon + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Shadow = false, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Colour = colours.BlueLighter; + } + } +} diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs new file mode 100644 index 0000000000..f5062aa40f --- /dev/null +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -0,0 +1,151 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps.Timing; +using osu.Game.Rulesets.Scoring; +using System.Collections.Generic; + +namespace osu.Game.Screens.Play.BreaksOverlay +{ + public class BreakOverlay : Container + { + private const double fade_duration = BreakPeriod.MIN_BREAK_DURATION / 2; + private const float remaining_time_container_max_size = 0.3f; + private const int vertical_margin = 25; + + private List breaks; + public List Breaks + { + set + { + breaks = value; + initializeBreaks(); + } + get + { + return breaks; + } + } + + private readonly bool letterboxing; + private readonly LetterboxOverlay letterboxOverlay; + private readonly Container remainingTimeAdjustmentBox; + private readonly Container remainingTimeBox; + private readonly RemainingTimeCounter remainingTimeCounter; + private readonly InfoContainer info; + private readonly ArrowsOverlay arrowsOverlay; + + public BreakOverlay(bool letterboxing) + { + this.letterboxing = letterboxing; + + RelativeSizeAxes = Axes.Both; + Children = new Drawable[] + { + letterboxOverlay = new LetterboxOverlay + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + remainingTimeAdjustmentBox = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Width = 0, + Child = remainingTimeBox = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + Height = 8, + CornerRadius = 4, + Masking = true, + Child = new Box { RelativeSizeAxes = Axes.Both } + } + }, + remainingTimeCounter = new RemainingTimeCounter + { + Anchor = Anchor.Centre, + Origin = Anchor.BottomCentre, + Margin = new MarginPadding { Bottom = vertical_margin }, + }, + info = new InfoContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.TopCentre, + Margin = new MarginPadding { Top = vertical_margin }, + }, + arrowsOverlay = new ArrowsOverlay + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + }; + } + + private void initializeBreaks() + { + FinishTransforms(true); + Scheduler.CancelDelayedTasks(); + + if (breaks == null) + return; + + foreach (var b in breaks) + { + if (!b.HasEffect) + continue; + + using (BeginAbsoluteSequence(b.StartTime)) + { + Schedule(() => onBreakIn(b)); + using (BeginDelayedSequence(b.Duration - fade_duration)) + Schedule(onBreakOut); + } + } + } + + private void onBreakIn(BreakPeriod b) + { + if (letterboxing) + letterboxOverlay.Show(); + + remainingTimeAdjustmentBox + .ResizeWidthTo(remaining_time_container_max_size, fade_duration, Easing.OutQuint) + .Delay(b.Duration - fade_duration) + .ResizeWidthTo(0); + + remainingTimeBox + .ResizeWidthTo(0, b.Duration - fade_duration) + .Then() + .ResizeWidthTo(1); + + remainingTimeCounter.StartCounting(b.EndTime); + + remainingTimeCounter.Show(); + info.Show(); + arrowsOverlay.Show(); + } + + private void onBreakOut() + { + if (letterboxing) + letterboxOverlay.Hide(); + + remainingTimeCounter.Hide(); + info.Hide(); + arrowsOverlay.Hide(); + } + + public void BindProcessor(ScoreProcessor processor) + { + info.AccuracyDisplay.Current.BindTo(processor.Accuracy); + info.GradeDisplay.Current.BindTo(processor.Rank); + } + } +} diff --git a/osu.Game/Screens/Play/BreaksOverlay/GlowIcon.cs b/osu.Game/Screens/Play/BreaksOverlay/GlowIcon.cs new file mode 100644 index 0000000000..b27eef632c --- /dev/null +++ b/osu.Game/Screens/Play/BreaksOverlay/GlowIcon.cs @@ -0,0 +1,65 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; +using osu.Game.Graphics; +using OpenTK; +using osu.Framework.Allocation; + +namespace osu.Game.Screens.Play.BreaksOverlay +{ + public class GlowIcon : Container + { + private readonly SpriteIcon spriteIcon; + private readonly BlurredIcon blurredIcon; + + public override Vector2 Size + { + set + { + blurredIcon.Size = spriteIcon.Size = value; + blurredIcon.ForceRedraw(); + } + get { return base.Size; } + } + + public Vector2 BlurSigma + { + set { blurredIcon.BlurSigma = value; } + get { return blurredIcon.BlurSigma; } + } + + public FontAwesome Icon + { + set { spriteIcon.Icon = blurredIcon.Icon = value; } + get { return spriteIcon.Icon; } + } + + public GlowIcon() + { + RelativePositionAxes = Axes.X; + AutoSizeAxes = Axes.Both; + Children = new Drawable[] + { + blurredIcon = new BlurredIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + spriteIcon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Shadow = false, + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + blurredIcon.Colour = colours.Blue; + } + } +} diff --git a/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs b/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs new file mode 100644 index 0000000000..1bf9b26cc9 --- /dev/null +++ b/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs @@ -0,0 +1,58 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Rulesets.Scoring; +using osu.Game.Beatmaps.Timing; + +namespace osu.Game.Screens.Play.BreaksOverlay +{ + public class InfoContainer : VisibilityContainer + { + private const double fade_duration = BreakPeriod.MIN_BREAK_DURATION / 2; + + public PercentageInfoLine AccuracyDisplay; + public InfoLine RankDisplay; + public InfoLine GradeDisplay; + + public InfoContainer() + { + AutoSizeAxes = Axes.Both; + Child = new FillFlowContainer + { + Direction = FillDirection.Vertical, + Spacing = new Vector2(5), + Children = new Drawable[] + { + new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = "current progress".ToUpper(), + TextSize = 15, + Font = "Exo2.0-Black", + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + AccuracyDisplay = new PercentageInfoLine("Accuracy"), + RankDisplay = new InfoLine("Rank"), + GradeDisplay = new InfoLine("Grade"), + }, + } + }, + }; + } + + protected override void PopIn() => this.FadeIn(fade_duration); + protected override void PopOut() => this.FadeOut(fade_duration); + } +} diff --git a/osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs b/osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs new file mode 100644 index 0000000000..751523d68c --- /dev/null +++ b/osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs @@ -0,0 +1,82 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Screens.Play.BreaksOverlay +{ + public class InfoLine : Container + where T : struct + { + private const int margin = 2; + + public Bindable Current = new Bindable(); + + private readonly OsuSpriteText text; + private readonly OsuSpriteText valueText; + + private readonly string prefix; + + public InfoLine(string name, string prefix = @"") + { + this.prefix = prefix; + + AutoSizeAxes = Axes.Y; + Children = new Drawable[] + { + text = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.CentreRight, + Text = name, + TextSize = 17, + Margin = new MarginPadding { Right = margin } + }, + valueText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.CentreLeft, + Text = prefix + @"-", + TextSize = 17, + Font = "Exo2.0-Bold", + Margin = new MarginPadding { Left = margin } + } + }; + + Current.ValueChanged += currentValueChanged; + } + + private void currentValueChanged(T newValue) + { + var newText = prefix + Format(newValue); + + if (valueText.Text == newText) + return; + + valueText.Text = newText; + } + + protected virtual string Format(T count) => count.ToString(); + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + text.Colour = colours.Yellow; + valueText.Colour = colours.YellowLight; + } + } + + public class PercentageInfoLine : InfoLine + { + public PercentageInfoLine(string name, string prefix = "") : base(name, prefix) + { + } + + protected override string Format(double count) => $@"{count:P2}"; + } +} diff --git a/osu.Game/Screens/Play/BreaksOverlay/LetterboxOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/LetterboxOverlay.cs new file mode 100644 index 0000000000..9d5bc986e9 --- /dev/null +++ b/osu.Game/Screens/Play/BreaksOverlay/LetterboxOverlay.cs @@ -0,0 +1,67 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK.Graphics; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps.Timing; + +namespace osu.Game.Screens.Play.BreaksOverlay +{ + public class LetterboxOverlay : VisibilityContainer + { + private const double fade_duration = BreakPeriod.MIN_BREAK_DURATION / 2; + private const int height = 350; + + private static readonly Color4 transparent_black = new Color4(0, 0, 0, 0); + + public LetterboxOverlay() + { + RelativeSizeAxes = Axes.Both; + Children = new Drawable[] + { + new Container + { + Anchor = Anchor.TopLeft, + Origin = Anchor.TopLeft, + RelativeSizeAxes = Axes.X, + Height = height, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = new ColourInfo + { + TopLeft = Color4.Black, + TopRight = Color4.Black, + BottomLeft = transparent_black, + BottomRight = transparent_black, + } + } + }, + new Container + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + Height = height, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = new ColourInfo + { + TopLeft = transparent_black, + TopRight = transparent_black, + BottomLeft = Color4.Black, + BottomRight = Color4.Black, + } + } + } + }; + } + + protected override void PopIn() => this.FadeIn(fade_duration); + protected override void PopOut() => this.FadeOut(fade_duration); + } +} diff --git a/osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs b/osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs new file mode 100644 index 0000000000..b5d77d0d02 --- /dev/null +++ b/osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs @@ -0,0 +1,65 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Framework.Graphics; +using System; +using osu.Game.Beatmaps.Timing; + +namespace osu.Game.Screens.Play.BreaksOverlay +{ + public class RemainingTimeCounter : VisibilityContainer + { + private const double fade_duration = BreakPeriod.MIN_BREAK_DURATION / 2; + + private readonly OsuSpriteText counter; + + private int? previousSecond; + + private double endTime; + + private bool isCounting; + + public RemainingTimeCounter() + { + AutoSizeAxes = Axes.Both; + Child = counter = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + TextSize = 33, + Font = "Venera", + }; + } + + public void StartCounting(double endTime) + { + this.endTime = endTime; + isCounting = true; + } + + protected override void Update() + { + base.Update(); + + if (isCounting) + { + var currentTime = Clock.CurrentTime; + if (currentTime < endTime) + { + int currentSecond = (int)Math.Ceiling((endTime - Clock.CurrentTime) / 1000.0); + if (currentSecond != previousSecond) + { + counter.Text = currentSecond.ToString(); + previousSecond = currentSecond; + } + } + else isCounting = false; + } + } + + protected override void PopIn() => this.FadeIn(fade_duration); + protected override void PopOut() => this.FadeOut(fade_duration); + } +} diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index e120c7f193..589f4b663a 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -24,6 +24,7 @@ using osu.Game.Screens.Ranking; using osu.Framework.Audio.Sample; using osu.Game.Beatmaps; using osu.Game.Online.API; +using osu.Game.Screens.Play.BreaksOverlay; using osu.Game.Storyboards.Drawables; using OpenTK.Graphics; @@ -69,6 +70,7 @@ namespace osu.Game.Screens.Play #endregion + private BreakOverlay breakOverlay; private Container storyboardContainer; private DrawableStoryboard storyboard; @@ -179,16 +181,20 @@ namespace osu.Game.Screens.Play { RelativeSizeAxes = Axes.Both, Clock = offsetClock, - Children = new Drawable[] - { - RulesetContainer, - } + Child = RulesetContainer, }, hudOverlay = new HUDOverlay { Anchor = Anchor.Centre, Origin = Anchor.Centre }, + breakOverlay = new BreakOverlay(beatmap.BeatmapInfo.LetterboxInBreaks) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Clock = decoupledClock, + Breaks = beatmap.Breaks + }, } }, failOverlay = new FailOverlay @@ -222,6 +228,8 @@ namespace osu.Game.Screens.Play hudOverlay.ModDisplay.Current.BindTo(working.Mods); + breakOverlay.BindProcessor(scoreProcessor); + // Bind ScoreProcessor to ourselves scoreProcessor.AllJudged += onCompletion; scoreProcessor.Failed += onFail; diff --git a/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs b/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs new file mode 100644 index 0000000000..206ca308cf --- /dev/null +++ b/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs @@ -0,0 +1,91 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Timing; +using osu.Game.Beatmaps.Timing; +using osu.Game.Screens.Play.BreaksOverlay; +using System.Collections.Generic; + +namespace osu.Game.Tests.Visual +{ + internal class TestCaseBreakOverlay : OsuTestCase + { + public override string Description => @"Tests breaks behavior"; + + private readonly BreakOverlay breakOverlay; + + public TestCaseBreakOverlay() + { + Clock = new FramedClock(); + + Child = breakOverlay = new BreakOverlay(true); + + AddStep("2s break", () => startBreak(2000)); + AddStep("5s break", () => startBreak(5000)); + AddStep("10s break", () => startBreak(10000)); + AddStep("15s break", () => startBreak(15000)); + AddStep("2s, 2s", startMultipleBreaks); + AddStep("0.5s, 0.7s, 1s, 2s", startAnotherMultipleBreaks); + } + + private void startBreak(double duration) + { + breakOverlay.Breaks = new List + { + new BreakPeriod + { + StartTime = Clock.CurrentTime, + EndTime = Clock.CurrentTime + duration, + } + }; + } + + private void startMultipleBreaks() + { + double currentTime = Clock.CurrentTime; + + breakOverlay.Breaks = new List + { + new BreakPeriod + { + StartTime = currentTime, + EndTime = currentTime + 2000, + }, + new BreakPeriod + { + StartTime = currentTime + 4000, + EndTime = currentTime + 6000, + } + }; + } + + private void startAnotherMultipleBreaks() + { + double currentTime = Clock.CurrentTime; + + breakOverlay.Breaks = new List + { + new BreakPeriod // Duration is less than 650 - too short to appear + { + StartTime = currentTime, + EndTime = currentTime + 500, + }, + new BreakPeriod + { + StartTime = currentTime + 1500, + EndTime = currentTime + 2200, + }, + new BreakPeriod + { + StartTime = currentTime + 3200, + EndTime = currentTime + 4200, + }, + new BreakPeriod + { + StartTime = currentTime + 5200, + EndTime = currentTime + 7200, + } + }; + } + } +} \ No newline at end of file diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index c8e42a3ad3..728724a080 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -274,6 +274,14 @@ + + + + + + + + @@ -736,6 +744,7 @@ +