1
0
mirror of https://github.com/ppy/osu.git synced 2025-03-07 05:47:18 +08:00

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

167 lines
4.6 KiB
C#
Raw Normal View History

// 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.
2018-04-13 18:19:50 +09:00
2018-11-20 16:51:59 +09:00
using osuTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
2020-01-09 13:43:44 +09:00
using osu.Framework.Utils;
using System;
2017-12-15 18:40:03 +09:00
using System.Linq;
using osu.Framework.Graphics.Sprites;
2018-04-13 18:19:50 +09:00
namespace osu.Game.Graphics.UserInterface
{
2016-10-22 17:50:42 +09:00
public partial class StarCounter : Container
{
private readonly FillFlowContainer<Star> stars;
2018-04-13 18:19:50 +09:00
2016-10-12 21:36:52 -05: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; }
2018-04-13 18:19:50 +09:00
/// <summary>
/// The added delay for each subsequent star to be animated.
/// </summary>
protected virtual double AnimationDelay => 80;
2018-04-13 18:19:50 +09:00
2017-03-06 18:49:23 +09:00
private const float star_spacing = 4;
2018-04-13 18:19:50 +09:00
2023-01-08 01:47:22 +01:00
public virtual FillDirection Direction
{
set => stars.Direction = value;
}
private float current;
2018-04-13 18:19:50 +09:00
2016-10-13 17:13:20 -05:00
/// <summary>
/// Amount of stars represented.
/// </summary>
public float Current
2016-10-13 17:13:20 -05:00
{
get => current;
2018-04-13 18:19:50 +09:00
2016-10-13 17:13:20 -05:00
set
{
if (current == value) return;
2018-04-13 18:19:50 +09:00
if (IsLoaded)
animate(value);
current = value;
2016-10-13 17:13:20 -05:00
}
}
2018-04-13 18:19:50 +09:00
2016-10-12 21:36:52 -05: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);
2018-04-13 18:19:50 +09:00
AutoSizeAxes = Axes.Both;
2018-04-13 18:19:50 +09:00
2016-10-12 20:51:50 -05:00
Children = new Drawable[]
{
2017-03-01 19:33:01 +01:00
stars = new FillFlowContainer<Star>
2016-10-12 20:51:50 -05:00
{
AutoSizeAxes = Axes.Both,
2017-03-01 19:33:01 +01:00
Spacing = new Vector2(star_spacing),
2022-06-24 21:25:23 +09:00
ChildrenEnumerable = Enumerable.Range(0, StarCount).Select(_ => CreateStar())
2016-10-12 20:51:50 -05:00
}
};
2016-11-01 23:24:14 +09:00
}
2018-04-13 18:19:50 +09:00
public virtual Star CreateStar() => new DefaultStar();
2016-11-01 23:24:14 +09:00
protected override void LoadComplete()
{
base.LoadComplete();
2018-04-13 18:19:50 +09:00
2016-10-16 18:30:25 -05:00
// Animate initial state from zero.
ReplayAnimation();
}
2018-04-13 18:19:50 +09:00
2016-10-13 17:13:20 -05:00
public void ResetCount()
{
current = 0;
2016-10-13 17:13:20 -05:00
StopAnimation();
}
2018-04-13 18:19:50 +09:00
public void ReplayAnimation()
{
float t = current;
ResetCount();
Current = t;
}
2018-04-13 18:19:50 +09:00
public void StopAnimation()
{
animate(current);
foreach (var star in stars)
star.FinishTransforms(true);
}
2018-04-13 18:19:50 +09:00
private float getStarScale(int i, float value) => i + 1 <= value ? 1.0f : Interpolation.ValueAt(value, 0, 1.0f, i, i + 1);
2018-04-13 18:19:50 +09:00
private void animate(float newValue)
{
for (int i = 0; i < stars.Children.Count; i++)
{
var star = stars.Children[i];
2017-02-25 13:12:39 +01:00
star.ClearTransforms(true);
2018-04-13 18:19:50 +09:00
double delay = Math.Max(current <= newValue ? i - current : Math.Min(current, StarCount) - 1 - i, 0) * AnimationDelay;
2018-04-13 18:19:50 +09:00
2021-07-05 23:52:39 +08:00
using (star.BeginDelayedSequence(delay))
star.DisplayAt(getStarScale(i, newValue));
}
}
2018-04-13 18:19:50 +09:00
public partial class DefaultStar : Star
{
private const double scaling_duration = 1000;
private const double fading_duration = 100;
private const Easing scaling_easing = Easing.OutElasticHalf;
private const float min_star_scale = 0.4f;
private const float star_size = 20;
public readonly SpriteIcon Icon;
2019-02-28 13:31:40 +09:00
public DefaultStar()
{
Size = new Vector2(star_size);
2018-04-13 18:19:50 +09:00
InternalChild = Icon = new SpriteIcon
{
2017-12-15 18:40:03 +09:00
Size = new Vector2(star_size),
2019-04-02 19:55:24 +09:00
Icon = FontAwesome.Solid.Star,
2017-12-15 18:40:03 +09:00
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
};
}
public override void DisplayAt(float scale)
{
2020-11-28 20:35:03 +01:00
scale = (float)Interpolation.Lerp(min_star_scale, 1, Math.Clamp(scale, 0, 1));
this.FadeTo(scale, fading_duration);
Icon.ScaleTo(scale, scaling_duration, scaling_easing);
}
}
public abstract partial class Star : CompositeDrawable
{
public abstract void DisplayAt(float scale);
}
}
}