diff --git a/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenBeatmap.cs b/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenBeatmap.cs index 8b941e4633..0d62bf9bdc 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenBeatmap.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenBeatmap.cs @@ -28,6 +28,7 @@ using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Play; using osu.Game.Screens.Play.PlayerSettings; using osu.Game.Screens.Select; +using osu.Game.Storyboards; using osu.Game.Tests.Resources; using osu.Game.Users; using osuTK; @@ -333,9 +334,9 @@ namespace osu.Game.Tests.Visual.Background { protected override BackgroundScreen CreateBackground() => new FadeAccessibleBackground(Beatmap.Value); - protected override UserDimContainer CreateStoryboardContainer() + protected override StoryboardContainer CreateStoryboardContainer(Storyboard storyboard) { - return new TestUserDimContainer(true) + return new TestStoryboardContainer { RelativeSizeAxes = Axes.Both, Alpha = 1, @@ -343,7 +344,7 @@ namespace osu.Game.Tests.Visual.Background }; } - public UserDimContainer CurrentStoryboardContainer => StoryboardContainer; + public TestStoryboardContainer CurrentStoryboardContainer => (TestStoryboardContainer)StoryboardContainer; // Whether or not the player should be allowed to load. public bool BlockLoad; @@ -357,9 +358,9 @@ namespace osu.Game.Tests.Visual.Background { } - public bool IsStoryboardVisible() => ((TestUserDimContainer)CurrentStoryboardContainer).CurrentAlpha == 1; + public bool IsStoryboardVisible() => CurrentStoryboardContainer.CurrentAlpha == 1; - public bool IsStoryboardInvisible() => ((TestUserDimContainer)CurrentStoryboardContainer).CurrentAlpha <= 1; + public bool IsStoryboardInvisible() => CurrentStoryboardContainer.CurrentAlpha <= 1; [BackgroundDependencyLoader] private void load(OsuConfigManager config, CancellationToken token) @@ -408,15 +409,20 @@ namespace osu.Game.Tests.Visual.Background } } + private class TestStoryboardContainer : StoryboardContainer + { + public float CurrentAlpha => DimContainer.Alpha; + + public TestStoryboardContainer() + : base(new Storyboard()) + { + } + } + private class TestUserDimContainer : UserDimContainer { public Color4 CurrentColour => DimContainer.Colour; public float CurrentAlpha => DimContainer.Alpha; - - public TestUserDimContainer(bool isStoryboard = false) - : base(isStoryboard) - { - } } } } diff --git a/osu.Game/Graphics/Containers/StoryboardContainer.cs b/osu.Game/Graphics/Containers/StoryboardContainer.cs new file mode 100644 index 0000000000..c425d38d48 --- /dev/null +++ b/osu.Game/Graphics/Containers/StoryboardContainer.cs @@ -0,0 +1,59 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Game.Storyboards; +using osu.Game.Storyboards.Drawables; + +namespace osu.Game.Graphics.Containers +{ + /// + /// A container that handles loading, as well as applies user-specified visual settings to it. + /// + public class StoryboardContainer : UserDimContainer + { + private readonly Storyboard storyboard; + private DrawableStoryboard drawableStoryboard; + + public StoryboardContainer(Storyboard storyboard) + { + this.storyboard = storyboard; + } + + [BackgroundDependencyLoader] + private void load() + { + initializeStoryboard(false); + } + + protected override void LoadComplete() + { + ShowStoryboard.ValueChanged += _ => initializeStoryboard(true); + base.LoadComplete(); + } + + protected override void ApplyFade() + { + // Storyboards cannot be blurred, so we should just hide the storyboard if it gets toggled. + DimContainer.FadeTo(!ShowStoryboard.Value || UserDimLevel.Value == 1 ? 0 : 1, BACKGROUND_FADE_DURATION, Easing.OutQuint); + } + + private void initializeStoryboard(bool async) + { + if (drawableStoryboard != null) + return; + + if (!ShowStoryboard.Value) + return; + + drawableStoryboard = storyboard.CreateDrawable(); + drawableStoryboard.Masking = true; + + if (async) + LoadComponentAsync(drawableStoryboard, Add); + else + Add(drawableStoryboard); + } + } +} diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index fe9eb7baf4..b14051f432 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -16,11 +16,10 @@ namespace osu.Game.Graphics.Containers { /// /// A container that applies user-configured visual settings to its contents. - /// This container specifies behavior that applies to both Storyboards and Backgrounds. /// public class UserDimContainer : Container { - private const float background_fade_duration = 800; + protected const float BACKGROUND_FADE_DURATION = 800; /// /// Whether or not user-configured dim levels should be applied to the container. @@ -40,17 +39,15 @@ namespace osu.Game.Graphics.Containers /// public readonly Bindable BlurAmount = new Bindable(); - private Bindable userDimLevel { get; set; } + protected Bindable UserDimLevel { get; private set; } - private Bindable userBlurLevel { get; set; } - - private Bindable showStoryboard { get; set; } + protected Bindable ShowStoryboard { get; private set; } protected Container DimContainer { get; } protected override Container Content => DimContainer; - private readonly bool isStoryboard; + private Bindable userBlurLevel { get; set; } /// /// As an optimisation, we add the two blur portions to be applied rather than actually applying two separate blurs. @@ -62,15 +59,12 @@ namespace osu.Game.Graphics.Containers /// /// Creates a new . /// - /// Whether or not this instance contains a storyboard. /// - /// While both backgrounds and storyboards allow user dim levels to be applied, storyboards can be toggled via + /// While both backgrounds and storyboards allow user dim levels to be applied, storyboards can be toggled via /// and can cause backgrounds to become hidden via . Storyboards are also currently unable to be blurred. /// - /// - public UserDimContainer(bool isStoryboard = false) + public UserDimContainer() { - this.isStoryboard = isStoryboard; AddInternal(DimContainer = new Container { RelativeSizeAxes = Axes.Both }); } @@ -97,16 +91,16 @@ namespace osu.Game.Graphics.Containers [BackgroundDependencyLoader] private void load(OsuConfigManager config) { - userDimLevel = config.GetBindable(OsuSetting.DimLevel); + UserDimLevel = config.GetBindable(OsuSetting.DimLevel); userBlurLevel = config.GetBindable(OsuSetting.BlurLevel); - showStoryboard = config.GetBindable(OsuSetting.ShowStoryboard); + ShowStoryboard = config.GetBindable(OsuSetting.ShowStoryboard); EnableUserDim.ValueChanged += _ => updateVisuals(); - userDimLevel.ValueChanged += _ => updateVisuals(); - userBlurLevel.ValueChanged += _ => updateVisuals(); - showStoryboard.ValueChanged += _ => updateVisuals(); + UserDimLevel.ValueChanged += _ => updateVisuals(); + ShowStoryboard.ValueChanged += _ => updateVisuals(); StoryboardReplacesBackground.ValueChanged += _ => updateVisuals(); BlurAmount.ValueChanged += _ => updateVisuals(); + userBlurLevel.ValueChanged += _ => updateVisuals(); } protected override void LoadComplete() @@ -115,21 +109,21 @@ namespace osu.Game.Graphics.Containers updateVisuals(); } + /// + /// Apply non-dim related settings to the background, such as hiding and blurring. + /// + protected virtual void ApplyFade() + { + // The background needs to be hidden in the case of it being replaced by the storyboard + DimContainer.FadeTo(ShowStoryboard.Value && StoryboardReplacesBackground.Value ? 0 : 1, BACKGROUND_FADE_DURATION, Easing.OutQuint); + Background?.BlurTo(blurTarget, BACKGROUND_FADE_DURATION, Easing.OutQuint); + } + private void updateVisuals() { - if (isStoryboard) - { - DimContainer.FadeTo(!showStoryboard.Value || userDimLevel.Value == 1 ? 0 : 1, background_fade_duration, Easing.OutQuint); - } - else - { - // The background needs to be hidden in the case of it being replaced by the storyboard - DimContainer.FadeTo(showStoryboard.Value && StoryboardReplacesBackground.Value ? 0 : 1, background_fade_duration, Easing.OutQuint); + ApplyFade(); - Background?.BlurTo(blurTarget, background_fade_duration, Easing.OutQuint); - } - - DimContainer.FadeColour(EnableUserDim.Value ? OsuColour.Gray(1 - (float)userDimLevel.Value) : Color4.White, background_fade_duration, Easing.OutQuint); + DimContainer.FadeColour(EnableUserDim.Value ? OsuColour.Gray(1 - (float)UserDimLevel.Value) : Color4.White, BACKGROUND_FADE_DURATION, Easing.OutQuint); } } } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index ea614e7658..621df0b562 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -26,7 +26,7 @@ using osu.Game.Rulesets.UI; using osu.Game.Scoring; using osu.Game.Screens.Ranking; using osu.Game.Skinning; -using osu.Game.Storyboards.Drawables; +using osu.Game.Storyboards; using osu.Game.Users; namespace osu.Game.Screens.Play @@ -109,7 +109,7 @@ namespace osu.Game.Screens.Play sampleRestart = audio.Samples.Get(@"Gameplay/restart"); mouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); - showStoryboard = config.GetBindable(OsuSetting.ShowStoryboard); + config.GetBindable(OsuSetting.ShowStoryboard); ScoreProcessor = DrawableRuleset.CreateScoreProcessor(); ScoreProcessor.Mods.BindTo(Mods); @@ -121,7 +121,7 @@ namespace osu.Game.Screens.Play GameplayClockContainer.Children = new[] { - StoryboardContainer = CreateStoryboardContainer(), + StoryboardContainer = CreateStoryboardContainer(Beatmap.Value.Storyboard), new ScalingContainer(ScalingMode.Gameplay) { Child = new LocalSkinOverrideContainer(working.Skin) @@ -199,9 +199,6 @@ namespace osu.Game.Screens.Play // bind clock into components that require it DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused); - // load storyboard as part of player's load if we can - initializeStoryboard(false); - // Bind ScoreProcessor to ourselves ScoreProcessor.AllJudged += onCompletion; ScoreProcessor.Failed += onFail; @@ -336,42 +333,15 @@ namespace osu.Game.Screens.Play #region Storyboard - private DrawableStoryboard storyboard; - protected UserDimContainer StoryboardContainer { get; private set; } + protected StoryboardContainer StoryboardContainer { get; private set; } - protected virtual UserDimContainer CreateStoryboardContainer() => new UserDimContainer(true) + protected virtual StoryboardContainer CreateStoryboardContainer(Storyboard storyboard) => new StoryboardContainer(storyboard) { RelativeSizeAxes = Axes.Both, Alpha = 1, EnableUserDim = { Value = true } }; - private Bindable showStoryboard; - - private void initializeStoryboard(bool asyncLoad) - { - if (StoryboardContainer == null || storyboard != null) - return; - - if (!showStoryboard.Value) - return; - - var beatmap = Beatmap.Value; - - storyboard = beatmap.Storyboard.CreateDrawable(); - storyboard.Masking = true; - - if (asyncLoad) - LoadComponentAsync(storyboard, c => - { - // Since the storyboard was loaded before it can be added to the draw hierarchy, manually set the clock for it here. - c.Clock = GameplayClockContainer.GameplayClock; - StoryboardContainer.Add(c); - }); - else - StoryboardContainer.Add(storyboard); - } - #endregion #region Fail Logic @@ -491,8 +461,6 @@ namespace osu.Game.Screens.Play .Delay(250) .FadeIn(250); - showStoryboard.ValueChanged += _ => initializeStoryboard(true); - Background.EnableUserDim.Value = true; Background.BlurAmount.Value = 0;