1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-26 10:12:54 +08:00

Change ParticleSpewer to use screen space

This commit is contained in:
Opelkuh 2021-08-29 21:41:47 +02:00
parent 1a60ce164e
commit 714cf33aac
2 changed files with 45 additions and 25 deletions

View File

@ -29,21 +29,20 @@ namespace osu.Game.Graphics.Particles
protected override FallingParticle SpawnParticle()
{
var p = base.SpawnParticle();
var directionRads = MathUtils.DegreesToRadians(
RNG.NextSingle(angle - angle_spread / 2, angle + angle_spread / 2)
);
var direction = new Vector2(MathF.Sin(directionRads), MathF.Cos(directionRads));
return new FallingParticle
{
StartTime = (float)Time.Current,
Position = OriginPosition,
Duration = RNG.NextSingle((float)particle_lifetime * 0.8f, (float)particle_lifetime),
Velocity = direction * new Vector2(RNG.NextSingle(velocity_min, velocity_max)),
AngularVelocity = RNG.NextSingle(-angular_velocity, angular_velocity),
StartScale = 1f,
EndScale = 2f,
};
p.Duration = RNG.NextSingle((float)particle_lifetime * 0.8f, (float)particle_lifetime);
p.Velocity = direction * new Vector2(RNG.NextSingle(velocity_min, velocity_max));
p.AngularVelocity = RNG.NextSingle(-angular_velocity, angular_velocity);
p.StartScale = 1f;
p.EndScale = 2f;
return p;
}
}
}

View File

@ -45,6 +45,10 @@ namespace osu.Game.Graphics.Particles
{
base.Update();
// reset cooldown if the clock was rewound.
// this can happen when seeking in replays.
if (lastParticleAdded > Time.Current) lastParticleAdded = 0;
if (Active && Time.Current > lastParticleAdded + cooldown)
{
addParticle(SpawnParticle());
@ -56,7 +60,14 @@ namespace osu.Game.Graphics.Particles
/// <summary>
/// Called each time a new particle should be spawned.
/// </summary>
protected abstract FallingParticle SpawnParticle();
protected virtual FallingParticle SpawnParticle()
{
return new FallingParticle
{
StartTime = (float)Time.Current,
StartPosition = ToScreenSpace(OriginPosition),
};
}
private void addParticle(FallingParticle fallingParticle)
{
@ -68,6 +79,8 @@ namespace osu.Game.Graphics.Particles
protected override DrawNode CreateDrawNode() => new ParticleSpewerDrawNode(this);
# region DrawNode
private class ParticleSpewerDrawNode : SpriteDrawNode
{
private readonly FallingParticle[] particles;
@ -102,6 +115,10 @@ namespace osu.Game.Graphics.Particles
var timeSinceStart = currentTime - p.StartTime;
// ignore particles from the future.
// these can appear when seeking in replays.
if (timeSinceStart < 0) continue;
var alpha = p.AlphaAtTime(timeSinceStart);
if (alpha <= 0) continue;
@ -109,17 +126,21 @@ namespace osu.Game.Graphics.Particles
var pos = p.PositionAtTime(timeSinceStart, gravity);
var angle = p.AngleAtTime(timeSinceStart);
var matrixScale = DrawInfo.Matrix.ExtractScale();
var width = Texture.DisplayWidth * scale * matrixScale.X;
var height = Texture.DisplayHeight * scale * matrixScale.Y;
var rect = new RectangleF(
pos.X - Texture.DisplayWidth * scale / 2,
pos.Y - Texture.DisplayHeight * scale / 2,
Texture.DisplayWidth * scale,
Texture.DisplayHeight * scale);
pos.X - width / 2,
pos.Y - height / 2,
width,
height);
var quad = new Quad(
transformPosition(rect.TopLeft, rect.Centre, angle),
transformPosition(rect.TopRight, rect.Centre, angle),
transformPosition(rect.BottomLeft, rect.Centre, angle),
transformPosition(rect.BottomRight, rect.Centre, angle)
rotatePosition(rect.TopLeft, rect.Centre, angle),
rotatePosition(rect.TopRight, rect.Centre, angle),
rotatePosition(rect.BottomLeft, rect.Centre, angle),
rotatePosition(rect.BottomRight, rect.Centre, angle)
);
DrawQuad(Texture, quad, DrawColourInfo.Colour.MultiplyAlpha(alpha), null, vertexAction,
@ -128,24 +149,24 @@ namespace osu.Game.Graphics.Particles
}
}
private Vector2 transformPosition(Vector2 pos, Vector2 centre, float angle)
private Vector2 rotatePosition(Vector2 pos, Vector2 centre, float angle)
{
// rotate point around centre.
float cos = MathF.Cos(angle);
float sin = MathF.Sin(angle);
float x = centre.X + (pos.X - centre.X) * cos + (pos.Y - centre.Y) * sin;
float y = centre.Y + (pos.Y - centre.Y) * cos - (pos.X - centre.X) * sin;
// convert to screen space.
return Vector2Extensions.Transform(new Vector2(x, y), DrawInfo.Matrix);
return new Vector2(x, y);
}
}
#endregion
protected struct FallingParticle
{
public float StartTime;
public Vector2 Position;
public Vector2 StartPosition;
public Vector2 Velocity;
public float Duration;
public float AngularVelocity;
@ -163,7 +184,7 @@ namespace osu.Game.Graphics.Particles
var progress = progressAtTime(timeSinceStart);
var grav = new Vector2(0, -gravity) * progress;
return Position + (Velocity - grav) * timeSinceStart;
return StartPosition + (Velocity - grav) * timeSinceStart;
}
private float progressAtTime(float timeSinceStart) => Math.Clamp(timeSinceStart / Duration, 0, 1);