1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-05 10:33:22 +08:00

Compare commits

...

10 Commits

Author SHA1 Message Date
Dean Herbert
cb3069461c
Merge pull request #8309 from smoogipoo/results-top-content
Implement the top score panel contents
2020-03-17 21:35:59 +09:00
Dean Herbert
75695938e2
Merge branch 'master' into results-top-content 2020-03-17 20:42:02 +09:00
Dean Herbert
18a98c8e73
Merge pull request #8308 from smoogipoo/results-scorepanel
Implement the results screen score panel
2020-03-17 20:41:46 +09:00
Dean Herbert
3b9c64b76f
Merge branch 'master' into results-scorepanel 2020-03-17 20:06:11 +09:00
Dean Herbert
af092966e4
Merge pull request #8302 from peppy/start-match-on-gameplay
Automatically mark the currently selected match as started on entering gameplay screen
2020-03-17 20:04:56 +09:00
Dan Balasescu
c6e4bf35de
Merge branch 'master' into start-match-on-gameplay 2020-03-17 18:21:55 +09:00
smoogipoo
6f801e1695 Add xmldoc 2020-03-17 17:35:14 +09:00
smoogipoo
7cc1a6040f Implement top panel contents 2020-03-17 17:01:38 +09:00
smoogipoo
05789e6fe4 Implement the score panel 2020-03-17 16:59:34 +09:00
Dean Herbert
99f28efc96 Automatically mark the currently selected match as stsrated on entering gameplay screen 2020-03-17 13:16:52 +09:00
7 changed files with 506 additions and 4 deletions

View File

@ -0,0 +1,35 @@
// 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.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Screens.Ranking.Expanded;
using osu.Game.Users;
using osuTK;
namespace osu.Game.Tests.Visual.Ranking
{
public class TestSceneExpandedPanelTopContent : OsuTestScene
{
public TestSceneExpandedPanelTopContent()
{
Child = new Container
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(500, 200),
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4Extensions.FromHex("#444"),
},
new ExpandedPanelTopContent(new User { Id = 2, Username = "peppy" }),
}
};
}
}
}

View File

@ -0,0 +1,143 @@
// 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;
using System.Collections.Generic;
using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
using osu.Game.Screens.Ranking;
using osu.Game.Screens.Ranking.Expanded;
using osu.Game.Tests.Beatmaps;
using osu.Game.Users;
namespace osu.Game.Tests.Visual.Ranking
{
public class TestSceneScorePanel : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(ScorePanel),
typeof(PanelState),
typeof(ExpandedPanelMiddleContent),
typeof(ExpandedPanelTopContent),
};
[Test]
public void TestDRank()
{
var score = createScore();
score.Accuracy = 0.5;
score.Rank = ScoreRank.D;
addPanelStep(score);
}
[Test]
public void TestCRank()
{
var score = createScore();
score.Accuracy = 0.75;
score.Rank = ScoreRank.C;
addPanelStep(score);
}
[Test]
public void TestBRank()
{
var score = createScore();
score.Accuracy = 0.85;
score.Rank = ScoreRank.B;
addPanelStep(score);
}
[Test]
public void TestARank()
{
var score = createScore();
score.Accuracy = 0.925;
score.Rank = ScoreRank.A;
addPanelStep(score);
}
[Test]
public void TestSRank()
{
var score = createScore();
score.Accuracy = 0.975;
score.Rank = ScoreRank.S;
addPanelStep(score);
}
[Test]
public void TestAlmostSSRank()
{
var score = createScore();
score.Accuracy = 0.9999;
score.Rank = ScoreRank.S;
addPanelStep(score);
}
[Test]
public void TestSSRank()
{
var score = createScore();
score.Accuracy = 1;
score.Rank = ScoreRank.X;
addPanelStep(score);
}
[Test]
public void TestAllHitResults()
{
var score = createScore();
score.Statistics[HitResult.Perfect] = 350;
score.Statistics[HitResult.Ok] = 200;
addPanelStep(score);
}
private void addPanelStep(ScoreInfo score) => AddStep("add panel", () =>
{
Child = new ScorePanel(score)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
State = PanelState.Expanded
};
});
private ScoreInfo createScore() => new ScoreInfo
{
User = new User
{
Id = 2,
Username = "peppy",
},
Beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo,
Mods = new Mod[] { new OsuModHardRock(), new OsuModDoubleTime() },
TotalScore = 2845370,
Accuracy = 0.95,
MaxCombo = 999,
Rank = ScoreRank.S,
Date = DateTimeOffset.Now,
Statistics =
{
{ HitResult.Miss, 1 },
{ HitResult.Meh, 50 },
{ HitResult.Good, 100 },
{ HitResult.Great, 300 },
}
};
}
}

View File

@ -35,7 +35,9 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components
private void load(LadderInfo ladder)
{
currentMatch.BindTo(ladder.CurrentMatch);
currentMatch.BindValueChanged(matchChanged, true);
currentMatch.BindValueChanged(matchChanged);
updateMatch();
}
private void matchChanged(ValueChangedEvent<TournamentMatch> match)
@ -43,10 +45,19 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components
currentTeamScore.UnbindBindings();
currentTeam.UnbindBindings();
if (match.NewValue != null)
Scheduler.AddOnce(updateMatch);
}
private void updateMatch()
{
var match = currentMatch.Value;
if (match != null)
{
currentTeamScore.BindTo(teamColour == TeamColour.Red ? match.NewValue.Team1Score : match.NewValue.Team2Score);
currentTeam.BindTo(teamColour == TeamColour.Red ? match.NewValue.Team1 : match.NewValue.Team2);
match.StartMatch();
currentTeamScore.BindTo(teamColour == TeamColour.Red ? match.Team1Score : match.Team2Score);
currentTeam.BindTo(teamColour == TeamColour.Red ? match.Team1 : match.Team2);
}
// team may change to same team, which means score is not in a good state.

View File

@ -0,0 +1,15 @@
// 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.Graphics.Containers;
using osu.Game.Scoring;
namespace osu.Game.Screens.Ranking.Expanded
{
public class ExpandedPanelMiddleContent : CompositeDrawable
{
public ExpandedPanelMiddleContent(ScoreInfo score)
{
}
}
}

View File

@ -0,0 +1,64 @@
// 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.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Users;
using osu.Game.Users.Drawables;
using osuTK;
namespace osu.Game.Screens.Ranking.Expanded
{
/// <summary>
/// The content that appears in the middle section of the <see cref="ScorePanel"/>.
/// </summary>
public class ExpandedPanelTopContent : CompositeDrawable
{
private readonly User user;
/// <summary>
/// Creates a new <see cref="ExpandedPanelTopContent"/>.
/// </summary>
/// <param name="user">The <see cref="User"/> to display.</param>
public ExpandedPanelTopContent(User user)
{
this.user = user;
Anchor = Anchor.TopCentre;
Origin = Anchor.Centre;
AutoSizeAxes = Axes.Both;
}
[BackgroundDependencyLoader]
private void load()
{
InternalChild = new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
new UpdateableAvatar(user)
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Size = new Vector2(80),
CornerRadius = 20,
CornerExponent = 2.5f,
Masking = true,
},
new OsuSpriteText
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Text = user.Username,
Font = OsuFont.Torus.With(size: 16, weight: FontWeight.SemiBold)
}
}
};
}
}
}

View File

@ -0,0 +1,11 @@
// 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.
namespace osu.Game.Screens.Ranking
{
public enum PanelState
{
Expanded,
Contracted
}
}

View File

@ -0,0 +1,223 @@
// 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;
using osu.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Scoring;
using osu.Game.Screens.Ranking.Expanded;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Screens.Ranking
{
public class ScorePanel : CompositeDrawable, IStateful<PanelState>
{
/// <summary>
/// Width of the panel when contracted.
/// </summary>
private const float contracted_width = 160;
/// <summary>
/// Height of the panel when contracted.
/// </summary>
private const float contracted_height = 320;
/// <summary>
/// Width of the panel when expanded.
/// </summary>
private const float expanded_width = 360;
/// <summary>
/// Height of the panel when expanded.
/// </summary>
private const float expanded_height = 560;
/// <summary>
/// Height of the top layer when the panel is expanded.
/// </summary>
private const float expanded_top_layer_height = 53;
/// <summary>
/// Height of the top layer when the panel is contracted.
/// </summary>
private const float contracted_top_layer_height = 40;
/// <summary>
/// Duration for the panel to resize into its expanded/contracted size.
/// </summary>
private const double resize_duration = 200;
/// <summary>
/// Delay after <see cref="resize_duration"/> before the top layer is expanded.
/// </summary>
private const double top_layer_expand_delay = 100;
/// <summary>
/// Duration for the top layer expansion.
/// </summary>
private const double top_layer_expand_duration = 200;
/// <summary>
/// Duration for the panel contents to fade in.
/// </summary>
private const double content_fade_duration = 50;
private static readonly ColourInfo expanded_top_layer_colour = ColourInfo.GradientVertical(Color4Extensions.FromHex("#444"), Color4Extensions.FromHex("#333"));
private static readonly ColourInfo expanded_middle_layer_colour = ColourInfo.GradientVertical(Color4Extensions.FromHex("#555"), Color4Extensions.FromHex("#333"));
private static readonly Color4 contracted_top_layer_colour = Color4Extensions.FromHex("#353535");
private static readonly Color4 contracted_middle_layer_colour = Color4Extensions.FromHex("#444");
public event Action<PanelState> StateChanged;
private readonly ScoreInfo score;
private Container topLayerContainer;
private Drawable topLayerBackground;
private Container topLayerContentContainer;
private Drawable topLayerContent;
private Container middleLayerContainer;
private Drawable middleLayerBackground;
private Container middleLayerContentContainer;
private Drawable middleLayerContent;
public ScorePanel(ScoreInfo score)
{
this.score = score;
}
[BackgroundDependencyLoader]
private void load()
{
InternalChildren = new Drawable[]
{
topLayerContainer = new Container
{
Name = "Top layer",
RelativeSizeAxes = Axes.X,
Height = 120,
Children = new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.Both,
CornerRadius = 20,
CornerExponent = 2.5f,
Masking = true,
Child = topLayerBackground = new Box { RelativeSizeAxes = Axes.Both }
},
topLayerContentContainer = new Container { RelativeSizeAxes = Axes.Both }
}
},
middleLayerContainer = new Container
{
Name = "Middle layer",
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.Both,
CornerRadius = 20,
CornerExponent = 2.5f,
Masking = true,
Child = middleLayerBackground = new Box { RelativeSizeAxes = Axes.Both }
},
middleLayerContentContainer = new Container { RelativeSizeAxes = Axes.Both }
}
}
};
}
protected override void LoadComplete()
{
base.LoadComplete();
if (state == PanelState.Expanded)
{
topLayerBackground.FadeColour(expanded_top_layer_colour);
middleLayerBackground.FadeColour(expanded_middle_layer_colour);
}
else
{
topLayerBackground.FadeColour(contracted_top_layer_colour);
middleLayerBackground.FadeColour(contracted_middle_layer_colour);
}
updateState();
}
private PanelState state = PanelState.Contracted;
public PanelState State
{
get => state;
set
{
if (state == value)
return;
state = value;
if (LoadState >= LoadState.Ready)
updateState();
StateChanged?.Invoke(value);
}
}
private void updateState()
{
topLayerContainer.MoveToY(0, resize_duration, Easing.OutQuint);
middleLayerContainer.MoveToY(0, resize_duration, Easing.OutQuint);
topLayerContent?.FadeOut(content_fade_duration).Expire();
middleLayerContent?.FadeOut(content_fade_duration).Expire();
switch (state)
{
case PanelState.Expanded:
this.ResizeTo(new Vector2(expanded_width, expanded_height), resize_duration, Easing.OutQuint);
topLayerBackground.FadeColour(expanded_top_layer_colour, resize_duration, Easing.OutQuint);
middleLayerBackground.FadeColour(expanded_middle_layer_colour, resize_duration, Easing.OutQuint);
topLayerContentContainer.Add(middleLayerContent = new ExpandedPanelTopContent(score.User).With(d => d.Alpha = 0));
middleLayerContentContainer.Add(topLayerContent = new ExpandedPanelMiddleContent(score).With(d => d.Alpha = 0));
break;
case PanelState.Contracted:
this.ResizeTo(new Vector2(contracted_width, contracted_height), resize_duration, Easing.OutQuint);
topLayerBackground.FadeColour(contracted_top_layer_colour, resize_duration, Easing.OutQuint);
middleLayerBackground.FadeColour(contracted_middle_layer_colour, resize_duration, Easing.OutQuint);
break;
}
using (BeginDelayedSequence(resize_duration + top_layer_expand_delay, true))
{
switch (state)
{
case PanelState.Expanded:
topLayerContainer.MoveToY(-expanded_top_layer_height / 2, top_layer_expand_duration, Easing.OutQuint);
middleLayerContainer.MoveToY(expanded_top_layer_height / 2, top_layer_expand_duration, Easing.OutQuint);
break;
case PanelState.Contracted:
topLayerContainer.MoveToY(-contracted_top_layer_height / 2, top_layer_expand_duration, Easing.OutQuint);
middleLayerContainer.MoveToY(contracted_top_layer_height / 2, top_layer_expand_duration, Easing.OutQuint);
break;
}
topLayerContent?.FadeIn(content_fade_duration);
middleLayerContent?.FadeIn(content_fade_duration);
}
}
}
}