mirror of
https://github.com/ppy/osu.git
synced 2025-01-14 18:32:56 +08:00
Merge pull request #14119 from frenzibyte/new-difficulty-colours
Update star rating difficulty colours and add spectrum support
This commit is contained in:
commit
cd0e9cc08b
@ -0,0 +1,90 @@
|
||||
// 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 NUnit.Framework;
|
||||
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;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Colours
|
||||
{
|
||||
public class TestSceneStarDifficultyColours : OsuTestScene
|
||||
{
|
||||
[Resolved]
|
||||
private OsuColour colours { get; set; }
|
||||
|
||||
[Test]
|
||||
public void TestColours()
|
||||
{
|
||||
AddStep("load colour displays", () =>
|
||||
{
|
||||
Child = new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(5f),
|
||||
ChildrenEnumerable = Enumerable.Range(0, 10).Select(i => new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(10f),
|
||||
ChildrenEnumerable = Enumerable.Range(0, 10).Select(j =>
|
||||
{
|
||||
var colour = colours.ForStarDifficulty(1f * i + 0.1f * j);
|
||||
|
||||
return new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0f, 10f),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new CircularContainer
|
||||
{
|
||||
Masking = true,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Size = new Vector2(75f, 25f),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = colour,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Colour = OsuColour.ForegroundTextColourFor(colour),
|
||||
Text = colour.ToHex(),
|
||||
},
|
||||
}
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Text = $"*{(1f * i + 0.1f * j):0.00}",
|
||||
}
|
||||
}
|
||||
};
|
||||
})
|
||||
})
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -93,20 +93,20 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
new CircularContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Scale = new Vector2(0.84f),
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Masking = true,
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Colour = Color4.Black.Opacity(0.08f),
|
||||
Colour = Color4.Black.Opacity(0.06f),
|
||||
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Radius = 5,
|
||||
Radius = 3,
|
||||
},
|
||||
Child = background = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = colours.ForDifficultyRating(beatmap.DifficultyRating) // Default value that will be re-populated once difficulty calculation completes
|
||||
Colour = colours.ForStarDifficulty(beatmap.StarDifficulty) // Default value that will be re-populated once difficulty calculation completes
|
||||
},
|
||||
},
|
||||
new ConstrainedIconContainer
|
||||
@ -124,7 +124,7 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
else
|
||||
difficultyBindable.Value = new StarDifficulty(beatmap.StarDifficulty, 0);
|
||||
|
||||
difficultyBindable.BindValueChanged(difficulty => background.Colour = colours.ForDifficultyRating(difficulty.NewValue.DifficultyRating));
|
||||
difficultyBindable.BindValueChanged(difficulty => background.Colour = colours.ForStarDifficulty(difficulty.NewValue.Stars));
|
||||
}
|
||||
|
||||
public ITooltip GetCustomTooltip() => new DifficultyIconTooltip();
|
||||
@ -271,7 +271,7 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
starDifficulty.BindValueChanged(difficulty =>
|
||||
{
|
||||
starRating.Text = $"{difficulty.NewValue.Stars:0.##}";
|
||||
difficultyFlow.Colour = colours.ForDifficultyRating(difficulty.NewValue.DifficultyRating, true);
|
||||
difficultyFlow.Colour = colours.ForStarDifficulty(difficulty.NewValue.Stars);
|
||||
}, true);
|
||||
|
||||
return true;
|
||||
|
@ -1,11 +1,13 @@
|
||||
// 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.Extensions.Color4Extensions;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Utils;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Graphics
|
||||
@ -15,31 +17,52 @@ namespace osu.Game.Graphics
|
||||
public static Color4 Gray(float amt) => new Color4(amt, amt, amt, 1f);
|
||||
public static Color4 Gray(byte amt) => new Color4(amt, amt, amt, 255);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the colour for a <see cref="DifficultyRating"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Sourced from the @diff-{rating} variables in https://github.com/ppy/osu-web/blob/71fbab8936d79a7929d13854f5e854b4f383b236/resources/assets/less/variables.less.
|
||||
/// </remarks>
|
||||
public Color4 ForDifficultyRating(DifficultyRating difficulty, bool useLighterColour = false)
|
||||
{
|
||||
switch (difficulty)
|
||||
{
|
||||
case DifficultyRating.Easy:
|
||||
return Green;
|
||||
return Color4Extensions.FromHex("4ebfff");
|
||||
|
||||
default:
|
||||
case DifficultyRating.Normal:
|
||||
return Blue;
|
||||
return Color4Extensions.FromHex("66ff91");
|
||||
|
||||
case DifficultyRating.Hard:
|
||||
return Yellow;
|
||||
return Color4Extensions.FromHex("f7e85d");
|
||||
|
||||
case DifficultyRating.Insane:
|
||||
return Pink;
|
||||
return Color4Extensions.FromHex("ff7e68");
|
||||
|
||||
case DifficultyRating.Expert:
|
||||
return PurpleLight;
|
||||
return Color4Extensions.FromHex("fe3c71");
|
||||
|
||||
case DifficultyRating.ExpertPlus:
|
||||
return useLighterColour ? Gray9 : Color4Extensions.FromHex("#121415");
|
||||
return Color4Extensions.FromHex("6662dd");
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(difficulty));
|
||||
}
|
||||
}
|
||||
|
||||
public Color4 ForStarDifficulty(double starDifficulty) => ColourUtils.SampleFromLinearGradient(new[]
|
||||
{
|
||||
(1.5f, Color4Extensions.FromHex("4fc0ff")),
|
||||
(2.0f, Color4Extensions.FromHex("4fffd5")),
|
||||
(2.5f, Color4Extensions.FromHex("7cff4f")),
|
||||
(3.25f, Color4Extensions.FromHex("f6f05c")),
|
||||
(4.5f, Color4Extensions.FromHex("ff8068")),
|
||||
(6.0f, Color4Extensions.FromHex("ff3c71")),
|
||||
(7.0f, Color4Extensions.FromHex("6563de")),
|
||||
(8.0f, Color4Extensions.FromHex("18158e")),
|
||||
(8.0f, Color4.Black),
|
||||
}, (float)Math.Round(starDifficulty, 2, MidpointRounding.AwayFromZero));
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the colour for a <see cref="ScoreRank"/>.
|
||||
/// </summary>
|
||||
|
@ -86,8 +86,8 @@ namespace osu.Game.Screens.OnlinePlay.Components
|
||||
minDisplay.Current.Value = minDifficulty;
|
||||
maxDisplay.Current.Value = maxDifficulty;
|
||||
|
||||
minBackground.Colour = colours.ForDifficultyRating(minDifficulty.DifficultyRating, true);
|
||||
maxBackground.Colour = colours.ForDifficultyRating(maxDifficulty.DifficultyRating, true);
|
||||
minBackground.Colour = colours.ForStarDifficulty(minDifficulty.Stars);
|
||||
maxBackground.Colour = colours.ForStarDifficulty(maxDifficulty.Stars);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ namespace osu.Game.Screens.Ranking.Expanded
|
||||
public class StarRatingDisplay : CompositeDrawable, IHasCurrentValue<StarDifficulty>
|
||||
{
|
||||
private Box background;
|
||||
private FillFlowContainer content;
|
||||
private OsuTextFlowContainer textFlow;
|
||||
|
||||
[Resolved]
|
||||
@ -64,7 +65,7 @@ namespace osu.Game.Screens.Ranking.Expanded
|
||||
},
|
||||
}
|
||||
},
|
||||
new FillFlowContainer
|
||||
content = new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Horizontal = 8, Vertical = 4 },
|
||||
@ -78,7 +79,6 @@ namespace osu.Game.Screens.Ranking.Expanded
|
||||
Origin = Anchor.CentreLeft,
|
||||
Size = new Vector2(7),
|
||||
Icon = FontAwesome.Solid.Star,
|
||||
Colour = Color4.Black
|
||||
},
|
||||
textFlow = new OsuTextFlowContainer(s => s.Font = OsuFont.Numeric.With(weight: FontWeight.Black))
|
||||
{
|
||||
@ -107,21 +107,20 @@ namespace osu.Game.Screens.Ranking.Expanded
|
||||
string fractionPart = starRatingParts[1];
|
||||
string separator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
|
||||
|
||||
var rating = Current.Value.DifficultyRating;
|
||||
var stars = Current.Value.Stars;
|
||||
|
||||
background.Colour = colours.ForDifficultyRating(rating, true);
|
||||
background.Colour = colours.ForStarDifficulty(stars);
|
||||
content.Colour = stars >= 6.5 ? colours.Orange1 : Color4.Black;
|
||||
|
||||
textFlow.Clear();
|
||||
textFlow.AddText($"{wholePart}", s =>
|
||||
{
|
||||
s.Colour = Color4.Black;
|
||||
s.Font = s.Font.With(size: 14);
|
||||
s.UseFullGlyphHeight = false;
|
||||
});
|
||||
|
||||
textFlow.AddText($"{separator}{fractionPart}", s =>
|
||||
{
|
||||
s.Colour = Color4.Black;
|
||||
s.Font = s.Font.With(size: 7);
|
||||
s.UseFullGlyphHeight = false;
|
||||
});
|
||||
|
@ -503,7 +503,7 @@ namespace osu.Game.Screens.Select
|
||||
{
|
||||
const float full_opacity_ratio = 0.7f;
|
||||
|
||||
var difficultyColour = colours.ForDifficultyRating(difficulty.DifficultyRating);
|
||||
var difficultyColour = colours.ForStarDifficulty(difficulty.Stars);
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
|
37
osu.Game/Utils/ColourUtils.cs
Normal file
37
osu.Game/Utils/ColourUtils.cs
Normal file
@ -0,0 +1,37 @@
|
||||
// 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.Collections.Generic;
|
||||
using osu.Framework.Utils;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Utils
|
||||
{
|
||||
public static class ColourUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Samples from a given linear gradient at a certain specified point.
|
||||
/// </summary>
|
||||
/// <param name="gradient">The gradient, defining the colour stops and their positions (in [0-1] range) in the gradient.</param>
|
||||
/// <param name="point">The point to sample the colour at.</param>
|
||||
/// <returns>A <see cref="Color4"/> sampled from the linear gradient.</returns>
|
||||
public static Color4 SampleFromLinearGradient(IReadOnlyList<(float position, Color4 colour)> gradient, float point)
|
||||
{
|
||||
if (point < gradient[0].position)
|
||||
return gradient[0].colour;
|
||||
|
||||
for (int i = 0; i < gradient.Count - 1; i++)
|
||||
{
|
||||
var startStop = gradient[i];
|
||||
var endStop = gradient[i + 1];
|
||||
|
||||
if (point >= endStop.position)
|
||||
continue;
|
||||
|
||||
return Interpolation.ValueAt(point, startStop.colour, endStop.colour, startStop.position, endStop.position);
|
||||
}
|
||||
|
||||
return gradient[^1].colour;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user