1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-14 03:25:11 +08:00

Rename class and move inside HUD namespace

This commit is contained in:
Dean Herbert 2020-12-15 15:27:26 +09:00
parent dd5572b20a
commit 8b68ccc0ff
4 changed files with 122 additions and 158 deletions

View File

@ -6,27 +6,27 @@ using NUnit.Framework;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Testing;
using osu.Game.Screens.Play;
using osu.Game.Screens.Play.HUD;
using osu.Game.Users;
using osuTK;
namespace osu.Game.Tests.Visual.Gameplay
{
[TestFixture]
public class TestSceneInGameLeaderboard : OsuTestScene
public class TestSceneGameplayLeaderboard : OsuTestScene
{
private readonly TestInGameLeaderboard leaderboard;
private readonly BindableDouble playerScore;
private readonly TestGameplayLeaderboard leaderboard;
public TestSceneInGameLeaderboard()
private readonly BindableDouble playerScore = new BindableDouble();
public TestSceneGameplayLeaderboard()
{
Add(leaderboard = new TestInGameLeaderboard
Add(leaderboard = new TestGameplayLeaderboard
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(2),
RelativeSizeAxes = Axes.X,
PlayerCurrentScore = { BindTarget = playerScore = new BindableDouble(1222333) }
});
}
@ -35,11 +35,11 @@ namespace osu.Game.Tests.Visual.Gameplay
{
AddStep("reset leaderboard", () =>
{
leaderboard.ClearScores();
leaderboard.Clear();
playerScore.Value = 1222333;
});
AddStep("add player user", () => leaderboard.PlayerUser = new User { Username = "You" });
AddStep("add player user", () => leaderboard.AddRealTimePlayer(playerScore, new User { Username = "You" }));
AddSliderStep("set player score", 50, 5000000, 1222333, v => playerScore.Value = v);
}
@ -49,8 +49,8 @@ namespace osu.Game.Tests.Visual.Gameplay
var player2Score = new BindableDouble(1234567);
var player3Score = new BindableDouble(1111111);
AddStep("add player 2", () => leaderboard.AddDummyPlayer(player2Score, "Player 2"));
AddStep("add player 3", () => leaderboard.AddDummyPlayer(player3Score, "Player 3"));
AddStep("add player 2", () => leaderboard.AddRealTimePlayer(player2Score, new User { Username = "Player 2" }));
AddStep("add player 3", () => leaderboard.AddRealTimePlayer(player3Score, new User { Username = "Player 3" }));
AddAssert("is player 2 position #1", () => leaderboard.CheckPositionByUsername("Player 2", 1));
AddAssert("is player position #2", () => leaderboard.CheckPositionByUsername("You", 2));
@ -67,18 +67,14 @@ namespace osu.Game.Tests.Visual.Gameplay
AddAssert("is player 2 position #3", () => leaderboard.CheckPositionByUsername("Player 2", 3));
}
private class TestInGameLeaderboard : InGameLeaderboard
private class TestGameplayLeaderboard : GameplayLeaderboard
{
public void ClearScores() => ScoresContainer.RemoveAll(s => s.User.Username != PlayerUser.Username);
public bool CheckPositionByUsername(string username, int? estimatedPosition)
public bool CheckPositionByUsername(string username, int? expectedPosition)
{
var scoreItem = ScoresContainer.FirstOrDefault(i => i.User.Username == username);
var scoreItem = this.FirstOrDefault(i => i.User.Username == username);
return scoreItem != null && scoreItem.ScorePosition == estimatedPosition;
return scoreItem != null && scoreItem.ScorePosition == expectedPosition;
}
public void AddDummyPlayer(BindableDouble currentScore, string username) => ScoresContainer.AddRealTimePlayer(currentScore, new User { Username = username });
}
}
}

View File

@ -0,0 +1,104 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Linq;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Scoring;
using osu.Game.Users;
using osuTK;
namespace osu.Game.Screens.Play.HUD
{
public class GameplayLeaderboard : FillFlowContainer<GameplayLeaderboardScore>
{
/// <summary>
/// Whether to declare a new position for un-positioned players.
/// Must be disabled for online leaderboards with top 50 scores only.
/// </summary>
public bool DeclareNewPosition = true;
public GameplayLeaderboard()
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Direction = FillDirection.Vertical;
Spacing = new Vector2(2.5f);
LayoutDuration = 500;
LayoutEasing = Easing.OutQuint;
}
/// <summary>
/// Adds a real-time player score item whose score is updated via a <see cref="BindableDouble"/>.
/// </summary>
/// <param name="currentScore">The bindable current score of the player.</param>
/// <param name="user">The player user.</param>
/// <returns>Returns the drawable score item of that player.</returns>
public GameplayLeaderboardScore AddRealTimePlayer(BindableDouble currentScore, User user = null)
{
if (currentScore == null)
return null;
var scoreItem = addScore(currentScore.Value, user);
currentScore.ValueChanged += s => scoreItem.TotalScore = s.NewValue;
return scoreItem;
}
/// <summary>
/// Adds a score item based off a <see cref="ScoreInfo"/> with an initial position.
/// </summary>
/// <param name="score">The score info to use for this item.</param>
/// <param name="initialPosition">The initial position of this item.</param>
/// <returns>Returns the drawable score item of that player.</returns>
public GameplayLeaderboardScore AddScore(ScoreInfo score, int? initialPosition = null) => score != null ? addScore(score.TotalScore, score.User, initialPosition) : null;
private int maxPosition => this.Max(i => this.Any(item => item.InitialPosition.HasValue) ? i.InitialPosition : i.ScorePosition) ?? 0;
private GameplayLeaderboardScore addScore(double totalScore, User user = null, int? position = null)
{
var scoreItem = new GameplayLeaderboardScore(position)
{
User = user,
TotalScore = totalScore,
OnScoreChange = updateScores,
};
Add(scoreItem);
SetLayoutPosition(scoreItem, position ?? maxPosition + 1);
reorderPositions();
return scoreItem;
}
private void reorderPositions()
{
var orderedByScore = this.OrderByDescending(i => i.TotalScore).ToList();
var orderedPositions = this.Select(i => this.Any(item => item.InitialPosition.HasValue) ? i.InitialPosition : i.ScorePosition).OrderByDescending(p => p.HasValue).ThenBy(p => p).ToList();
for (int i = 0; i < Count; i++)
{
int newPosition = orderedPositions[i] ?? maxPosition + 1;
SetLayoutPosition(orderedByScore[i], newPosition);
orderedByScore[i].ScorePosition = DeclareNewPosition ? newPosition : orderedPositions[i];
}
}
private void updateScores()
{
var orderedByScore = this.OrderByDescending(i => i.TotalScore).ToList();
var orderedPositions = this.Select(i => this.Any(item => item.InitialPosition.HasValue) ? i.InitialPosition : i.ScorePosition).OrderByDescending(p => p.HasValue).ThenBy(p => p).ToList();
for (int i = 0; i < Count; i++)
{
int newPosition = orderedPositions[i] ?? maxPosition + 1;
SetLayoutPosition(orderedByScore[i], newPosition);
orderedByScore[i].ScorePosition = DeclareNewPosition ? newPosition : orderedPositions[i];
}
}
}
}

View File

@ -2,113 +2,19 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Linq;
using Humanizer;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Scoring;
using osu.Game.Users;
using osuTK;
namespace osu.Game.Screens.Play
namespace osu.Game.Screens.Play.HUD
{
public class InGameScoreContainer : FillFlowContainer<InGameScoreItem>
{
/// <summary>
/// Whether to declare a new position for un-positioned players.
/// Must be disabled for online leaderboards with top 50 scores only.
/// </summary>
public bool DeclareNewPosition = true;
public InGameScoreContainer()
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Direction = FillDirection.Vertical;
Spacing = new Vector2(2.5f);
LayoutDuration = 500;
LayoutEasing = Easing.OutQuint;
}
/// <summary>
/// Adds a real-time player score item whose score is updated via a <see cref="BindableDouble"/>.
/// </summary>
/// <param name="currentScore">The bindable current score of the player.</param>
/// <param name="user">The player user.</param>
/// <returns>Returns the drawable score item of that player.</returns>
public InGameScoreItem AddRealTimePlayer(BindableDouble currentScore, User user = null)
{
if (currentScore == null)
return null;
var scoreItem = addScore(currentScore.Value, user);
currentScore.ValueChanged += s => scoreItem.TotalScore = s.NewValue;
return scoreItem;
}
/// <summary>
/// Adds a score item based off a <see cref="ScoreInfo"/> with an initial position.
/// </summary>
/// <param name="score">The score info to use for this item.</param>
/// <param name="initialPosition">The initial position of this item.</param>
/// <returns>Returns the drawable score item of that player.</returns>
public InGameScoreItem AddScore(ScoreInfo score, int? initialPosition = null) => score != null ? addScore(score.TotalScore, score.User, initialPosition) : null;
private int maxPosition => this.Max(i => this.Any(item => item.InitialPosition.HasValue) ? i.InitialPosition : i.ScorePosition) ?? 0;
private InGameScoreItem addScore(double totalScore, User user = null, int? position = null)
{
var scoreItem = new InGameScoreItem(position)
{
User = user,
TotalScore = totalScore,
OnScoreChange = updateScores,
};
Add(scoreItem);
SetLayoutPosition(scoreItem, position ?? maxPosition + 1);
reorderPositions();
return scoreItem;
}
private void reorderPositions()
{
var orderedByScore = this.OrderByDescending(i => i.TotalScore).ToList();
var orderedPositions = this.Select(i => this.Any(item => item.InitialPosition.HasValue) ? i.InitialPosition : i.ScorePosition).OrderByDescending(p => p.HasValue).ThenBy(p => p).ToList();
for (int i = 0; i < Count; i++)
{
int newPosition = orderedPositions[i] ?? maxPosition + 1;
SetLayoutPosition(orderedByScore[i], newPosition);
orderedByScore[i].ScorePosition = DeclareNewPosition ? newPosition : orderedPositions[i];
}
}
private void updateScores()
{
var orderedByScore = this.OrderByDescending(i => i.TotalScore).ToList();
var orderedPositions = this.Select(i => this.Any(item => item.InitialPosition.HasValue) ? i.InitialPosition : i.ScorePosition).OrderByDescending(p => p.HasValue).ThenBy(p => p).ToList();
for (int i = 0; i < Count; i++)
{
int newPosition = orderedPositions[i] ?? maxPosition + 1;
SetLayoutPosition(orderedByScore[i], newPosition);
orderedByScore[i].ScorePosition = DeclareNewPosition ? newPosition : orderedPositions[i];
}
}
}
public class InGameScoreItem : CompositeDrawable
public class GameplayLeaderboardScore : CompositeDrawable
{
private readonly OsuSpriteText positionText, positionSymbol, userString;
private readonly GlowingSpriteText scoreText;
@ -159,7 +65,7 @@ namespace osu.Game.Screens.Play
}
}
public InGameScoreItem(int? initialPosition)
public GameplayLeaderboardScore(int? initialPosition)
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;

View File

@ -1,42 +0,0 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Users;
namespace osu.Game.Screens.Play
{
public class InGameLeaderboard : CompositeDrawable
{
protected readonly InGameScoreContainer ScoresContainer;
public readonly BindableDouble PlayerCurrentScore = new BindableDouble();
private bool playerItemCreated;
private User playerUser;
public User PlayerUser
{
get => playerUser;
set
{
playerUser = value;
if (playerItemCreated)
return;
ScoresContainer.AddRealTimePlayer(PlayerCurrentScore, playerUser);
playerItemCreated = true;
}
}
public InGameLeaderboard()
{
AutoSizeAxes = Axes.Y;
InternalChild = ScoresContainer = new InGameScoreContainer();
}
}
}