diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs index 3cd1b8307a..ffa822d175 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs @@ -1,8 +1,13 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Collections.Generic; using NUnit.Framework; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps.Timing; using osu.Game.Screens.Play; @@ -11,11 +16,30 @@ namespace osu.Game.Tests.Visual.Gameplay [TestFixture] public class TestSceneBreakOverlay : OsuTestScene { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(BreakOverlay), + }; + private readonly BreakOverlay breakOverlay; + private readonly IBindable isBreakTimeBindable = new BindableBool(); public TestSceneBreakOverlay() { - Child = breakOverlay = new BreakOverlay(true); + SpriteText breakTimeText; + Child = new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + breakTimeText = new SpriteText(), + breakOverlay = new BreakOverlay(true) + } + }; + + isBreakTimeBindable.BindTo(breakOverlay.IsBreakTime); + isBreakTimeBindable.BindValueChanged(e => breakTimeText.Text = $"IsBreakTime: {e.NewValue}", true); AddStep("2s break", () => startBreak(2000)); AddStep("5s break", () => startBreak(5000)); diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 0470cdb0d5..aceacdbab1 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -31,7 +31,7 @@ public List Breaks set { breaks = value; - currentBreakIndex = 0; + nearestBreakIndex = 0; initializeBreaks(); } @@ -44,7 +44,7 @@ public List Breaks /// public IBindable IsBreakTime => isBreakTime; - private int currentBreakIndex; + private int nearestBreakIndex; private readonly BindableBool isBreakTime = new BindableBool(); private readonly Container remainingTimeAdjustmentBox; @@ -136,24 +136,17 @@ private void updateBreakTimeBindable() return; } - int indexDirection = Clock.CurrentTime < breaks[currentBreakIndex].StartTime ? -1 : (Clock.CurrentTime > breaks[currentBreakIndex].EndTime ? 1 : 0); + while (nearestBreakIndex < breaks.Count - 1 && Clock.CurrentTime > breaks[nearestBreakIndex].EndTime) + nearestBreakIndex++; - while (Clock.CurrentTime < breaks[currentBreakIndex].StartTime || Clock.CurrentTime > breaks[currentBreakIndex].EndTime) - { - currentBreakIndex += indexDirection; + while (nearestBreakIndex > 0 && Clock.CurrentTime < breaks[nearestBreakIndex].StartTime) + nearestBreakIndex--; - if (currentBreakIndex < 0 || currentBreakIndex >= breaks.Count) - break; - } - - if (currentBreakIndex < 0 || currentBreakIndex >= breaks.Count) - { - isBreakTime.Value = false; - currentBreakIndex = 0; - return; - } - - isBreakTime.Value = true; + // This ensures that IsBreakTime is generally consistent with the overlay's transforms during a break. + // If the overlay never shows (break.HasEffect is false), IsBreakTime should be false. + // We also assume that the overlay's fade out transform is "not break time". + var nearestBreak = breaks[nearestBreakIndex]; + isBreakTime.Value = nearestBreak.HasEffect && Clock.CurrentTime >= nearestBreak.StartTime && Clock.CurrentTime <= nearestBreak.EndTime - fade_duration; } private void initializeBreaks()