mirror of
https://github.com/ppy/osu.git
synced 2025-02-26 20:43:10 +08:00
Change ParticleSpewer
to use screen space
This commit is contained in:
parent
1a60ce164e
commit
714cf33aac
@ -29,21 +29,20 @@ namespace osu.Game.Graphics.Particles
|
|||||||
|
|
||||||
protected override FallingParticle SpawnParticle()
|
protected override FallingParticle SpawnParticle()
|
||||||
{
|
{
|
||||||
|
var p = base.SpawnParticle();
|
||||||
|
|
||||||
var directionRads = MathUtils.DegreesToRadians(
|
var directionRads = MathUtils.DegreesToRadians(
|
||||||
RNG.NextSingle(angle - angle_spread / 2, angle + angle_spread / 2)
|
RNG.NextSingle(angle - angle_spread / 2, angle + angle_spread / 2)
|
||||||
);
|
);
|
||||||
var direction = new Vector2(MathF.Sin(directionRads), MathF.Cos(directionRads));
|
var direction = new Vector2(MathF.Sin(directionRads), MathF.Cos(directionRads));
|
||||||
|
|
||||||
return new FallingParticle
|
p.Duration = RNG.NextSingle((float)particle_lifetime * 0.8f, (float)particle_lifetime);
|
||||||
{
|
p.Velocity = direction * new Vector2(RNG.NextSingle(velocity_min, velocity_max));
|
||||||
StartTime = (float)Time.Current,
|
p.AngularVelocity = RNG.NextSingle(-angular_velocity, angular_velocity);
|
||||||
Position = OriginPosition,
|
p.StartScale = 1f;
|
||||||
Duration = RNG.NextSingle((float)particle_lifetime * 0.8f, (float)particle_lifetime),
|
p.EndScale = 2f;
|
||||||
Velocity = direction * new Vector2(RNG.NextSingle(velocity_min, velocity_max)),
|
|
||||||
AngularVelocity = RNG.NextSingle(-angular_velocity, angular_velocity),
|
return p;
|
||||||
StartScale = 1f,
|
|
||||||
EndScale = 2f,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,10 @@ namespace osu.Game.Graphics.Particles
|
|||||||
{
|
{
|
||||||
base.Update();
|
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)
|
if (Active && Time.Current > lastParticleAdded + cooldown)
|
||||||
{
|
{
|
||||||
addParticle(SpawnParticle());
|
addParticle(SpawnParticle());
|
||||||
@ -56,7 +60,14 @@ namespace osu.Game.Graphics.Particles
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called each time a new particle should be spawned.
|
/// Called each time a new particle should be spawned.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected abstract FallingParticle SpawnParticle();
|
protected virtual FallingParticle SpawnParticle()
|
||||||
|
{
|
||||||
|
return new FallingParticle
|
||||||
|
{
|
||||||
|
StartTime = (float)Time.Current,
|
||||||
|
StartPosition = ToScreenSpace(OriginPosition),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private void addParticle(FallingParticle fallingParticle)
|
private void addParticle(FallingParticle fallingParticle)
|
||||||
{
|
{
|
||||||
@ -68,6 +79,8 @@ namespace osu.Game.Graphics.Particles
|
|||||||
|
|
||||||
protected override DrawNode CreateDrawNode() => new ParticleSpewerDrawNode(this);
|
protected override DrawNode CreateDrawNode() => new ParticleSpewerDrawNode(this);
|
||||||
|
|
||||||
|
# region DrawNode
|
||||||
|
|
||||||
private class ParticleSpewerDrawNode : SpriteDrawNode
|
private class ParticleSpewerDrawNode : SpriteDrawNode
|
||||||
{
|
{
|
||||||
private readonly FallingParticle[] particles;
|
private readonly FallingParticle[] particles;
|
||||||
@ -102,6 +115,10 @@ namespace osu.Game.Graphics.Particles
|
|||||||
|
|
||||||
var timeSinceStart = currentTime - p.StartTime;
|
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);
|
var alpha = p.AlphaAtTime(timeSinceStart);
|
||||||
if (alpha <= 0) continue;
|
if (alpha <= 0) continue;
|
||||||
|
|
||||||
@ -109,17 +126,21 @@ namespace osu.Game.Graphics.Particles
|
|||||||
var pos = p.PositionAtTime(timeSinceStart, gravity);
|
var pos = p.PositionAtTime(timeSinceStart, gravity);
|
||||||
var angle = p.AngleAtTime(timeSinceStart);
|
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(
|
var rect = new RectangleF(
|
||||||
pos.X - Texture.DisplayWidth * scale / 2,
|
pos.X - width / 2,
|
||||||
pos.Y - Texture.DisplayHeight * scale / 2,
|
pos.Y - height / 2,
|
||||||
Texture.DisplayWidth * scale,
|
width,
|
||||||
Texture.DisplayHeight * scale);
|
height);
|
||||||
|
|
||||||
var quad = new Quad(
|
var quad = new Quad(
|
||||||
transformPosition(rect.TopLeft, rect.Centre, angle),
|
rotatePosition(rect.TopLeft, rect.Centre, angle),
|
||||||
transformPosition(rect.TopRight, rect.Centre, angle),
|
rotatePosition(rect.TopRight, rect.Centre, angle),
|
||||||
transformPosition(rect.BottomLeft, rect.Centre, angle),
|
rotatePosition(rect.BottomLeft, rect.Centre, angle),
|
||||||
transformPosition(rect.BottomRight, rect.Centre, angle)
|
rotatePosition(rect.BottomRight, rect.Centre, angle)
|
||||||
);
|
);
|
||||||
|
|
||||||
DrawQuad(Texture, quad, DrawColourInfo.Colour.MultiplyAlpha(alpha), null, vertexAction,
|
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 cos = MathF.Cos(angle);
|
||||||
float sin = MathF.Sin(angle);
|
float sin = MathF.Sin(angle);
|
||||||
|
|
||||||
float x = centre.X + (pos.X - centre.X) * cos + (pos.Y - centre.Y) * sin;
|
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;
|
float y = centre.Y + (pos.Y - centre.Y) * cos - (pos.X - centre.X) * sin;
|
||||||
|
|
||||||
// convert to screen space.
|
return new Vector2(x, y);
|
||||||
return Vector2Extensions.Transform(new Vector2(x, y), DrawInfo.Matrix);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
protected struct FallingParticle
|
protected struct FallingParticle
|
||||||
{
|
{
|
||||||
public float StartTime;
|
public float StartTime;
|
||||||
public Vector2 Position;
|
public Vector2 StartPosition;
|
||||||
public Vector2 Velocity;
|
public Vector2 Velocity;
|
||||||
public float Duration;
|
public float Duration;
|
||||||
public float AngularVelocity;
|
public float AngularVelocity;
|
||||||
@ -163,7 +184,7 @@ namespace osu.Game.Graphics.Particles
|
|||||||
var progress = progressAtTime(timeSinceStart);
|
var progress = progressAtTime(timeSinceStart);
|
||||||
var grav = new Vector2(0, -gravity) * progress;
|
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);
|
private float progressAtTime(float timeSinceStart) => Math.Clamp(timeSinceStart / Duration, 0, 1);
|
||||||
|
Loading…
Reference in New Issue
Block a user