mirror of
https://github.com/ppy/osu.git
synced 2026-05-23 13:20:31 +08:00
Implement local user position display for multiplayer
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
// 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 NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osu.Game.Tests.Gameplay;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
public partial class TestSceneMultiplayerPositionDisplay : OsuTestScene
|
||||
{
|
||||
[Resolved]
|
||||
private OsuConfigManager config { get; set; } = null!;
|
||||
|
||||
[Test]
|
||||
public void TestAppearance()
|
||||
{
|
||||
TestGameplayLeaderboardProvider leaderboard = null!;
|
||||
MultiplayerPositionDisplay display = null!;
|
||||
GameplayState gameplayState = null!;
|
||||
|
||||
AddStep("create content", () =>
|
||||
{
|
||||
leaderboard = new TestGameplayLeaderboardProvider();
|
||||
Children = new Drawable[]
|
||||
{
|
||||
leaderboard,
|
||||
new DependencyProvidingContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
CachedDependencies =
|
||||
[
|
||||
(typeof(IGameplayLeaderboardProvider), leaderboard),
|
||||
(typeof(GameplayState), gameplayState = TestGameplayState.Create(new OsuRuleset()))
|
||||
],
|
||||
Child = display = new MultiplayerPositionDisplay
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
AddSliderStep("set score position", 1, 100, 50, r =>
|
||||
{
|
||||
if (leaderboard.IsNotNull() && leaderboard.Score.IsNotNull())
|
||||
leaderboard.Score.Position.Value = r;
|
||||
});
|
||||
AddStep("unset position", () => leaderboard.Score.Position.Value = null);
|
||||
|
||||
AddStep("toggle leaderboard on", () => config.SetValue(OsuSetting.GameplayLeaderboard, true));
|
||||
AddUntilStep("display visible", () => display.Alpha, () => Is.EqualTo(1));
|
||||
|
||||
AddStep("toggle leaderboard off", () => config.SetValue(OsuSetting.GameplayLeaderboard, false));
|
||||
AddUntilStep("display hidden", () => display.Alpha, () => Is.EqualTo(0));
|
||||
|
||||
AddStep("enter break", () => ((Bindable<LocalUserPlayingState>)gameplayState.PlayingState).Value = LocalUserPlayingState.Break);
|
||||
AddUntilStep("display visible", () => display.Alpha, () => Is.EqualTo(1));
|
||||
|
||||
AddStep("exit break", () => ((Bindable<LocalUserPlayingState>)gameplayState.PlayingState).Value = LocalUserPlayingState.Playing);
|
||||
AddUntilStep("display hidden", () => display.Alpha, () => Is.EqualTo(0));
|
||||
|
||||
AddStep("toggle leaderboard on", () => config.SetValue(OsuSetting.GameplayLeaderboard, true));
|
||||
AddUntilStep("display visible", () => display.Alpha, () => Is.EqualTo(1));
|
||||
|
||||
AddStep("change local user", () => ((DummyAPIAccess)API).LocalUser.Value = new GuestUser());
|
||||
AddUntilStep("display hidden", () => display.Alpha, () => Is.EqualTo(0));
|
||||
}
|
||||
|
||||
private partial class TestGameplayLeaderboardProvider : Component, IGameplayLeaderboardProvider
|
||||
{
|
||||
public GameplayLeaderboardScore Score { get; private set; } = null!;
|
||||
|
||||
IBindableList<GameplayLeaderboardScore> IGameplayLeaderboardProvider.Scores => scores;
|
||||
private readonly BindableList<GameplayLeaderboardScore> scores = new BindableList<GameplayLeaderboardScore>();
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(IAPIProvider api)
|
||||
{
|
||||
scores.Add(Score = new GameplayLeaderboardScore(api.LocalUser.Value, true, new BindableLong()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// 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.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
||||
{
|
||||
public partial class MultiplayerPositionDisplay : CompositeDrawable
|
||||
{
|
||||
private readonly IBindable<APIUser> user = new Bindable<APIUser>();
|
||||
private readonly IBindableList<GameplayLeaderboardScore> scores = new BindableList<GameplayLeaderboardScore>();
|
||||
private readonly BindableBool showLeaderboard = new BindableBool();
|
||||
private readonly IBindable<LocalUserPlayingState> localUserPlayingState = new Bindable<LocalUserPlayingState>();
|
||||
|
||||
private readonly Bindable<int?> position = new Bindable<int?>();
|
||||
|
||||
private OsuSpriteText positionText = null!;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(IGameplayLeaderboardProvider leaderboardProvider, IAPIProvider api, OsuConfigManager configManager, GameplayState gameplayState)
|
||||
{
|
||||
scores.BindTo(leaderboardProvider.Scores);
|
||||
user.BindTo(api.LocalUser);
|
||||
configManager.BindWith(OsuSetting.GameplayLeaderboard, showLeaderboard);
|
||||
localUserPlayingState.BindTo(gameplayState.PlayingState);
|
||||
|
||||
AutoSizeAxes = Axes.Both;
|
||||
InternalChild = positionText = new OsuSpriteText
|
||||
{
|
||||
Alpha = 0.5f,
|
||||
Font = OsuFont.Torus.With(size: 60, weight: FontWeight.Light),
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
user.BindValueChanged(_ => updateState());
|
||||
scores.BindCollectionChanged((_, __) => updateState());
|
||||
showLeaderboard.BindValueChanged(_ => updateState());
|
||||
localUserPlayingState.BindValueChanged(_ => updateState(), true);
|
||||
|
||||
position.BindValueChanged(_ => positionText.Text = position.Value != null ? $@"#{position.Value.Value:N0}" : "-", true);
|
||||
}
|
||||
|
||||
private void updateState()
|
||||
{
|
||||
position.UnbindBindings();
|
||||
|
||||
var userScore = scores.SingleOrDefault(s => s.User.Equals(user.Value));
|
||||
if (userScore != null)
|
||||
position.BindTo(userScore.Position);
|
||||
else
|
||||
position.Value = null;
|
||||
|
||||
Alpha = userScore != null && (showLeaderboard.Value || localUserPlayingState.Value == LocalUserPlayingState.Break) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user