mirror of
https://github.com/osukey/osukey.git
synced 2025-06-05 12:57:39 +09:00
Merge branch 'results-middle-content' into results-screen
This commit is contained in:
commit
afed01d781
155
osu.Game.Tests/Visual/Ranking/TestSceneAccuracyCircle.cs
Normal file
155
osu.Game.Tests/Visual/Ranking/TestSceneAccuracyCircle.cs
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
// 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.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Colour;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
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.Expanded.Accuracy;
|
||||||
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
using osu.Game.Users;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Ranking
|
||||||
|
{
|
||||||
|
public class TestSceneAccuracyCircle : OsuTestScene
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(AccuracyCircle),
|
||||||
|
typeof(RankBadge),
|
||||||
|
typeof(RankNotch),
|
||||||
|
typeof(RankText),
|
||||||
|
typeof(SmoothCircularProgress)
|
||||||
|
};
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestDRank()
|
||||||
|
{
|
||||||
|
var score = createScore();
|
||||||
|
score.Accuracy = 0.5;
|
||||||
|
score.Rank = ScoreRank.D;
|
||||||
|
|
||||||
|
addCircleStep(score);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestCRank()
|
||||||
|
{
|
||||||
|
var score = createScore();
|
||||||
|
score.Accuracy = 0.75;
|
||||||
|
score.Rank = ScoreRank.C;
|
||||||
|
|
||||||
|
addCircleStep(score);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestBRank()
|
||||||
|
{
|
||||||
|
var score = createScore();
|
||||||
|
score.Accuracy = 0.85;
|
||||||
|
score.Rank = ScoreRank.B;
|
||||||
|
|
||||||
|
addCircleStep(score);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestARank()
|
||||||
|
{
|
||||||
|
var score = createScore();
|
||||||
|
score.Accuracy = 0.925;
|
||||||
|
score.Rank = ScoreRank.A;
|
||||||
|
|
||||||
|
addCircleStep(score);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSRank()
|
||||||
|
{
|
||||||
|
var score = createScore();
|
||||||
|
score.Accuracy = 0.975;
|
||||||
|
score.Rank = ScoreRank.S;
|
||||||
|
|
||||||
|
addCircleStep(score);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestAlmostSSRank()
|
||||||
|
{
|
||||||
|
var score = createScore();
|
||||||
|
score.Accuracy = 0.9999;
|
||||||
|
score.Rank = ScoreRank.S;
|
||||||
|
|
||||||
|
addCircleStep(score);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSSRank()
|
||||||
|
{
|
||||||
|
var score = createScore();
|
||||||
|
score.Accuracy = 1;
|
||||||
|
score.Rank = ScoreRank.X;
|
||||||
|
|
||||||
|
addCircleStep(score);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addCircleStep(ScoreInfo score) => AddStep("add panel", () =>
|
||||||
|
{
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Size = new Vector2(500, 700),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = ColourInfo.GradientVertical(Color4Extensions.FromHex("#555"), Color4Extensions.FromHex("#333"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new AccuracyCircle(score)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Size = new Vector2(230)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
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 },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
// 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 osu.Framework.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
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.Expanded;
|
||||||
|
using osu.Game.Screens.Ranking.Expanded.Accuracy;
|
||||||
|
using osu.Game.Screens.Ranking.Expanded.Statistics;
|
||||||
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
using osu.Game.Users;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Ranking
|
||||||
|
{
|
||||||
|
public class TestSceneExpandedPanelMiddleContent : OsuTestScene
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(ExpandedPanelMiddleContent),
|
||||||
|
typeof(AccuracyCircle),
|
||||||
|
typeof(AccuracyStatistic),
|
||||||
|
typeof(ComboStatistic),
|
||||||
|
typeof(CounterStatistic),
|
||||||
|
typeof(StarRatingDisplay),
|
||||||
|
typeof(StatisticDisplay),
|
||||||
|
typeof(TotalScoreCounter)
|
||||||
|
};
|
||||||
|
|
||||||
|
public TestSceneExpandedPanelMiddleContent()
|
||||||
|
{
|
||||||
|
Child = new Container
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Size = new Vector2(500, 700),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4Extensions.FromHex("#444"),
|
||||||
|
},
|
||||||
|
new ExpandedPanelMiddleContent(createTestScore())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private ScoreInfo createTestScore() => new ScoreInfo
|
||||||
|
{
|
||||||
|
User = new User
|
||||||
|
{
|
||||||
|
Id = 2,
|
||||||
|
Username = "peppy",
|
||||||
|
},
|
||||||
|
Beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo,
|
||||||
|
Mods = new Mod[] { new OsuModHardRock(), new OsuModDoubleTime() },
|
||||||
|
TotalScore = 999999,
|
||||||
|
Accuracy = 0.95,
|
||||||
|
MaxCombo = 999,
|
||||||
|
Rank = ScoreRank.S,
|
||||||
|
Date = DateTimeOffset.Now,
|
||||||
|
Statistics =
|
||||||
|
{
|
||||||
|
{ HitResult.Miss, 1 },
|
||||||
|
{ HitResult.Meh, 50 },
|
||||||
|
{ HitResult.Good, 100 },
|
||||||
|
{ HitResult.Great, 300 },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Scoring;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Graphics
|
namespace osu.Game.Graphics
|
||||||
@ -37,6 +38,35 @@ namespace osu.Game.Graphics
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the colour for a <see cref="ScoreRank"/>.
|
||||||
|
/// </summary>
|
||||||
|
public static Color4 ForRank(ScoreRank rank)
|
||||||
|
{
|
||||||
|
switch (rank)
|
||||||
|
{
|
||||||
|
case ScoreRank.XH:
|
||||||
|
case ScoreRank.X:
|
||||||
|
return Color4Extensions.FromHex(@"ce1c9d");
|
||||||
|
|
||||||
|
case ScoreRank.SH:
|
||||||
|
case ScoreRank.S:
|
||||||
|
return Color4Extensions.FromHex(@"00a8b5");
|
||||||
|
|
||||||
|
case ScoreRank.A:
|
||||||
|
return Color4Extensions.FromHex(@"7cce14");
|
||||||
|
|
||||||
|
case ScoreRank.B:
|
||||||
|
return Color4Extensions.FromHex(@"e3b130");
|
||||||
|
|
||||||
|
case ScoreRank.C:
|
||||||
|
return Color4Extensions.FromHex(@"f18252");
|
||||||
|
|
||||||
|
default:
|
||||||
|
return Color4Extensions.FromHex(@"e95353");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// See https://github.com/ppy/osu-web/blob/master/resources/assets/less/colors.less
|
// See https://github.com/ppy/osu-web/blob/master/resources/assets/less/colors.less
|
||||||
public readonly Color4 PurpleLighter = Color4Extensions.FromHex(@"eeeeff");
|
public readonly Color4 PurpleLighter = Color4Extensions.FromHex(@"eeeeff");
|
||||||
public readonly Color4 PurpleLight = Color4Extensions.FromHex(@"aa88ff");
|
public readonly Color4 PurpleLight = Color4Extensions.FromHex(@"aa88ff");
|
||||||
|
@ -43,6 +43,18 @@ namespace osu.Game.Graphics.Sprites
|
|||||||
set => blurredText.Colour = value;
|
set => blurredText.Colour = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector2 Spacing
|
||||||
|
{
|
||||||
|
get => spriteText.Spacing;
|
||||||
|
set => spriteText.Spacing = blurredText.Spacing = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool UseFullGlyphHeight
|
||||||
|
{
|
||||||
|
get => spriteText.UseFullGlyphHeight;
|
||||||
|
set => spriteText.UseFullGlyphHeight = blurredText.UseFullGlyphHeight = value;
|
||||||
|
}
|
||||||
|
|
||||||
public GlowingSpriteText()
|
public GlowingSpriteText()
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Both;
|
AutoSizeAxes = Axes.Both;
|
||||||
|
@ -28,7 +28,7 @@ namespace osu.Game.Online.Leaderboards
|
|||||||
FillMode = FillMode.Fit;
|
FillMode = FillMode.Fit;
|
||||||
FillAspectRatio = 2;
|
FillAspectRatio = 2;
|
||||||
|
|
||||||
var rankColour = getRankColour();
|
var rankColour = OsuColour.ForRank(rank);
|
||||||
InternalChild = new DrawSizePreservingFillContainer
|
InternalChild = new DrawSizePreservingFillContainer
|
||||||
{
|
{
|
||||||
TargetDrawSize = new Vector2(64, 32),
|
TargetDrawSize = new Vector2(64, 32),
|
||||||
@ -59,7 +59,7 @@ namespace osu.Game.Online.Leaderboards
|
|||||||
Padding = new MarginPadding { Top = 5 },
|
Padding = new MarginPadding { Top = 5 },
|
||||||
Colour = getRankNameColour(),
|
Colour = getRankNameColour(),
|
||||||
Font = OsuFont.Numeric.With(size: 25),
|
Font = OsuFont.Numeric.With(size: 25),
|
||||||
Text = getRankName(),
|
Text = GetRankName(rank),
|
||||||
ShadowColour = Color4.Black.Opacity(0.3f),
|
ShadowColour = Color4.Black.Opacity(0.3f),
|
||||||
ShadowOffset = new Vector2(0, 0.08f),
|
ShadowOffset = new Vector2(0, 0.08f),
|
||||||
Shadow = true,
|
Shadow = true,
|
||||||
@ -69,36 +69,7 @@ namespace osu.Game.Online.Leaderboards
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private string getRankName() => rank.GetDescription().TrimEnd('+');
|
public static string GetRankName(ScoreRank rank) => rank.GetDescription().TrimEnd('+');
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Retrieves the grade background colour.
|
|
||||||
/// </summary>
|
|
||||||
private Color4 getRankColour()
|
|
||||||
{
|
|
||||||
switch (rank)
|
|
||||||
{
|
|
||||||
case ScoreRank.XH:
|
|
||||||
case ScoreRank.X:
|
|
||||||
return Color4Extensions.FromHex(@"ce1c9d");
|
|
||||||
|
|
||||||
case ScoreRank.SH:
|
|
||||||
case ScoreRank.S:
|
|
||||||
return Color4Extensions.FromHex(@"00a8b5");
|
|
||||||
|
|
||||||
case ScoreRank.A:
|
|
||||||
return Color4Extensions.FromHex(@"7cce14");
|
|
||||||
|
|
||||||
case ScoreRank.B:
|
|
||||||
return Color4Extensions.FromHex(@"e3b130");
|
|
||||||
|
|
||||||
case ScoreRank.C:
|
|
||||||
return Color4Extensions.FromHex(@"f18252");
|
|
||||||
|
|
||||||
default:
|
|
||||||
return Color4Extensions.FromHex(@"e95353");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves the grade text colour.
|
/// Retrieves the grade text colour.
|
||||||
|
253
osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
Normal file
253
osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
// 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.Allocation;
|
||||||
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Colour;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Utils;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Scoring;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Ranking.Expanded.Accuracy
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The component that displays the player's accuracy on the results screen.
|
||||||
|
/// </summary>
|
||||||
|
public class AccuracyCircle : CompositeDrawable
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Duration for the transforms causing this component to appear.
|
||||||
|
/// </summary>
|
||||||
|
public const double APPEAR_DURATION = 200;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Delay before the accuracy circle starts filling.
|
||||||
|
/// </summary>
|
||||||
|
public const double ACCURACY_TRANSFORM_DELAY = 450;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Duration for the accuracy circle fill.
|
||||||
|
/// </summary>
|
||||||
|
public const double ACCURACY_TRANSFORM_DURATION = 3000;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Delay after <see cref="ACCURACY_TRANSFORM_DURATION"/> for the rank text (A/B/C/D/S/SS) to appear.
|
||||||
|
/// </summary>
|
||||||
|
public const double TEXT_APPEAR_DELAY = ACCURACY_TRANSFORM_DURATION / 2;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Delay before the rank circles start filling.
|
||||||
|
/// </summary>
|
||||||
|
public const double RANK_CIRCLE_TRANSFORM_DELAY = 150;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Duration for the rank circle fills.
|
||||||
|
/// </summary>
|
||||||
|
public const double RANK_CIRCLE_TRANSFORM_DURATION = 800;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Relative width of the rank circles.
|
||||||
|
/// </summary>
|
||||||
|
public const float RANK_CIRCLE_RADIUS = 0.06f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Relative width of the circle showing the accuracy.
|
||||||
|
/// </summary>
|
||||||
|
private const float accuracy_circle_radius = 0.2f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// SS is displayed as a 1% region, otherwise it would be invisible.
|
||||||
|
/// </summary>
|
||||||
|
private const double virtual_ss_percentage = 0.01;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The easing for the circle filling transforms.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly Easing ACCURACY_TRANSFORM_EASING = Easing.OutPow10;
|
||||||
|
|
||||||
|
private readonly ScoreInfo score;
|
||||||
|
|
||||||
|
private SmoothCircularProgress accuracyCircle;
|
||||||
|
private SmoothCircularProgress innerMask;
|
||||||
|
private Container<RankBadge> badges;
|
||||||
|
private RankText rankText;
|
||||||
|
|
||||||
|
public AccuracyCircle(ScoreInfo score)
|
||||||
|
{
|
||||||
|
this.score = score;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
new SmoothCircularProgress
|
||||||
|
{
|
||||||
|
Name = "Background circle",
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = OsuColour.Gray(47),
|
||||||
|
Alpha = 0.5f,
|
||||||
|
InnerRadius = accuracy_circle_radius + 0.01f, // Extends a little bit into the circle
|
||||||
|
Current = { Value = 1 },
|
||||||
|
},
|
||||||
|
accuracyCircle = new SmoothCircularProgress
|
||||||
|
{
|
||||||
|
Name = "Accuracy circle",
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = ColourInfo.GradientVertical(Color4Extensions.FromHex("#7CF6FF"), Color4Extensions.FromHex("#BAFFA9")),
|
||||||
|
InnerRadius = accuracy_circle_radius,
|
||||||
|
},
|
||||||
|
new BufferedContainer
|
||||||
|
{
|
||||||
|
Name = "Graded circles",
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Size = new Vector2(0.8f),
|
||||||
|
Padding = new MarginPadding(2),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new SmoothCircularProgress
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4Extensions.FromHex("#BE0089"),
|
||||||
|
InnerRadius = RANK_CIRCLE_RADIUS,
|
||||||
|
Current = { Value = 1 }
|
||||||
|
},
|
||||||
|
new SmoothCircularProgress
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4Extensions.FromHex("#0096A2"),
|
||||||
|
InnerRadius = RANK_CIRCLE_RADIUS,
|
||||||
|
Current = { Value = 1 - virtual_ss_percentage }
|
||||||
|
},
|
||||||
|
new SmoothCircularProgress
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4Extensions.FromHex("#72C904"),
|
||||||
|
InnerRadius = RANK_CIRCLE_RADIUS,
|
||||||
|
Current = { Value = 0.95f }
|
||||||
|
},
|
||||||
|
new SmoothCircularProgress
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4Extensions.FromHex("#D99D03"),
|
||||||
|
InnerRadius = RANK_CIRCLE_RADIUS,
|
||||||
|
Current = { Value = 0.9f }
|
||||||
|
},
|
||||||
|
new SmoothCircularProgress
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4Extensions.FromHex("#EA7948"),
|
||||||
|
InnerRadius = RANK_CIRCLE_RADIUS,
|
||||||
|
Current = { Value = 0.8f }
|
||||||
|
},
|
||||||
|
new SmoothCircularProgress
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4Extensions.FromHex("#FF5858"),
|
||||||
|
InnerRadius = RANK_CIRCLE_RADIUS,
|
||||||
|
Current = { Value = 0.7f }
|
||||||
|
},
|
||||||
|
new RankNotch(0),
|
||||||
|
new RankNotch((float)(1 - virtual_ss_percentage)),
|
||||||
|
new RankNotch(0.95f),
|
||||||
|
new RankNotch(0.9f),
|
||||||
|
new RankNotch(0.8f),
|
||||||
|
new RankNotch(0.7f),
|
||||||
|
new BufferedContainer
|
||||||
|
{
|
||||||
|
Name = "Graded circle mask",
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Padding = new MarginPadding(1),
|
||||||
|
Blending = new BlendingParameters
|
||||||
|
{
|
||||||
|
Source = BlendingType.DstColor,
|
||||||
|
Destination = BlendingType.OneMinusSrcAlpha,
|
||||||
|
SourceAlpha = BlendingType.One,
|
||||||
|
DestinationAlpha = BlendingType.SrcAlpha
|
||||||
|
},
|
||||||
|
Child = innerMask = new SmoothCircularProgress
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
InnerRadius = RANK_CIRCLE_RADIUS - 0.01f,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
badges = new Container<RankBadge>
|
||||||
|
{
|
||||||
|
Name = "Rank badges",
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Padding = new MarginPadding { Vertical = -15, Horizontal = -20 },
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new RankBadge(1f, ScoreRank.X),
|
||||||
|
new RankBadge(0.95f, ScoreRank.S),
|
||||||
|
new RankBadge(0.9f, ScoreRank.A),
|
||||||
|
new RankBadge(0.8f, ScoreRank.B),
|
||||||
|
new RankBadge(0.7f, ScoreRank.C),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rankText = new RankText(score.Rank)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
this.ScaleTo(0).Then().ScaleTo(1, APPEAR_DURATION, Easing.OutQuint);
|
||||||
|
|
||||||
|
using (BeginDelayedSequence(RANK_CIRCLE_TRANSFORM_DELAY, true))
|
||||||
|
innerMask.FillTo(1f, RANK_CIRCLE_TRANSFORM_DURATION, ACCURACY_TRANSFORM_EASING);
|
||||||
|
|
||||||
|
using (BeginDelayedSequence(ACCURACY_TRANSFORM_DELAY, true))
|
||||||
|
{
|
||||||
|
double targetAccuracy = score.Rank == ScoreRank.X || score.Rank == ScoreRank.XH ? 1 : Math.Min(1 - virtual_ss_percentage, score.Accuracy);
|
||||||
|
|
||||||
|
accuracyCircle.FillTo(targetAccuracy, ACCURACY_TRANSFORM_DURATION, ACCURACY_TRANSFORM_EASING);
|
||||||
|
|
||||||
|
foreach (var badge in badges)
|
||||||
|
{
|
||||||
|
if (badge.Accuracy > score.Accuracy)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
using (BeginDelayedSequence(inverseEasing(ACCURACY_TRANSFORM_EASING, badge.Accuracy / targetAccuracy) * ACCURACY_TRANSFORM_DURATION, true))
|
||||||
|
badge.Appear();
|
||||||
|
}
|
||||||
|
|
||||||
|
using (BeginDelayedSequence(TEXT_APPEAR_DELAY, true))
|
||||||
|
rankText.Appear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private double inverseEasing(Easing easing, double targetValue)
|
||||||
|
{
|
||||||
|
double test = 0;
|
||||||
|
double result = 0;
|
||||||
|
int count = 2;
|
||||||
|
|
||||||
|
while (Math.Abs(result - targetValue) > 0.005)
|
||||||
|
{
|
||||||
|
int dir = Math.Sign(targetValue - result);
|
||||||
|
|
||||||
|
test += dir * 1.0 / count;
|
||||||
|
result = Interpolation.ApplyEasing(easing, test);
|
||||||
|
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
99
osu.Game/Screens/Ranking/Expanded/Accuracy/RankBadge.cs
Normal file
99
osu.Game/Screens/Ranking/Expanded/Accuracy/RankBadge.cs
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
// 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.Allocation;
|
||||||
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Effects;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Online.Leaderboards;
|
||||||
|
using osu.Game.Scoring;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Ranking.Expanded.Accuracy
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Contains a <see cref="DrawableRank"/> that is positioned around the <see cref="AccuracyCircle"/>.
|
||||||
|
/// </summary>
|
||||||
|
public class RankBadge : CompositeDrawable
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The accuracy value corresponding to the <see cref="ScoreRank"/> displayed by this badge.
|
||||||
|
/// </summary>
|
||||||
|
public readonly float Accuracy;
|
||||||
|
|
||||||
|
private readonly ScoreRank rank;
|
||||||
|
|
||||||
|
private Drawable rankContainer;
|
||||||
|
private Drawable overlay;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new <see cref="RankBadge"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="accuracy">The accuracy value corresponding to <paramref name="rank"/>.</param>
|
||||||
|
/// <param name="rank">The <see cref="ScoreRank"/> to be displayed in this <see cref="RankBadge"/>.</param>
|
||||||
|
public RankBadge(float accuracy, ScoreRank rank)
|
||||||
|
{
|
||||||
|
Accuracy = accuracy;
|
||||||
|
this.rank = rank;
|
||||||
|
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
Alpha = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
InternalChild = rankContainer = new Container
|
||||||
|
{
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Size = new Vector2(28, 14),
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new DrawableRank(rank),
|
||||||
|
overlay = new CircularContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Blending = BlendingParameters.Additive,
|
||||||
|
Masking = true,
|
||||||
|
EdgeEffect = new EdgeEffectParameters
|
||||||
|
{
|
||||||
|
Type = EdgeEffectType.Glow,
|
||||||
|
Colour = OsuColour.ForRank(rank).Opacity(0.2f),
|
||||||
|
Radius = 10,
|
||||||
|
},
|
||||||
|
Child = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Alpha = 0,
|
||||||
|
AlwaysPresent = true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Shows this <see cref="RankBadge"/>.
|
||||||
|
/// </summary>
|
||||||
|
public void Appear()
|
||||||
|
{
|
||||||
|
this.FadeIn(50);
|
||||||
|
overlay.FadeIn().FadeOut(500, Easing.In);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
// Starts at -90deg (top) and moves counter-clockwise by the accuracy
|
||||||
|
rankContainer.Position = circlePosition(-MathF.PI / 2 - (1 - Accuracy) * MathF.PI * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vector2 circlePosition(float t)
|
||||||
|
=> DrawSize / 2 + new Vector2(MathF.Cos(t), MathF.Sin(t)) * DrawSize / 2;
|
||||||
|
}
|
||||||
|
}
|
49
osu.Game/Screens/Ranking/Expanded/Accuracy/RankNotch.cs
Normal file
49
osu.Game/Screens/Ranking/Expanded/Accuracy/RankNotch.cs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// 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.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Ranking.Expanded.Accuracy
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A solid "notch" of the <see cref="AccuracyCircle"/> that appears at the ends of the rank circles to add separation.
|
||||||
|
/// </summary>
|
||||||
|
public class RankNotch : CompositeDrawable
|
||||||
|
{
|
||||||
|
private readonly float position;
|
||||||
|
|
||||||
|
public RankNotch(float position)
|
||||||
|
{
|
||||||
|
this.position = position;
|
||||||
|
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
InternalChild = new Container
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Rotation = position * 360f,
|
||||||
|
Child = new Box
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
Height = AccuracyCircle.RANK_CIRCLE_RADIUS,
|
||||||
|
Width = 1f,
|
||||||
|
Colour = OsuColour.Gray(0.3f),
|
||||||
|
EdgeSmoothness = new Vector2(1f)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
83
osu.Game/Screens/Ranking/Expanded/Accuracy/RankText.cs
Normal file
83
osu.Game/Screens/Ranking/Expanded/Accuracy/RankText.cs
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
// 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.Online.Leaderboards;
|
||||||
|
using osu.Game.Scoring;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Ranking.Expanded.Accuracy
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The text that appears in the middle of the <see cref="AccuracyCircle"/> displaying the user's rank.
|
||||||
|
/// </summary>
|
||||||
|
public class RankText : CompositeDrawable
|
||||||
|
{
|
||||||
|
private readonly ScoreRank rank;
|
||||||
|
|
||||||
|
private Drawable flash;
|
||||||
|
|
||||||
|
public RankText(ScoreRank rank)
|
||||||
|
{
|
||||||
|
this.rank = rank;
|
||||||
|
|
||||||
|
Anchor = Anchor.Centre;
|
||||||
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
|
Alpha = 0;
|
||||||
|
AutoSizeAxes = Axes.Both;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
InternalChildren = new[]
|
||||||
|
{
|
||||||
|
new GlowingSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Spacing = new Vector2(-15, 0),
|
||||||
|
Text = DrawableRank.GetRankName(rank),
|
||||||
|
Font = OsuFont.Numeric.With(size: 76),
|
||||||
|
UseFullGlyphHeight = false
|
||||||
|
},
|
||||||
|
flash = new BufferedContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
BlurSigma = new Vector2(35),
|
||||||
|
BypassAutoSizeAxes = Axes.Both,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Blending = BlendingParameters.Additive,
|
||||||
|
Size = new Vector2(2f),
|
||||||
|
Scale = new Vector2(1.8f),
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Spacing = new Vector2(-15, 0),
|
||||||
|
Text = DrawableRank.GetRankName(rank),
|
||||||
|
Font = OsuFont.Numeric.With(size: 76),
|
||||||
|
UseFullGlyphHeight = false,
|
||||||
|
Shadow = false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Appear()
|
||||||
|
{
|
||||||
|
this.FadeIn(0, Easing.In);
|
||||||
|
|
||||||
|
flash.FadeIn(0, Easing.In).Then().FadeOut(800, Easing.OutQuint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,126 @@
|
|||||||
|
// 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.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Graphics.Transforms;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Ranking.Expanded.Accuracy
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Contains a <see cref="CircularProgress"/> with smoothened edges.
|
||||||
|
/// </summary>
|
||||||
|
public class SmoothCircularProgress : CompositeDrawable
|
||||||
|
{
|
||||||
|
public Bindable<double> Current
|
||||||
|
{
|
||||||
|
get => progress.Current;
|
||||||
|
set => progress.Current = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float InnerRadius
|
||||||
|
{
|
||||||
|
get => progress.InnerRadius;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
progress.InnerRadius = value;
|
||||||
|
innerSmoothingContainer.Size = new Vector2(1 - value);
|
||||||
|
smoothingWedge.Height = value / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly CircularProgress progress;
|
||||||
|
private readonly Container innerSmoothingContainer;
|
||||||
|
private readonly Drawable smoothingWedge;
|
||||||
|
|
||||||
|
public SmoothCircularProgress()
|
||||||
|
{
|
||||||
|
Container smoothingWedgeContainer;
|
||||||
|
|
||||||
|
InternalChild = new BufferedContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
progress = new CircularProgress { RelativeSizeAxes = Axes.Both },
|
||||||
|
smoothingWedgeContainer = new Container
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Child = smoothingWedge = new Box
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
Width = 1f,
|
||||||
|
EdgeSmoothness = new Vector2(2, 0),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Padding = new MarginPadding(-1),
|
||||||
|
Child = new CircularContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
BorderThickness = 2,
|
||||||
|
Masking = true,
|
||||||
|
BorderColour = OsuColour.Gray(0.5f).Opacity(0.75f),
|
||||||
|
Blending = new BlendingParameters
|
||||||
|
{
|
||||||
|
AlphaEquation = BlendingEquation.ReverseSubtract,
|
||||||
|
},
|
||||||
|
Child = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Alpha = 0,
|
||||||
|
AlwaysPresent = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
innerSmoothingContainer = new Container
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Size = Vector2.Zero,
|
||||||
|
Padding = new MarginPadding(-1),
|
||||||
|
Child = new CircularContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
BorderThickness = 2,
|
||||||
|
BorderColour = OsuColour.Gray(0.5f).Opacity(0.75f),
|
||||||
|
Masking = true,
|
||||||
|
Blending = new BlendingParameters
|
||||||
|
{
|
||||||
|
AlphaEquation = BlendingEquation.ReverseSubtract,
|
||||||
|
},
|
||||||
|
Child = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Alpha = 0,
|
||||||
|
AlwaysPresent = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Current.BindValueChanged(c =>
|
||||||
|
{
|
||||||
|
smoothingWedgeContainer.Alpha = c.NewValue > 0 ? 1 : 0;
|
||||||
|
smoothingWedgeContainer.Rotation = (float)(360 * c.NewValue);
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransformSequence<CircularProgress> FillTo(double newValue, double duration = 0, Easing easing = Easing.None)
|
||||||
|
=> progress.FillTo(newValue, duration, easing);
|
||||||
|
}
|
||||||
|
}
|
@ -1,15 +1,226 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Extensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
|
using osu.Game.Screens.Play.HUD;
|
||||||
|
using osu.Game.Screens.Ranking.Expanded.Accuracy;
|
||||||
|
using osu.Game.Screens.Ranking.Expanded.Statistics;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Ranking.Expanded
|
namespace osu.Game.Screens.Ranking.Expanded
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The content that appears in the middle section of the <see cref="ScorePanel"/>.
|
||||||
|
/// </summary>
|
||||||
public class ExpandedPanelMiddleContent : CompositeDrawable
|
public class ExpandedPanelMiddleContent : CompositeDrawable
|
||||||
{
|
{
|
||||||
|
private readonly ScoreInfo score;
|
||||||
|
|
||||||
|
private readonly List<StatisticDisplay> statisticDisplays = new List<StatisticDisplay>();
|
||||||
|
private RollingCounter<long> scoreCounter;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new <see cref="ExpandedPanelMiddleContent"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="score">The score to display.</param>
|
||||||
public ExpandedPanelMiddleContent(ScoreInfo score)
|
public ExpandedPanelMiddleContent(ScoreInfo score)
|
||||||
{
|
{
|
||||||
|
this.score = score;
|
||||||
|
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
Masking = true;
|
||||||
|
|
||||||
|
Padding = new MarginPadding { Vertical = 10, Horizontal = 10 };
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
var topStatistics = new List<StatisticDisplay>
|
||||||
|
{
|
||||||
|
new AccuracyStatistic(score.Accuracy),
|
||||||
|
new ComboStatistic(score.MaxCombo, true),
|
||||||
|
new CounterStatistic("pp", (int)(score.PP ?? 0)),
|
||||||
|
};
|
||||||
|
|
||||||
|
var bottomStatistics = new List<StatisticDisplay>();
|
||||||
|
foreach (var stat in score.SortedStatistics)
|
||||||
|
bottomStatistics.Add(new CounterStatistic(stat.Key.GetDescription(), stat.Value));
|
||||||
|
|
||||||
|
statisticDisplays.AddRange(topStatistics);
|
||||||
|
statisticDisplays.AddRange(bottomStatistics);
|
||||||
|
|
||||||
|
InternalChild = new FillFlowContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Spacing = new Vector2(20),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Text = new LocalisedString((score.Beatmap.Metadata.Title, score.Beatmap.Metadata.TitleUnicode)),
|
||||||
|
Font = OsuFont.Torus.With(size: 20, weight: FontWeight.SemiBold),
|
||||||
|
},
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Text = new LocalisedString((score.Beatmap.Metadata.Artist, score.Beatmap.Metadata.ArtistUnicode)),
|
||||||
|
Font = OsuFont.Torus.With(size: 14, weight: FontWeight.SemiBold)
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Margin = new MarginPadding { Top = 40 },
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Height = 230,
|
||||||
|
Child = new AccuracyCircle(score)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
FillMode = FillMode.Fit,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scoreCounter = new TotalScoreCounter
|
||||||
|
{
|
||||||
|
Margin = new MarginPadding { Top = 0, Bottom = 5 },
|
||||||
|
Current = { Value = 0 },
|
||||||
|
Alpha = 0,
|
||||||
|
AlwaysPresent = true
|
||||||
|
},
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new StarRatingDisplay(score.Beatmap)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft
|
||||||
|
},
|
||||||
|
new ModDisplay
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
DisplayUnrankedText = false,
|
||||||
|
ExpansionMode = ExpansionMode.AlwaysExpanded,
|
||||||
|
Scale = new Vector2(0.5f),
|
||||||
|
Current = { Value = score.Mods }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Text = score.Beatmap.Version,
|
||||||
|
Font = OsuFont.Torus.With(size: 16, weight: FontWeight.SemiBold),
|
||||||
|
},
|
||||||
|
new OsuTextFlowContainer(s => s.Font = OsuFont.Torus.With(size: 12))
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
}.With(t =>
|
||||||
|
{
|
||||||
|
t.AddText("mapped by ");
|
||||||
|
t.AddText(score.UserString, s => s.Font = s.Font.With(weight: FontWeight.SemiBold));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Spacing = new Vector2(0, 5),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new GridContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Content = new[] { topStatistics.Cast<Drawable>().ToArray() },
|
||||||
|
RowDimensions = new[]
|
||||||
|
{
|
||||||
|
new Dimension(GridSizeMode.AutoSize),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new GridContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Content = new[] { bottomStatistics.Cast<Drawable>().ToArray() },
|
||||||
|
RowDimensions = new[]
|
||||||
|
{
|
||||||
|
new Dimension(GridSizeMode.AutoSize),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
// Score counter value setting must be scheduled so it isn't transferred instantaneously
|
||||||
|
ScheduleAfterChildren(() =>
|
||||||
|
{
|
||||||
|
using (BeginDelayedSequence(AccuracyCircle.ACCURACY_TRANSFORM_DELAY, true))
|
||||||
|
{
|
||||||
|
scoreCounter.FadeIn();
|
||||||
|
scoreCounter.Current.Value = score.TotalScore;
|
||||||
|
|
||||||
|
double delay = 0;
|
||||||
|
|
||||||
|
foreach (var stat in statisticDisplays)
|
||||||
|
{
|
||||||
|
using (BeginDelayedSequence(delay, true))
|
||||||
|
stat.Appear();
|
||||||
|
|
||||||
|
delay += 200;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
102
osu.Game/Screens/Ranking/Expanded/StarRatingDisplay.cs
Normal file
102
osu.Game/Screens/Ranking/Expanded/StarRatingDisplay.cs
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
// 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.Globalization;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
using osuTK;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Ranking.Expanded
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A pill that displays the star rating of a <see cref="BeatmapInfo"/>.
|
||||||
|
/// </summary>
|
||||||
|
public class StarRatingDisplay : CompositeDrawable
|
||||||
|
{
|
||||||
|
private readonly BeatmapInfo beatmap;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new <see cref="StarRatingDisplay"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="beatmap">The <see cref="BeatmapInfo"/> to display the star difficulty of.</param>
|
||||||
|
public StarRatingDisplay(BeatmapInfo beatmap)
|
||||||
|
{
|
||||||
|
this.beatmap = beatmap;
|
||||||
|
AutoSizeAxes = Axes.Both;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
var starRatingParts = beatmap.StarDifficulty.ToString("0.00", CultureInfo.InvariantCulture).Split('.');
|
||||||
|
string wholePart = starRatingParts[0];
|
||||||
|
string fractionPart = starRatingParts[1];
|
||||||
|
string separator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
|
||||||
|
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
new CircularContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Masking = true,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = colours.ForDifficultyRating(beatmap.DifficultyRating)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Padding = new MarginPadding { Horizontal = 8, Vertical = 4 },
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
Spacing = new Vector2(2, 0),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new SpriteIcon
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
Size = new Vector2(7),
|
||||||
|
Icon = FontAwesome.Solid.Star,
|
||||||
|
Colour = Color4.Black
|
||||||
|
},
|
||||||
|
new OsuTextFlowContainer(s => s.Font = OsuFont.Numeric.With(weight: FontWeight.Black))
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
TextAnchor = Anchor.BottomLeft,
|
||||||
|
}.With(t =>
|
||||||
|
{
|
||||||
|
t.AddText($"{wholePart}", s =>
|
||||||
|
{
|
||||||
|
s.Colour = Color4.Black;
|
||||||
|
s.Font = s.Font.With(size: 14);
|
||||||
|
s.UseFullGlyphHeight = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
t.AddText($"{separator}{fractionPart}", s =>
|
||||||
|
{
|
||||||
|
s.Colour = Color4.Black;
|
||||||
|
s.Font = s.Font.With(size: 7);
|
||||||
|
s.UseFullGlyphHeight = false;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
// 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;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Screens.Ranking.Expanded.Accuracy;
|
||||||
|
using osu.Game.Utils;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Ranking.Expanded.Statistics
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A <see cref="StatisticDisplay"/> to display the player's accuracy.
|
||||||
|
/// </summary>
|
||||||
|
public class AccuracyStatistic : StatisticDisplay
|
||||||
|
{
|
||||||
|
private readonly double accuracy;
|
||||||
|
|
||||||
|
private RollingCounter<double> counter;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new <see cref="AccuracyStatistic"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="accuracy">The accuracy to display.</param>
|
||||||
|
public AccuracyStatistic(double accuracy)
|
||||||
|
: base("accuracy")
|
||||||
|
{
|
||||||
|
this.accuracy = accuracy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Appear()
|
||||||
|
{
|
||||||
|
base.Appear();
|
||||||
|
counter.Current.Value = accuracy;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Drawable CreateContent() => counter = new Counter();
|
||||||
|
|
||||||
|
private class Counter : RollingCounter<double>
|
||||||
|
{
|
||||||
|
protected override double RollingDuration => AccuracyCircle.ACCURACY_TRANSFORM_DURATION;
|
||||||
|
|
||||||
|
protected override Easing RollingEasing => AccuracyCircle.ACCURACY_TRANSFORM_EASING;
|
||||||
|
|
||||||
|
public Counter()
|
||||||
|
{
|
||||||
|
DisplayedCountSpriteText.Font = OsuFont.Torus.With(size: 20, fixedWidth: true);
|
||||||
|
DisplayedCountSpriteText.Spacing = new Vector2(-2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string FormatCount(double count) => count.FormatAccuracy();
|
||||||
|
|
||||||
|
public override void Increment(double amount)
|
||||||
|
=> Current.Value += amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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 osu.Framework.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Colour;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Screens.Ranking.Expanded.Accuracy;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Ranking.Expanded.Statistics
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A <see cref="StatisticDisplay"/> to display the player's combo.
|
||||||
|
/// </summary>
|
||||||
|
public class ComboStatistic : CounterStatistic
|
||||||
|
{
|
||||||
|
private readonly bool isPerfect;
|
||||||
|
|
||||||
|
private Drawable perfectText;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new <see cref="ComboStatistic"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="combo">The combo to be displayed.</param>
|
||||||
|
/// <param name="isPerfect">Whether this is a perfect combo.</param>
|
||||||
|
public ComboStatistic(int combo, bool isPerfect)
|
||||||
|
: base("combo", combo)
|
||||||
|
{
|
||||||
|
this.isPerfect = isPerfect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Appear()
|
||||||
|
{
|
||||||
|
base.Appear();
|
||||||
|
|
||||||
|
if (isPerfect)
|
||||||
|
{
|
||||||
|
using (BeginDelayedSequence(AccuracyCircle.ACCURACY_TRANSFORM_DURATION / 2, true))
|
||||||
|
perfectText.FadeIn(50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Drawable CreateContent() => new FillFlowContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
Spacing = new Vector2(10, 0),
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
base.CreateContent().With(d =>
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft;
|
||||||
|
Origin = Anchor.CentreLeft;
|
||||||
|
}),
|
||||||
|
perfectText = new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
Text = "PERFECT",
|
||||||
|
Font = OsuFont.Torus.With(size: 11, weight: FontWeight.SemiBold),
|
||||||
|
Colour = ColourInfo.GradientVertical(Color4Extensions.FromHex("#66FFCC"), Color4Extensions.FromHex("#FF9AD7")),
|
||||||
|
Alpha = 0,
|
||||||
|
UseFullGlyphHeight = false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
// 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;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Screens.Ranking.Expanded.Accuracy;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Ranking.Expanded.Statistics
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A <see cref="StatisticDisplay"/> to display general numeric values.
|
||||||
|
/// </summary>
|
||||||
|
public class CounterStatistic : StatisticDisplay
|
||||||
|
{
|
||||||
|
private readonly int count;
|
||||||
|
|
||||||
|
private RollingCounter<int> counter;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new <see cref="CounterStatistic"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="header">The name of the statistic.</param>
|
||||||
|
/// <param name="count">The value to display.</param>
|
||||||
|
public CounterStatistic(string header, int count)
|
||||||
|
: base(header)
|
||||||
|
{
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Appear()
|
||||||
|
{
|
||||||
|
base.Appear();
|
||||||
|
counter.Current.Value = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Drawable CreateContent() => counter = new Counter();
|
||||||
|
|
||||||
|
private class Counter : RollingCounter<int>
|
||||||
|
{
|
||||||
|
protected override double RollingDuration => AccuracyCircle.ACCURACY_TRANSFORM_DURATION;
|
||||||
|
|
||||||
|
protected override Easing RollingEasing => AccuracyCircle.ACCURACY_TRANSFORM_EASING;
|
||||||
|
|
||||||
|
public Counter()
|
||||||
|
{
|
||||||
|
DisplayedCountSpriteText.Font = OsuFont.Torus.With(size: 20, fixedWidth: true);
|
||||||
|
DisplayedCountSpriteText.Spacing = new Vector2(-2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Increment(int amount)
|
||||||
|
=> Current.Value += amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,95 @@
|
|||||||
|
// 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.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Ranking.Expanded.Statistics
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A statistic from the score to be displayed in the <see cref="ExpandedPanelMiddleContent"/>.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class StatisticDisplay : CompositeDrawable
|
||||||
|
{
|
||||||
|
private readonly string header;
|
||||||
|
|
||||||
|
private Drawable content;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new <see cref="StatisticDisplay"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="header">The name of the statistic.</param>
|
||||||
|
protected StatisticDisplay(string header)
|
||||||
|
{
|
||||||
|
this.header = header;
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
|
AutoSizeAxes = Axes.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
InternalChild = new FillFlowContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new CircularContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Height = 12,
|
||||||
|
Masking = true,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4Extensions.FromHex("#222")
|
||||||
|
},
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Font = OsuFont.Torus.With(size: 12, weight: FontWeight.SemiBold),
|
||||||
|
Text = header.ToUpperInvariant(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
content = CreateContent().With(d =>
|
||||||
|
{
|
||||||
|
d.Anchor = Anchor.TopCentre;
|
||||||
|
d.Origin = Anchor.TopCentre;
|
||||||
|
d.Alpha = 0;
|
||||||
|
d.AlwaysPresent = true;
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Shows the statistic value.
|
||||||
|
/// </summary>
|
||||||
|
public virtual void Appear() => content.FadeIn(100);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates the content for this <see cref="StatisticDisplay"/>.
|
||||||
|
/// </summary>
|
||||||
|
protected abstract Drawable CreateContent();
|
||||||
|
}
|
||||||
|
}
|
38
osu.Game/Screens/Ranking/Expanded/TotalScoreCounter.cs
Normal file
38
osu.Game/Screens/Ranking/Expanded/TotalScoreCounter.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// 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;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Screens.Ranking.Expanded.Accuracy;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Ranking.Expanded
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A counter for the player's total score to be displayed in the <see cref="ExpandedPanelMiddleContent"/>.
|
||||||
|
/// </summary>
|
||||||
|
public class TotalScoreCounter : RollingCounter<long>
|
||||||
|
{
|
||||||
|
protected override double RollingDuration => AccuracyCircle.ACCURACY_TRANSFORM_DURATION;
|
||||||
|
|
||||||
|
protected override Easing RollingEasing => AccuracyCircle.ACCURACY_TRANSFORM_EASING;
|
||||||
|
|
||||||
|
public TotalScoreCounter()
|
||||||
|
{
|
||||||
|
// Todo: AutoSize X removed here due to https://github.com/ppy/osu-framework/issues/3369
|
||||||
|
AutoSizeAxes = Axes.Y;
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
|
DisplayedCountSpriteText.Anchor = Anchor.TopCentre;
|
||||||
|
DisplayedCountSpriteText.Origin = Anchor.TopCentre;
|
||||||
|
|
||||||
|
DisplayedCountSpriteText.Font = OsuFont.Torus.With(size: 60, weight: FontWeight.Light, fixedWidth: true);
|
||||||
|
DisplayedCountSpriteText.Spacing = new Vector2(-5, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string FormatCount(long count) => count.ToString("N0");
|
||||||
|
|
||||||
|
public override void Increment(long amount)
|
||||||
|
=> Current.Value += amount;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user