mirror of
https://github.com/ppy/osu.git
synced 2025-02-14 02:43:02 +08:00
Merge pull request #20389 from peppy/fix-gameplay-leaderboard-layout
Fix gameplay leaderboard sometimes not showing up
This commit is contained in:
commit
445e026a32
@ -6,7 +6,9 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Extensions.PolygonExtensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
@ -18,37 +20,52 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneGameplayLeaderboard : OsuTestScene
|
public class TestSceneGameplayLeaderboard : OsuTestScene
|
||||||
{
|
{
|
||||||
private readonly TestGameplayLeaderboard leaderboard;
|
private TestGameplayLeaderboard leaderboard;
|
||||||
|
|
||||||
private readonly BindableDouble playerScore = new BindableDouble();
|
private readonly BindableDouble playerScore = new BindableDouble();
|
||||||
|
|
||||||
public TestSceneGameplayLeaderboard()
|
public TestSceneGameplayLeaderboard()
|
||||||
{
|
{
|
||||||
Add(leaderboard = new TestGameplayLeaderboard
|
AddStep("toggle expanded", () =>
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
if (leaderboard != null)
|
||||||
Origin = Anchor.Centre,
|
leaderboard.Expanded.Value = !leaderboard.Expanded.Value;
|
||||||
Scale = new Vector2(2),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
AddSliderStep("set player score", 50, 5000000, 1222333, v => playerScore.Value = v);
|
||||||
}
|
}
|
||||||
|
|
||||||
[SetUpSteps]
|
[Test]
|
||||||
public void SetUpSteps()
|
public void TestLayoutWithManyScores()
|
||||||
{
|
{
|
||||||
AddStep("reset leaderboard", () =>
|
createLeaderboard();
|
||||||
|
|
||||||
|
AddStep("add many scores in one go", () =>
|
||||||
{
|
{
|
||||||
leaderboard.Clear();
|
for (int i = 0; i < 32; i++)
|
||||||
playerScore.Value = 1222333;
|
createRandomScore(new APIUser { Username = $"Player {i + 1}" });
|
||||||
|
|
||||||
|
// Add player at end to force an animation down the whole list.
|
||||||
|
playerScore.Value = 0;
|
||||||
|
createLeaderboardScore(playerScore, new APIUser { Username = "You", Id = 3 }, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("add local player", () => createLeaderboardScore(playerScore, new APIUser { Username = "You", Id = 3 }, true));
|
// Gameplay leaderboard has custom scroll logic, which when coupled with LayoutDuration
|
||||||
AddStep("toggle expanded", () => leaderboard.Expanded.Value = !leaderboard.Expanded.Value);
|
// has caused layout to not work in the past.
|
||||||
AddSliderStep("set player score", 50, 5000000, 1222333, v => playerScore.Value = v);
|
|
||||||
|
AddUntilStep("wait for fill flow layout",
|
||||||
|
() => leaderboard.ChildrenOfType<FillFlowContainer<GameplayLeaderboardScore>>().First().ScreenSpaceDrawQuad.Intersects(leaderboard.ScreenSpaceDrawQuad));
|
||||||
|
|
||||||
|
AddUntilStep("wait for some scores not masked away",
|
||||||
|
() => leaderboard.ChildrenOfType<GameplayLeaderboardScore>().Any(s => leaderboard.ScreenSpaceDrawQuad.Contains(s.ScreenSpaceDrawQuad.Centre)));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestPlayerScore()
|
public void TestPlayerScore()
|
||||||
{
|
{
|
||||||
|
createLeaderboard();
|
||||||
|
addLocalPlayer();
|
||||||
|
|
||||||
var player2Score = new BindableDouble(1234567);
|
var player2Score = new BindableDouble(1234567);
|
||||||
var player3Score = new BindableDouble(1111111);
|
var player3Score = new BindableDouble(1111111);
|
||||||
|
|
||||||
@ -73,6 +90,9 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestRandomScores()
|
public void TestRandomScores()
|
||||||
{
|
{
|
||||||
|
createLeaderboard();
|
||||||
|
addLocalPlayer();
|
||||||
|
|
||||||
int playerNumber = 1;
|
int playerNumber = 1;
|
||||||
AddRepeatStep("add player with random score", () => createRandomScore(new APIUser { Username = $"Player {playerNumber++}" }), 10);
|
AddRepeatStep("add player with random score", () => createRandomScore(new APIUser { Username = $"Player {playerNumber++}" }), 10);
|
||||||
}
|
}
|
||||||
@ -80,6 +100,9 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestExistingUsers()
|
public void TestExistingUsers()
|
||||||
{
|
{
|
||||||
|
createLeaderboard();
|
||||||
|
addLocalPlayer();
|
||||||
|
|
||||||
AddStep("add peppy", () => createRandomScore(new APIUser { Username = "peppy", Id = 2 }));
|
AddStep("add peppy", () => createRandomScore(new APIUser { Username = "peppy", Id = 2 }));
|
||||||
AddStep("add smoogipoo", () => createRandomScore(new APIUser { Username = "smoogipoo", Id = 1040328 }));
|
AddStep("add smoogipoo", () => createRandomScore(new APIUser { Username = "smoogipoo", Id = 1040328 }));
|
||||||
AddStep("add flyte", () => createRandomScore(new APIUser { Username = "flyte", Id = 3103765 }));
|
AddStep("add flyte", () => createRandomScore(new APIUser { Username = "flyte", Id = 3103765 }));
|
||||||
@ -89,6 +112,9 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestMaxHeight()
|
public void TestMaxHeight()
|
||||||
{
|
{
|
||||||
|
createLeaderboard();
|
||||||
|
addLocalPlayer();
|
||||||
|
|
||||||
int playerNumber = 1;
|
int playerNumber = 1;
|
||||||
AddRepeatStep("add 3 other players", () => createRandomScore(new APIUser { Username = $"Player {playerNumber++}" }), 3);
|
AddRepeatStep("add 3 other players", () => createRandomScore(new APIUser { Username = $"Player {playerNumber++}" }), 3);
|
||||||
checkHeight(4);
|
checkHeight(4);
|
||||||
@ -103,6 +129,28 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
=> AddAssert($"leaderboard height is {panelCount} panels high", () => leaderboard.DrawHeight == (GameplayLeaderboardScore.PANEL_HEIGHT + leaderboard.Spacing) * panelCount);
|
=> AddAssert($"leaderboard height is {panelCount} panels high", () => leaderboard.DrawHeight == (GameplayLeaderboardScore.PANEL_HEIGHT + leaderboard.Spacing) * panelCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addLocalPlayer()
|
||||||
|
{
|
||||||
|
AddStep("add local player", () =>
|
||||||
|
{
|
||||||
|
playerScore.Value = 1222333;
|
||||||
|
createLeaderboardScore(playerScore, new APIUser { Username = "You", Id = 3 }, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createLeaderboard()
|
||||||
|
{
|
||||||
|
AddStep("create leaderboard", () =>
|
||||||
|
{
|
||||||
|
Child = leaderboard = new TestGameplayLeaderboard
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Scale = new Vector2(2),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void createRandomScore(APIUser user) => createLeaderboardScore(new BindableDouble(RNG.Next(0, 5_000_000)), user);
|
private void createRandomScore(APIUser user) => createLeaderboardScore(new BindableDouble(RNG.Next(0, 5_000_000)), user);
|
||||||
|
|
||||||
private void createLeaderboardScore(BindableDouble score, APIUser user, bool isTracked = false)
|
private void createLeaderboardScore(BindableDouble score, APIUser user, bool isTracked = false)
|
||||||
|
@ -96,6 +96,14 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
|
|
||||||
int displayCount = Math.Min(Flow.Count, maxPanels);
|
int displayCount = Math.Min(Flow.Count, maxPanels);
|
||||||
Height = displayCount * (GameplayLeaderboardScore.PANEL_HEIGHT + Flow.Spacing.Y);
|
Height = displayCount * (GameplayLeaderboardScore.PANEL_HEIGHT + Flow.Spacing.Y);
|
||||||
|
// Add extra margin space to flow equal to height of leaderboard.
|
||||||
|
// This ensures the content is always on screen, but also accounts for the fact that scroll operations
|
||||||
|
// without animation were actually forcing the local score to a location it can't usually reside at.
|
||||||
|
//
|
||||||
|
// Basically, the local score was in the scroll extension region (due to always trying to scroll the
|
||||||
|
// local player to the middle of the display, but there being no other content below the local player
|
||||||
|
// to scroll up by).
|
||||||
|
Flow.Margin = new MarginPadding { Bottom = Height };
|
||||||
requiresScroll = displayCount != Flow.Count;
|
requiresScroll = displayCount != Flow.Count;
|
||||||
|
|
||||||
return drawable;
|
return drawable;
|
||||||
@ -118,7 +126,7 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
if (requiresScroll && trackedScore != null)
|
if (requiresScroll && trackedScore != null)
|
||||||
{
|
{
|
||||||
float scrollTarget = scroll.GetChildPosInContent(trackedScore) + trackedScore.DrawHeight / 2 - scroll.DrawHeight / 2;
|
float scrollTarget = scroll.GetChildPosInContent(trackedScore) + trackedScore.DrawHeight / 2 - scroll.DrawHeight / 2;
|
||||||
scroll.ScrollTo(scrollTarget, false);
|
scroll.ScrollTo(scrollTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
const float panel_height = GameplayLeaderboardScore.PANEL_HEIGHT;
|
const float panel_height = GameplayLeaderboardScore.PANEL_HEIGHT;
|
||||||
|
Loading…
Reference in New Issue
Block a user