From ee2f7a75d734f9c9f1debff3f867629b87dffa08 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 30 Mar 2026 15:48:41 +0900 Subject: [PATCH] Adjust `RankedPlayCard` to always show card back (when loading content) (#37129) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was mentioned in vivi's feedback. Basically now the card backside is always loaded and there, rather than faffing with switching the content around. > Cards have a stale grey background when they are spawning in before they get changed into the cards they’re supposed to be. This can be changed to the backside of the card or maybe a bright white card. Makes it look less placeholdery. Keeping it simple for now. Can probably hide it when not in use in the future. --- .../RankedPlay/TestSceneDiscardScreen.cs | 23 ++++++++++++-- .../RankedPlay/TestSceneOpponentPickScreen.cs | 23 ++++++++++++-- .../Visual/RankedPlay/TestScenePickScreen.cs | 23 ++++++++++++-- .../RankedPlay/Card/RankedPlayCard.cs | 31 +++++++++---------- 4 files changed, 78 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/RankedPlay/TestSceneDiscardScreen.cs b/osu.Game.Tests/Visual/RankedPlay/TestSceneDiscardScreen.cs index f3e39796ac..e01e26524f 100644 --- a/osu.Game.Tests/Visual/RankedPlay/TestSceneDiscardScreen.cs +++ b/osu.Game.Tests/Visual/RankedPlay/TestSceneDiscardScreen.cs @@ -2,15 +2,15 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Extensions; +using osu.Game.Online.API; using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer.MatchTypes.RankedPlay; using osu.Game.Online.Rooms; using osu.Game.Screens.OnlinePlay.Matchmaking.RankedPlay; -using osu.Game.Tests.Visual.Multiplayer; namespace osu.Game.Tests.Visual.RankedPlay { - public partial class TestSceneDiscardScreen : MultiplayerTestScene + public partial class TestSceneDiscardScreen : RankedPlayTestScene { private RankedPlayScreen screen = null!; @@ -26,7 +26,26 @@ namespace osu.Game.Tests.Visual.RankedPlay AddStep("load screen", () => LoadScreen(screen = new RankedPlayScreen(MultiplayerClient.ClientRoom!))); AddUntilStep("screen loaded", () => screen.IsLoaded); + var requestHandler = new BeatmapRequestHandler(); + + AddStep("setup request handler", () => ((DummyAPIAccess)API).HandleRequest = requestHandler.HandleRequest); + AddStep("set pick state", () => MultiplayerClient.RankedPlayChangeStage(RankedPlayStage.CardDiscard).WaitSafely()); + + AddWaitStep("wait some", 5); + + AddStep("reveal cards", () => + { + for (int i = 0; i < 5; i++) + { + int i2 = i; + MultiplayerClient.RankedPlayRevealCard(hand => hand[i2], new MultiplayerPlaylistItem + { + ID = i2, + BeatmapID = requestHandler.Beatmaps[i2].OnlineID + }).WaitSafely(); + } + }); } } } diff --git a/osu.Game.Tests/Visual/RankedPlay/TestSceneOpponentPickScreen.cs b/osu.Game.Tests/Visual/RankedPlay/TestSceneOpponentPickScreen.cs index 838a49d255..ddf111e110 100644 --- a/osu.Game.Tests/Visual/RankedPlay/TestSceneOpponentPickScreen.cs +++ b/osu.Game.Tests/Visual/RankedPlay/TestSceneOpponentPickScreen.cs @@ -2,15 +2,15 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Extensions; +using osu.Game.Online.API; using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer.MatchTypes.RankedPlay; using osu.Game.Online.Rooms; using osu.Game.Screens.OnlinePlay.Matchmaking.RankedPlay; -using osu.Game.Tests.Visual.Multiplayer; namespace osu.Game.Tests.Visual.RankedPlay { - public partial class TestSceneOpponentPickScreen : MultiplayerTestScene + public partial class TestSceneOpponentPickScreen : RankedPlayTestScene { private RankedPlayScreen screen = null!; @@ -26,7 +26,26 @@ namespace osu.Game.Tests.Visual.RankedPlay AddStep("load screen", () => LoadScreen(screen = new RankedPlayScreen(MultiplayerClient.ClientRoom!))); AddUntilStep("screen loaded", () => screen.IsLoaded); + var requestHandler = new BeatmapRequestHandler(); + + AddStep("setup request handler", () => ((DummyAPIAccess)API).HandleRequest = requestHandler.HandleRequest); + AddStep("set pick state", () => MultiplayerClient.RankedPlayChangeStage(RankedPlayStage.CardPlay, state => state.ActiveUserId = 2).WaitSafely()); + + AddWaitStep("wait some", 5); + + AddStep("reveal cards", () => + { + for (int i = 0; i < 5; i++) + { + int i2 = i; + MultiplayerClient.RankedPlayRevealCard(hand => hand[i2], new MultiplayerPlaylistItem + { + ID = i2, + BeatmapID = requestHandler.Beatmaps[i2].OnlineID + }).WaitSafely(); + } + }); } } } diff --git a/osu.Game.Tests/Visual/RankedPlay/TestScenePickScreen.cs b/osu.Game.Tests/Visual/RankedPlay/TestScenePickScreen.cs index 042a56adf8..104872d20f 100644 --- a/osu.Game.Tests/Visual/RankedPlay/TestScenePickScreen.cs +++ b/osu.Game.Tests/Visual/RankedPlay/TestScenePickScreen.cs @@ -2,15 +2,15 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Extensions; +using osu.Game.Online.API; using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer.MatchTypes.RankedPlay; using osu.Game.Online.Rooms; using osu.Game.Screens.OnlinePlay.Matchmaking.RankedPlay; -using osu.Game.Tests.Visual.Multiplayer; namespace osu.Game.Tests.Visual.RankedPlay { - public partial class TestScenePickScreen : MultiplayerTestScene + public partial class TestScenePickScreen : RankedPlayTestScene { private RankedPlayScreen screen = null!; @@ -26,7 +26,26 @@ namespace osu.Game.Tests.Visual.RankedPlay AddStep("load screen", () => LoadScreen(screen = new RankedPlayScreen(MultiplayerClient.ClientRoom!))); AddUntilStep("screen loaded", () => screen.IsLoaded); + var requestHandler = new BeatmapRequestHandler(); + + AddStep("setup request handler", () => ((DummyAPIAccess)API).HandleRequest = requestHandler.HandleRequest); + AddStep("set pick state", () => MultiplayerClient.RankedPlayChangeStage(RankedPlayStage.CardPlay, state => state.ActiveUserId = API.LocalUser.Value.OnlineID).WaitSafely()); + + AddWaitStep("wait some", 5); + + AddStep("reveal cards", () => + { + for (int i = 0; i < 5; i++) + { + int i2 = i; + MultiplayerClient.RankedPlayRevealCard(hand => hand[i2], new MultiplayerPlaylistItem + { + ID = i2, + BeatmapID = requestHandler.Beatmaps[i2].OnlineID + }).WaitSafely(); + } + }); } } } diff --git a/osu.Game/Screens/OnlinePlay/Matchmaking/RankedPlay/Card/RankedPlayCard.cs b/osu.Game/Screens/OnlinePlay/Matchmaking/RankedPlay/Card/RankedPlayCard.cs index 8ece23e4d3..dfb24827b1 100644 --- a/osu.Game/Screens/OnlinePlay/Matchmaking/RankedPlay/Card/RankedPlayCard.cs +++ b/osu.Game/Screens/OnlinePlay/Matchmaking/RankedPlay/Card/RankedPlayCard.cs @@ -97,10 +97,11 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.RankedPlay.Card Origin = Anchor.Centre, Children = [ + new RankedPlayCardBackSide(), cardContent = new Container { RelativeSizeAxes = Axes.Both, - Child = new RankedPlayCardBackSide() + Child = Empty(), }, selectionOutline = new SelectionOutline { @@ -123,9 +124,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.RankedPlay.Card { base.LoadComplete(); - playlistItem.BindValueChanged(e => onPlaylistItemChanged(e.NewValue)); - if (playlistItem.Value != null) - loadCardContent(playlistItem.Value, false); + playlistItem.BindValueChanged(e => onPlaylistItemChanged(e.NewValue), true); } protected override void UpdateAfterChildren() @@ -147,14 +146,14 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.RankedPlay.Card { if (playlistItem == null) { - SetContent(new RankedPlayCardBackSide(), true); + SetContent(null); return; } - loadCardContent(playlistItem, true); + loadCardContentAsync(playlistItem); } - private void loadCardContent(MultiplayerPlaylistItem playlistItem, bool flip) => Task.Run(async () => + private void loadCardContentAsync(MultiplayerPlaylistItem playlistItem) => Task.Run(async () => { var beatmap = await beatmapLookupCache.GetBeatmapAsync(playlistItem.BeatmapID).ConfigureAwait(false); @@ -168,22 +167,22 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.RankedPlay.Card Schedule(() => { - SetContent(new RankedPlayCardContent(beatmap), flip); + SetContent(new RankedPlayCardContent(beatmap)); songPreviewContainer.LoadPreview(beatmap); }); }); - public void SetContent(Drawable newContent, bool flip) - { - if (!flip) - { - cardContent.Child = newContent; - return; - } + private bool hasContent; + public void SetContent(Drawable? newContent) + { + if (newContent == null && !hasContent) + return; + + hasContent = newContent != null; content.ScaleTo(new Vector2(0, 1), 100, Easing.In) .Then() - .Schedule(() => cardContent.Child = newContent) + .Schedule(() => cardContent.Child = newContent ?? Empty()) .ScaleTo(new Vector2(1), 300, Easing.OutElasticQuarter); SamplePlaybackHelper.PlayWithRandomPitch(cardFlipSample);