1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-06 15:17:28 +08:00
osu-lazer/osu.Game/Graphics/UserInterface/StarCounter.cs

155 lines
4.5 KiB
C#
Raw Normal View History

2018-01-05 19:21:19 +08:00
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.MathUtils;
using System;
2017-12-15 17:40:03 +08:00
using System.Linq;
namespace osu.Game.Graphics.UserInterface
{
2016-10-22 16:50:42 +08:00
public class StarCounter : Container
{
private readonly Container<Star> stars;
2016-10-13 10:36:52 +08:00
/// <summary>
/// Maximum amount of stars displayed.
/// </summary>
/// <remarks>
/// This does not limit the counter value, but the amount of stars displayed.
/// </remarks>
public int StarCount { get; }
2016-10-13 09:51:50 +08:00
2016-12-15 21:51:35 +08:00
private double animationDelay => 80;
2016-10-14 06:13:20 +08:00
private double scalingDuration => 1000;
2017-07-23 02:50:25 +08:00
private Easing scalingEasing => Easing.OutElasticHalf;
private float minStarScale => 0.4f;
2016-10-14 06:13:20 +08:00
2016-10-15 07:23:27 +08:00
private double fadingDuration => 100;
private float minStarAlpha => 0.5f;
2016-10-14 06:13:20 +08:00
private const float star_size = 20;
2017-03-06 17:49:23 +08:00
private const float star_spacing = 4;
2016-10-14 06:13:20 +08:00
2017-07-11 21:58:06 +08:00
private float countStars;
2016-10-14 06:13:20 +08:00
/// <summary>
/// Amount of stars represented.
/// </summary>
2017-07-11 21:58:06 +08:00
public float CountStars
2016-10-14 06:13:20 +08:00
{
get
{
2017-07-11 21:58:06 +08:00
return countStars;
2016-10-14 06:13:20 +08:00
}
2016-10-14 06:13:20 +08:00
set
{
2017-07-11 21:58:06 +08:00
if (countStars == value) return;
if (IsLoaded)
transformCount(value);
2017-07-11 21:58:06 +08:00
countStars = value;
2016-10-14 06:13:20 +08:00
}
}
2016-10-13 10:36:52 +08:00
/// <summary>
/// Shows a float count as stars. Used as star difficulty display.
/// </summary>
/// <param name="starCount">Maximum amount of stars to display.</param>
public StarCounter(int starCount = 10)
{
StarCount = Math.Max(starCount, 0);
AutoSizeAxes = Axes.Both;
2016-10-13 09:51:50 +08:00
Children = new Drawable[]
{
2017-03-02 02:33:01 +08:00
stars = new FillFlowContainer<Star>
2016-10-13 09:51:50 +08:00
{
AutoSizeAxes = Axes.Both,
2017-03-04 18:00:17 +08:00
Direction = FillDirection.Horizontal,
2017-03-02 02:33:01 +08:00
Spacing = new Vector2(star_spacing),
2017-12-15 17:40:03 +08:00
ChildrenEnumerable = Enumerable.Range(0, StarCount).Select(i => new Star { Alpha = minStarAlpha })
2016-10-13 09:51:50 +08:00
}
};
2016-11-01 22:24:14 +08:00
}
2016-11-01 22:24:14 +08:00
protected override void LoadComplete()
{
base.LoadComplete();
2016-10-17 07:30:25 +08:00
// Animate initial state from zero.
ReplayAnimation();
}
2016-10-14 06:13:20 +08:00
public void ResetCount()
{
2017-07-11 21:58:06 +08:00
countStars = 0;
2016-10-14 06:13:20 +08:00
StopAnimation();
}
public void ReplayAnimation()
{
2017-07-11 21:58:06 +08:00
var t = countStars;
ResetCount();
2017-07-11 21:58:06 +08:00
CountStars = t;
}
public void StopAnimation()
{
int i = 0;
foreach (var star in stars.Children)
{
2017-02-25 20:12:39 +08:00
star.ClearTransforms(true);
2017-07-11 21:58:06 +08:00
star.FadeTo(i < countStars ? 1.0f : minStarAlpha);
star.Icon.ScaleTo(getStarScale(i, countStars));
i++;
}
}
2016-10-14 06:13:20 +08:00
private float getStarScale(int i, float value)
{
2016-10-14 06:13:20 +08:00
if (value <= i)
2016-10-15 07:23:27 +08:00
return minStarScale;
return i + 1 <= value ? 1.0f : Interpolation.ValueAt(value, minStarScale, 1.0f, i, i + 1);
}
private void transformCount(float newValue)
{
int i = 0;
foreach (var star in stars.Children)
{
2017-02-25 20:12:39 +08:00
star.ClearTransforms(true);
2017-07-11 21:58:06 +08:00
var delay = (countStars <= newValue ? Math.Max(i - countStars, 0) : Math.Max(countStars - 1 - i, 0)) * animationDelay;
star.Delay(delay).FadeTo(i < newValue ? 1.0f : minStarAlpha, fadingDuration);
star.Icon.Delay(delay).ScaleTo(getStarScale(i, newValue), scalingDuration, scalingEasing);
i++;
}
}
2017-03-07 09:59:19 +08:00
private class Star : Container
{
public readonly SpriteIcon Icon;
public Star()
{
Size = new Vector2(star_size);
2017-12-15 17:40:03 +08:00
Child = Icon = new SpriteIcon
{
2017-12-15 17:40:03 +08:00
Size = new Vector2(star_size),
Icon = FontAwesome.fa_star,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
};
}
}
}
}