1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-22 00:43:25 +08:00

Visual and readability improvements to StarCounter.

This commit is contained in:
Dean Herbert 2017-02-24 19:30:04 +09:00
parent 65a24dfe5d
commit 12db33ad4b
No known key found for this signature in database
GPG Key ID: 46D71BF4958ABB49
4 changed files with 95 additions and 99 deletions

View File

@ -158,7 +158,7 @@ namespace osu.Desktop.VisualTests.Tests
AddButton(@"Alter stars", delegate AddButton(@"Alter stars", delegate
{ {
stars.Count = RNG.NextSingle() * (stars.MaxStars + 1); stars.Count = RNG.NextSingle() * (stars.StarCount + 1);
starsLabel.Text = stars.Count.ToString("0.00"); starsLabel.Text = stars.Count.ToString("0.00");
}); });

View File

@ -26,6 +26,7 @@ namespace osu.Game.Beatmaps.Drawables
public Action<BeatmapPanel> GainedSelection; public Action<BeatmapPanel> GainedSelection;
public Action<BeatmapPanel> StartRequested; public Action<BeatmapPanel> StartRequested;
private Triangles triangles; private Triangles triangles;
private StarCounter starCounter;
protected override void Selected() protected override void Selected()
{ {
@ -56,6 +57,14 @@ namespace osu.Game.Beatmaps.Drawables
return base.OnClick(state); return base.OnClick(state);
} }
protected override void ApplyState(PanelSelectedState last = PanelSelectedState.Hidden)
{
base.ApplyState(last);
if (last == PanelSelectedState.Hidden && State != last)
starCounter.ReplayAnimation();
}
public BeatmapPanel(BeatmapInfo beatmap) public BeatmapPanel(BeatmapInfo beatmap)
{ {
Beatmap = beatmap; Beatmap = beatmap;
@ -92,7 +101,6 @@ namespace osu.Game.Beatmaps.Drawables
new FlowContainer new FlowContainer
{ {
Padding = new MarginPadding { Left = 5 }, Padding = new MarginPadding { Left = 5 },
Spacing = new Vector2(0, 5),
Direction = FlowDirections.Vertical, Direction = FlowDirections.Vertical,
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Children = new Drawable[] Children = new Drawable[]
@ -130,7 +138,11 @@ namespace osu.Game.Beatmaps.Drawables
}, },
} }
}, },
new StarCounter { Count = beatmap.StarDifficulty, StarSize = 8 } starCounter = new StarCounter
{
Count = beatmap.StarDifficulty,
Scale = new Vector2(0.8f),
}
} }
} }
} }

View File

@ -50,10 +50,10 @@ namespace osu.Game.Beatmaps.Drawables
protected override void LoadComplete() protected override void LoadComplete()
{ {
base.LoadComplete(); base.LoadComplete();
applyState(); ApplyState();
} }
private void applyState() protected virtual void ApplyState(PanelSelectedState last = PanelSelectedState.Hidden)
{ {
switch (state) switch (state)
{ {
@ -81,9 +81,10 @@ namespace osu.Game.Beatmaps.Drawables
set set
{ {
if (state == value) return; if (state == value) return;
state = value;
applyState(); var last = state;
state = value;
ApplyState(last);
} }
} }

View File

@ -7,16 +7,14 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Transformations; using osu.Framework.Graphics.Transformations;
using osu.Framework.MathUtils; using osu.Framework.MathUtils;
using System; using System;
using System.Collections.Generic;
namespace osu.Game.Graphics.UserInterface namespace osu.Game.Graphics.UserInterface
{ {
public class StarCounter : Container public class StarCounter : Container
{ {
private readonly Container starContainer; private readonly Container<Star> stars;
private readonly List<TextAwesome> stars = new List<TextAwesome>();
private double transformStartTime = 0; private double transformStartTime;
/// <summary> /// <summary>
/// Maximum amount of stars displayed. /// Maximum amount of stars displayed.
@ -24,37 +22,20 @@ namespace osu.Game.Graphics.UserInterface
/// <remarks> /// <remarks>
/// This does not limit the counter value, but the amount of stars displayed. /// This does not limit the counter value, but the amount of stars displayed.
/// </remarks> /// </remarks>
public int MaxStars public int StarCount { get; }
{
get;
protected set;
}
private double animationDelay => 80; private double animationDelay => 80;
private double scalingDuration => 500; private double scalingDuration => 1000;
private EasingTypes scalingEasing => EasingTypes.OutElasticHalf; private EasingTypes scalingEasing => EasingTypes.OutElasticHalf;
private float minStarScale => 0.3f; private float minStarScale => 0.4f;
private double fadingDuration => 100; private double fadingDuration => 100;
private float minStarAlpha => 0.5f; private float minStarAlpha => 0.5f;
public float StarSize = 20; private const float star_size = 20;
public float StarSpacing = 4; private float star_spacing = 4;
public float VisibleValue
{
get
{
double elapsedTime = Time.Current - transformStartTime;
double expectedElapsedTime = Math.Abs(prevCount - count) * animationDelay;
if (elapsedTime >= expectedElapsedTime)
return count;
return Interpolation.ValueAt(elapsedTime, prevCount, count, 0, expectedElapsedTime);
}
}
private float prevCount;
private float count; private float count;
/// <summary> /// <summary>
@ -69,119 +50,121 @@ namespace osu.Game.Graphics.UserInterface
set set
{ {
if (IsLoaded) if (count == value) return;
{
prevCount = VisibleValue;
transformCount(prevCount, value);
}
if (IsLoaded)
transformCount(value);
count = value; count = value;
} }
} }
/// <summary>
/// Shows a float count as stars (up to 10). Used as star difficulty display.
/// </summary>
public StarCounter() : this(10)
{
AutoSizeAxes = Axes.Both;
}
/// <summary> /// <summary>
/// Shows a float count as stars. Used as star difficulty display. /// Shows a float count as stars. Used as star difficulty display.
/// </summary> /// </summary>
/// <param name="maxstars">Maximum amount of stars to display.</param> /// <param name="starCount">Maximum amount of stars to display.</param>
public StarCounter(int maxstars) public StarCounter(int starCount = 10)
{ {
MaxStars = Math.Max(maxstars, 0); StarCount = Math.Max(starCount, 0);
AutoSizeAxes = Axes.Both;
Children = new Drawable[] Children = new Drawable[]
{ {
starContainer = new Container stars = new FlowContainer<Star>
{ {
Anchor = Anchor.CentreLeft, AutoSizeAxes = Axes.Both,
Origin = Anchor.CentreLeft, Direction = FlowDirections.Horizontal,
Spacing = new Vector2(star_spacing),
} }
}; };
starContainer.Width = MaxStars * StarSize + Math.Max(MaxStars - 1, 0) * StarSpacing; for (int i = 0; i < StarCount; i++)
starContainer.Height = StarSize;
for (int i = 0; i < MaxStars; i++)
{ {
TextAwesome star = new TextAwesome stars.Add(new Star
{ {
Icon = FontAwesome.fa_star,
Anchor = Anchor.CentreLeft,
Origin = Anchor.Centre,
TextSize = StarSize,
Scale = new Vector2(minStarScale),
Alpha = minStarAlpha, Alpha = minStarAlpha,
Position = new Vector2((StarSize + StarSpacing) * i + (StarSize + StarSpacing) / 2, 0), });
};
//todo: user Container<T> once we have it.
stars.Add(star);
starContainer.Add(star);
} }
} }
protected override void LoadComplete() protected override void LoadComplete()
{ {
base.LoadComplete(); base.LoadComplete();
// Animate initial state from zero. // Animate initial state from zero.
transformCount(0, Count); ReplayAnimation();
} }
public void ResetCount() public void ResetCount()
{ {
Count = 0; count = 0;
StopAnimation(); StopAnimation();
} }
public void ReplayAnimation()
{
var t = count;
ResetCount();
Count = t;
}
public void StopAnimation() public void StopAnimation()
{ {
prevCount = count; int i = 0;
transformStartTime = Time.Current; foreach (var star in stars.Children)
{
for (int i = 0; i < MaxStars; i++) star.ClearTransformations(true);
transformStarQuick(i, count); star.FadeTo(i < count ? 1.0f : minStarAlpha);
star.Icon.ScaleTo(getStarScale(i, count));
i++;
}
} }
private float getStarScale(int i, float value) private float getStarScale(int i, float value)
{ {
if (value <= i) if (value <= i)
return minStarScale; return minStarScale;
if (i + 1 <= value)
return 1.0f; return i + 1 <= value ? 1.0f : Interpolation.ValueAt(value, minStarScale, 1.0f, i, i + 1);
return Interpolation.ValueAt(value, minStarScale, 1.0f, i, i + 1);
} }
private void transformStar(int i, float value) private void transformCount(float newValue)
{ {
stars[i].FadeTo(i < value ? 1.0f : minStarAlpha, fadingDuration); int i = 0;
stars[i].ScaleTo(getStarScale(i, value), scalingDuration, scalingEasing); foreach (var star in stars.Children)
}
private void transformStarQuick(int i, float value)
{
stars[i].FadeTo(i < value ? 1.0f : minStarAlpha);
stars[i].ScaleTo(getStarScale(i, value));
}
private void transformCount(float currentValue, float newValue)
{
for (int i = 0; i < MaxStars; i++)
{ {
stars[i].ClearTransformations(); star.ClearTransformations(true);
if (currentValue <= newValue) if (count <= newValue)
stars[i].Delay(Math.Max(i - currentValue, 0) * animationDelay); star.Delay(Math.Max(i - count, 0) * animationDelay, true);
else else
stars[i].Delay(Math.Max(currentValue - 1 - i, 0) * animationDelay); star.Delay(Math.Max(count - 1 - i, 0) * animationDelay, true);
transformStar(i, newValue);
stars[i].DelayReset(); star.FadeTo(i < newValue ? 1.0f : minStarAlpha, fadingDuration);
star.Icon.ScaleTo(getStarScale(i, newValue), scalingDuration, scalingEasing);
star.DelayReset();
i++;
}
}
class Star : Container
{
public TextAwesome Icon;
public Star()
{
Size = new Vector2(star_size);
Children = new[]
{
Icon = new TextAwesome
{
TextSize = star_size,
Icon = FontAwesome.fa_star,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
}
};
} }
transformStartTime = Time.Current;
} }
} }
} }