From 9497db0b0bb38e35c73f6ab6db54d9d09cfc22c0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 May 2018 20:21:25 +0900 Subject: [PATCH 1/7] Add a delay before the loading logo is displayed --- osu.Game/Screens/Loader.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index fb5c5ca84b..28b139c9f9 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -36,7 +36,13 @@ namespace osu.Game.Screens logo.Position = new Vector2(-40); logo.Scale = new Vector2(0.2f); - logo.FadeInFromZero(5000, Easing.OutQuint); + logo.Delay(500).FadeInFromZero(1000, Easing.OutQuint); + } + + protected override void LogoSuspending(OsuLogo logo) + { + base.LogoSuspending(logo); + logo.FadeOut(logo.Alpha * 1000); } private OsuScreen loadScreen; @@ -63,12 +69,6 @@ namespace osu.Game.Screens Push(loadScreen); } - protected override void LogoSuspending(OsuLogo logo) - { - base.LogoSuspending(logo); - logo.FadeOut(100); - } - [BackgroundDependencyLoader] private void load(OsuGameBase game) { From 9ea6ab28ea45ce90de2471f22a1b20de8ce44b5b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 May 2018 20:21:53 +0900 Subject: [PATCH 2/7] Fix intro potentially starting out-of-sync due to logo's outward animation --- osu.Game/Screens/Menu/Intro.cs | 48 ++++++++++++++++------------------ 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/osu.Game/Screens/Menu/Intro.cs b/osu.Game/Screens/Menu/Intro.cs index c174e2d470..5aca184d24 100644 --- a/osu.Game/Screens/Menu/Intro.cs +++ b/osu.Game/Screens/Menu/Intro.cs @@ -79,31 +79,6 @@ namespace osu.Game.Screens.Menu seeya = audio.Sample.Get(@"seeya"); } - protected override void OnEntering(Screen last) - { - base.OnEntering(last); - - Game.Beatmap.Value = beatmap; - - if (menuVoice) - welcome.Play(); - - Scheduler.AddDelayed(delegate - { - // Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Manu. - if (menuMusic) - track.Start(); - - LoadComponentAsync(mainMenu = new MainMenu()); - - Scheduler.AddDelayed(delegate - { - DidLoadMenu = true; - Push(mainMenu); - }, delay_step_one); - }, delay_step_two); - } - private const double delay_step_one = 2300; private const double delay_step_two = 600; @@ -113,6 +88,29 @@ namespace osu.Game.Screens.Menu { base.LogoArriving(logo, resuming); + if (!resuming) + { + Game.Beatmap.Value = beatmap; + + if (menuVoice) + welcome.Play(); + + Scheduler.AddDelayed(delegate + { + // Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Manu. + if (menuMusic) + track.Start(); + + LoadComponentAsync(mainMenu = new MainMenu()); + + Scheduler.AddDelayed(delegate + { + DidLoadMenu = true; + Push(mainMenu); + }, delay_step_one); + }, delay_step_two); + } + logo.RelativePositionAxes = Axes.Both; logo.Colour = Color4.White; logo.Ripple = false; From c161d8247479f401b0719b029459a9107ef3705f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 31 May 2018 17:14:04 +0900 Subject: [PATCH 3/7] Reduce the length of the fadeout animation --- osu.Game/Screens/Loader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index 28b139c9f9..c8a80d470b 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -42,7 +42,7 @@ namespace osu.Game.Screens protected override void LogoSuspending(OsuLogo logo) { base.LogoSuspending(logo); - logo.FadeOut(logo.Alpha * 1000); + logo.FadeOut(logo.Alpha * 400); } private OsuScreen loadScreen; From 7487c82ec151b2b3a9fffc7adc260f87794ce182 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 31 May 2018 17:14:47 +0900 Subject: [PATCH 4/7] Stop the logo from beating --- osu.Game/Screens/Loader.cs | 1 + osu.Game/Screens/Menu/OsuLogo.cs | 4 ++++ osu.Game/Screens/OsuScreen.cs | 1 + 3 files changed, 6 insertions(+) diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index c8a80d470b..b8c1c31b8c 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -30,6 +30,7 @@ namespace osu.Game.Screens { base.LogoArriving(logo, resuming); + logo.BeatMatching = false; logo.Triangles = false; logo.Origin = Anchor.BottomRight; logo.Anchor = Anchor.BottomRight; diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index 42a8dbd5da..16482b0e48 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -64,6 +64,8 @@ namespace osu.Game.Screens.Menu set { colourAndTriangles.FadeTo(value ? 1 : 0, transition_length, Easing.OutQuint); } } + public bool BeatMatching = true; + public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => logoContainer.ReceiveMouseInputAt(screenSpacePos); public bool Ripple @@ -264,6 +266,8 @@ namespace osu.Game.Screens.Menu { base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes); + if (!BeatMatching) return; + lastBeatIndex = beatIndex; var beatLength = timingPoint.BeatLength; diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index db9807b9ab..7f68e5144b 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -225,6 +225,7 @@ namespace osu.Game.Screens logo.Anchor = Anchor.TopLeft; logo.Origin = Anchor.Centre; logo.RelativePositionAxes = Axes.None; + logo.BeatMatching = true; logo.Triangles = true; logo.Ripple = true; } From dfbcf4d7b7df2cde7194ea952a2eec221b81cd87 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 31 May 2018 17:29:59 +0900 Subject: [PATCH 5/7] Add tests --- .../Visual/TestCaseLoaderAnimation.cs | 101 ++++++++++++++++++ osu.Game/Screens/Loader.cs | 4 +- 2 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Tests/Visual/TestCaseLoaderAnimation.cs diff --git a/osu.Game.Tests/Visual/TestCaseLoaderAnimation.cs b/osu.Game.Tests/Visual/TestCaseLoaderAnimation.cs new file mode 100644 index 0000000000..066efb5116 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseLoaderAnimation.cs @@ -0,0 +1,101 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Threading; +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osu.Game.Screens; +using osu.Game.Screens.Menu; +using OpenTK.Graphics; + +namespace osu.Game.Tests.Visual +{ + [TestFixture] + public class TestCaseLoaderAnimation : OsuTestCase + { + private TestLoader loader; + + public TestCaseLoaderAnimation() + { + bool logoVisible = false; + + AddStep("almost instant display", () => Child = loader = new TestLoader(0.25f)); + AddUntilStep(() => + { + logoVisible = loader.Logo.Alpha > 0; + return !loader.IsCurrentScreen; + }, "loaded"); + AddAssert("logo not visible", () => !logoVisible); + + AddStep("short load", () => Child = loader = new TestLoader(0.8f)); + AddUntilStep(() => + { + logoVisible = loader.Logo.Alpha > 0; + return !loader.IsCurrentScreen; + }, "loaded"); + AddAssert("logo visible", () => logoVisible); + AddUntilStep(() => loader.Logo.Alpha == 0, "logo gone"); + + AddStep("longer load", () => Child = loader = new TestLoader(1.4f)); + AddUntilStep(() => + { + logoVisible = loader.Logo.Alpha > 0; + return !loader.IsCurrentScreen; + }, "loaded"); + AddAssert("logo visible", () => logoVisible); + AddUntilStep(() => loader.Logo.Alpha == 0, "logo gone"); + } + + private class TestLoader : Loader + { + private readonly float secondsDelay; + + public OsuLogo Logo; + + public TestLoader(float secondsDelay) + { + this.secondsDelay = secondsDelay; + } + + protected override void LogoArriving(OsuLogo logo, bool resuming) + { + Logo = logo; + base.LogoArriving(logo, resuming); + } + + protected override OsuScreen CreateLoadableScreen() => new TestScreen(secondsDelay); + + private class TestScreen : OsuScreen + { + private readonly float secondsDelay; + + public TestScreen(float secondsDelay) + { + this.secondsDelay = secondsDelay; + + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.DarkSlateGray, + Alpha = 0, + }; + } + + [BackgroundDependencyLoader] + private void load() + { + Thread.Sleep((int)(secondsDelay * 1000)); + } + + protected override void LogoArriving(OsuLogo logo, bool resuming) + { + base.LogoArriving(logo, resuming); + + Child.FadeInFromZero(200); + } + } + } + } +} diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index b8c1c31b8c..6335700a8f 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -49,12 +49,14 @@ namespace osu.Game.Screens private OsuScreen loadScreen; private ShaderPrecompiler precompiler; + protected virtual OsuScreen CreateLoadableScreen() => showDisclaimer ? (OsuScreen)new Disclaimer() : new Intro(); + protected override void OnEntering(Screen last) { base.OnEntering(last); LoadComponentAsync(precompiler = new ShaderPrecompiler(loadIfReady), Add); - LoadComponentAsync(loadScreen = showDisclaimer ? (OsuScreen)new Disclaimer() : new Intro(), s => loadIfReady()); + LoadComponentAsync(loadScreen = CreateLoadableScreen(), s => loadIfReady()); } private void loadIfReady() From b68a5f5eabb589b787a844d96d0606915f44d55d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 31 May 2018 20:07:44 +0900 Subject: [PATCH 6/7] Tidy up Loader logic --- osu.Game/Screens/Loader.cs | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index 6335700a8f..c3b3e747fd 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; @@ -46,30 +45,32 @@ namespace osu.Game.Screens logo.FadeOut(logo.Alpha * 400); } - private OsuScreen loadScreen; + private OsuScreen loadableScreen; private ShaderPrecompiler precompiler; protected virtual OsuScreen CreateLoadableScreen() => showDisclaimer ? (OsuScreen)new Disclaimer() : new Intro(); + protected virtual ShaderPrecompiler CreateShaderPrecompiler() => new ShaderPrecompiler(); + protected override void OnEntering(Screen last) { base.OnEntering(last); - LoadComponentAsync(precompiler = new ShaderPrecompiler(loadIfReady), Add); - LoadComponentAsync(loadScreen = CreateLoadableScreen(), s => loadIfReady()); + LoadComponentAsync(precompiler = CreateShaderPrecompiler(), Add); + LoadComponentAsync(loadableScreen = CreateLoadableScreen()); + + checkIfLoaded(); } - private void loadIfReady() + private void checkIfLoaded() { - if (ChildScreen == loadScreen) return; - - if (loadScreen.LoadState != LoadState.Ready) + if (loadableScreen.LoadState != LoadState.Ready || !precompiler.FinishedCompiling) + { + Schedule(checkIfLoaded); return; + } - if (!precompiler.FinishedCompiling) - return; - - Push(loadScreen); + Push(loadableScreen); } [BackgroundDependencyLoader] @@ -83,16 +84,10 @@ namespace osu.Game.Screens /// public class ShaderPrecompiler : Drawable { - private readonly Action onLoaded; private readonly List loadTargets = new List(); public bool FinishedCompiling { get; private set; } - public ShaderPrecompiler(Action onLoaded) - { - this.onLoaded = onLoaded; - } - [BackgroundDependencyLoader] private void load(ShaderManager manager) { @@ -106,16 +101,17 @@ namespace osu.Game.Screens loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_3, FragmentShaderDescriptor.TEXTURE)); } + protected virtual bool AllLoaded => loadTargets.All(s => s.Loaded); + protected override void Update() { base.Update(); // if our target is null we are done. - if (loadTargets.All(s => s.Loaded)) + if (AllLoaded) { FinishedCompiling = true; Expire(); - onLoaded?.Invoke(); } } } From a6f2561be83855dd1075495cc8a44cf5bb173c70 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 31 May 2018 20:07:55 +0900 Subject: [PATCH 7/7] Fix automated testing --- .../Visual/TestCaseLoaderAnimation.cs | 76 +++++++++++-------- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseLoaderAnimation.cs b/osu.Game.Tests/Visual/TestCaseLoaderAnimation.cs index 066efb5116..600784f8db 100644 --- a/osu.Game.Tests/Visual/TestCaseLoaderAnimation.cs +++ b/osu.Game.Tests/Visual/TestCaseLoaderAnimation.cs @@ -1,9 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Threading; using NUnit.Framework; -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Screens; @@ -17,46 +15,53 @@ namespace osu.Game.Tests.Visual { private TestLoader loader; - public TestCaseLoaderAnimation() + protected override void LoadComplete() { - bool logoVisible = false; + base.LoadComplete(); - AddStep("almost instant display", () => Child = loader = new TestLoader(0.25f)); + // required to preload the logo in a headless run (so it doesn't delay the loading itself). + Add(new OsuLogo()); + + bool logoVisible = false; + AddStep("almost instant display", () => Child = loader = new TestLoader(250)); AddUntilStep(() => { - logoVisible = loader.Logo.Alpha > 0; - return !loader.IsCurrentScreen; + logoVisible = loader.Logo?.Alpha > 0; + return loader.Logo != null && loader.ScreenLoaded; }, "loaded"); AddAssert("logo not visible", () => !logoVisible); - AddStep("short load", () => Child = loader = new TestLoader(0.8f)); + AddStep("short load", () => Child = loader = new TestLoader(800)); AddUntilStep(() => { - logoVisible = loader.Logo.Alpha > 0; - return !loader.IsCurrentScreen; + logoVisible = loader.Logo?.Alpha > 0; + return loader.Logo != null && loader.ScreenLoaded; }, "loaded"); AddAssert("logo visible", () => logoVisible); - AddUntilStep(() => loader.Logo.Alpha == 0, "logo gone"); + AddUntilStep(() => loader.Logo?.Alpha == 0, "logo gone"); - AddStep("longer load", () => Child = loader = new TestLoader(1.4f)); + AddStep("longer load", () => Child = loader = new TestLoader(1400)); AddUntilStep(() => { - logoVisible = loader.Logo.Alpha > 0; - return !loader.IsCurrentScreen; + logoVisible = loader.Logo?.Alpha > 0; + return loader.Logo != null && loader.ScreenLoaded; }, "loaded"); AddAssert("logo visible", () => logoVisible); - AddUntilStep(() => loader.Logo.Alpha == 0, "logo gone"); + AddUntilStep(() => loader.Logo?.Alpha == 0, "logo gone"); } private class TestLoader : Loader { - private readonly float secondsDelay; + private readonly double delay; public OsuLogo Logo; + private TestScreen screen; - public TestLoader(float secondsDelay) + public bool ScreenLoaded => screen.IsCurrentScreen; + + public TestLoader(double delay) { - this.secondsDelay = secondsDelay; + this.delay = delay; } protected override void LogoArriving(OsuLogo logo, bool resuming) @@ -65,16 +70,32 @@ namespace osu.Game.Tests.Visual base.LogoArriving(logo, resuming); } - protected override OsuScreen CreateLoadableScreen() => new TestScreen(secondsDelay); + protected override OsuScreen CreateLoadableScreen() => screen = new TestScreen(); + protected override ShaderPrecompiler CreateShaderPrecompiler() => new TestShaderPrecompiler(delay); + + private class TestShaderPrecompiler : ShaderPrecompiler + { + private readonly double delay; + private double startTime; + + public TestShaderPrecompiler(double delay) + { + this.delay = delay; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + startTime = Time.Current; + } + + protected override bool AllLoaded => Time.Current > startTime + delay; + } private class TestScreen : OsuScreen { - private readonly float secondsDelay; - - public TestScreen(float secondsDelay) + public TestScreen() { - this.secondsDelay = secondsDelay; - Child = new Box { RelativeSizeAxes = Axes.Both, @@ -83,16 +104,9 @@ namespace osu.Game.Tests.Visual }; } - [BackgroundDependencyLoader] - private void load() - { - Thread.Sleep((int)(secondsDelay * 1000)); - } - protected override void LogoArriving(OsuLogo logo, bool resuming) { base.LogoArriving(logo, resuming); - Child.FadeInFromZero(200); } }