mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 19:42:55 +08:00
Use structs for parts for added safety
This commit is contained in:
parent
3a7291c5cf
commit
84e73e88d5
@ -13,8 +13,12 @@ using osuTK;
|
|||||||
|
|
||||||
namespace osu.Game.Graphics
|
namespace osu.Game.Graphics
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An explosion of textured particles based on how osu-stable randomises the explosion pattern.
|
||||||
|
/// </summary>
|
||||||
public class ParticleExplosion : Sprite
|
public class ParticleExplosion : Sprite
|
||||||
{
|
{
|
||||||
|
private readonly int particleCount;
|
||||||
private readonly double duration;
|
private readonly double duration;
|
||||||
private double startTime;
|
private double startTime;
|
||||||
|
|
||||||
@ -23,11 +27,9 @@ namespace osu.Game.Graphics
|
|||||||
public ParticleExplosion(Texture texture, int particleCount, double duration)
|
public ParticleExplosion(Texture texture, int particleCount, double duration)
|
||||||
{
|
{
|
||||||
Texture = texture;
|
Texture = texture;
|
||||||
|
this.particleCount = particleCount;
|
||||||
this.duration = duration;
|
this.duration = duration;
|
||||||
Blending = BlendingParameters.Additive;
|
Blending = BlendingParameters.Additive;
|
||||||
|
|
||||||
for (int i = 0; i < particleCount; i++)
|
|
||||||
parts.Add(new ParticlePart(duration));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
@ -36,19 +38,23 @@ namespace osu.Game.Graphics
|
|||||||
Restart();
|
Restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Restart the animation from the current point in time.
|
||||||
|
/// Supports transform time offset chaining.
|
||||||
|
/// </summary>
|
||||||
public void Restart()
|
public void Restart()
|
||||||
{
|
{
|
||||||
startTime = TransformStartTime;
|
startTime = TransformStartTime;
|
||||||
this.FadeOutFromOne(duration);
|
this.FadeOutFromOne(duration);
|
||||||
|
|
||||||
foreach (var p in parts)
|
parts.Clear();
|
||||||
p.Randomise();
|
for (int i = 0; i < particleCount; i++)
|
||||||
|
parts.Add(new ParticlePart(duration));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
|
|
||||||
Invalidate(Invalidation.DrawNode);
|
Invalidate(Invalidation.DrawNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +62,7 @@ namespace osu.Game.Graphics
|
|||||||
|
|
||||||
private class ParticleExplosionDrawNode : SpriteDrawNode
|
private class ParticleExplosionDrawNode : SpriteDrawNode
|
||||||
{
|
{
|
||||||
private List<ParticlePart> parts = new List<ParticlePart>();
|
private readonly List<ParticlePart> parts = new List<ParticlePart>();
|
||||||
|
|
||||||
private ParticleExplosion source => (ParticleExplosion)Source;
|
private ParticleExplosion source => (ParticleExplosion)Source;
|
||||||
|
|
||||||
@ -73,9 +79,9 @@ namespace osu.Game.Graphics
|
|||||||
{
|
{
|
||||||
base.ApplyState();
|
base.ApplyState();
|
||||||
|
|
||||||
// this is mostly safe as the parts are immutable.
|
parts.Clear();
|
||||||
// the most that can go wrong is the random state be incorrect
|
parts.AddRange(source.parts);
|
||||||
parts = source.parts;
|
|
||||||
sourceSize = source.Size;
|
sourceSize = source.Size;
|
||||||
startTime = source.startTime;
|
startTime = source.startTime;
|
||||||
currentTime = source.Time.Current;
|
currentTime = source.Time.Current;
|
||||||
@ -111,22 +117,13 @@ namespace osu.Game.Graphics
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ParticlePart
|
private readonly struct ParticlePart
|
||||||
{
|
{
|
||||||
private readonly double availableDuration;
|
private readonly double duration;
|
||||||
|
private readonly double direction;
|
||||||
private double duration;
|
private readonly float distance;
|
||||||
private double direction;
|
|
||||||
private float distance;
|
|
||||||
|
|
||||||
public ParticlePart(double availableDuration)
|
public ParticlePart(double availableDuration)
|
||||||
{
|
|
||||||
this.availableDuration = availableDuration;
|
|
||||||
|
|
||||||
Randomise();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Randomise()
|
|
||||||
{
|
{
|
||||||
distance = RNG.NextSingle(0.5f);
|
distance = RNG.NextSingle(0.5f);
|
||||||
duration = RNG.NextDouble(availableDuration / 3, availableDuration);
|
duration = RNG.NextDouble(availableDuration / 3, availableDuration);
|
||||||
@ -137,12 +134,8 @@ namespace osu.Game.Graphics
|
|||||||
|
|
||||||
public Vector2 PositionAtTime(double time)
|
public Vector2 PositionAtTime(double time)
|
||||||
{
|
{
|
||||||
return new Vector2(0.5f) + positionForOffset(distance * progressAtTime(time));
|
var travelledDistance = distance * progressAtTime(time);
|
||||||
|
return new Vector2(0.5f) + travelledDistance * new Vector2((float)Math.Sin(direction), (float)Math.Cos(direction));
|
||||||
Vector2 positionForOffset(float offset) => new Vector2(
|
|
||||||
(float)(offset * Math.Sin(direction)),
|
|
||||||
(float)(offset * Math.Cos(direction))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private float progressAtTime(double time) => (float)Math.Clamp(time / duration, 0, 1);
|
private float progressAtTime(double time) => (float)Math.Clamp(time / duration, 0, 1);
|
||||||
|
Loading…
Reference in New Issue
Block a user