diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorStarParticles.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorStarParticles.cs
index 52d4eedf42..58fe4f9b7c 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorStarParticles.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorStarParticles.cs
@@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
Direction = SpewDirection.None,
Active =
{
- Value = true,
+ Value = false,
}
},
kiaiSpewer = new StarParticleSpewer(texture, 60)
@@ -64,6 +64,12 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
{
breakSpewer.Active.BindTarget = player.IsBreakTime;
}
+
+ if (osuPlayfield != null)
+ {
+ breakSpewer.ParticleParent = osuPlayfield;
+ kiaiSpewer.ParticleParent = osuPlayfield;
+ }
}
protected override void Update()
@@ -126,7 +132,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
public SpewDirection Direction { get; set; }
- protected override float ParticleGravity => 460;
+ protected override float ParticleGravity => 240;
public StarParticleSpewer(Texture texture, int perSecond)
: base(texture, perSecond, particle_lifetime_max)
@@ -134,7 +140,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
Active.BindValueChanged(_ => resetVelocityCalculation());
}
- private Vector2 screenPosition => ToScreenSpace(OriginPosition);
+ private Vector2 positionInParent => ToSpaceOfOtherDrawable(OriginPosition, ParticleParent);
private Vector2 screenVelocity;
@@ -149,11 +155,11 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
if (lastPosition != null)
{
- positionDifference += (screenPosition - lastPosition.Value);
+ positionDifference += (positionInParent - lastPosition.Value);
lastVelocityCalculation += Clock.ElapsedFrameTime;
}
- lastPosition = screenPosition;
+ lastPosition = positionInParent;
if (lastVelocityCalculation > velocity_calculation_delay)
{
@@ -175,6 +181,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
{
var p = base.SpawnParticle();
+ p.StartPosition = positionInParent;
p.Duration = RNG.NextSingle(particle_lifetime_min, particle_lifetime_max);
p.AngularVelocity = RNG.NextSingle(-3f, 3f);
p.StartScale = RNG.NextSingle(0.5f, 1f);
@@ -188,27 +195,27 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
case SpewDirection.Left:
p.Velocity = new Vector2(
- RNG.NextSingle(-460f, 0) * 2,
- RNG.NextSingle(-40f, 40f) * 2
+ RNG.NextSingle(-460f, 0),
+ RNG.NextSingle(-40f, 40f)
);
break;
case SpewDirection.Right:
p.Velocity = new Vector2(
- RNG.NextSingle(0, 460f) * 2,
- RNG.NextSingle(-40f, 40f) * 2
+ RNG.NextSingle(0, 460f),
+ RNG.NextSingle(-40f, 40f)
);
break;
case SpewDirection.Both:
p.Velocity = new Vector2(
- RNG.NextSingle(-460f, 460f) * 2,
- RNG.NextSingle(-160f, 160f) * 2
+ RNG.NextSingle(-460f, 460f),
+ RNG.NextSingle(-160f, 160f)
);
break;
}
- p.Velocity += screenVelocity * 50;
+ p.Velocity += screenVelocity * 40;
return p;
}
diff --git a/osu.Game/Graphics/Particles/ParticleJet.cs b/osu.Game/Graphics/Particles/ParticleJet.cs
index 6bdde44a2c..763f8d0a9e 100644
--- a/osu.Game/Graphics/Particles/ParticleJet.cs
+++ b/osu.Game/Graphics/Particles/ParticleJet.cs
@@ -36,6 +36,7 @@ namespace osu.Game.Graphics.Particles
);
var direction = new Vector2(MathF.Sin(directionRads), MathF.Cos(directionRads));
+ p.StartPosition = OriginPosition;
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);
diff --git a/osu.Game/Graphics/Particles/ParticleSpewer.cs b/osu.Game/Graphics/Particles/ParticleSpewer.cs
index bc25206311..2251d9590d 100644
--- a/osu.Game/Graphics/Particles/ParticleSpewer.cs
+++ b/osu.Game/Graphics/Particles/ParticleSpewer.cs
@@ -26,6 +26,12 @@ namespace osu.Game.Graphics.Particles
///
public readonly BindableBool Active = new BindableBool();
+ ///
+ /// whose DrawInfo will be used to draw each particle.
+ /// Defaults to the itself.
+ ///
+ public IDrawable ParticleParent;
+
public bool HasActiveParticles => Active.Value || (lastParticleAdded + maxLifetime) > Time.Current;
public override bool IsPresent => base.IsPresent && HasActiveParticles;
@@ -35,6 +41,7 @@ namespace osu.Game.Graphics.Particles
{
Texture = texture;
Blending = BlendingParameters.Additive;
+ ParticleParent = this;
particles = new FallingParticle[perSecond * (int)Math.Ceiling(maxLifetime / 1000)];
@@ -66,7 +73,6 @@ namespace osu.Game.Graphics.Particles
return new FallingParticle
{
StartTime = (float)Time.Current,
- StartPosition = ToScreenSpace(OriginPosition),
};
}
@@ -90,6 +96,7 @@ namespace osu.Game.Graphics.Particles
private float currentTime;
private float gravity;
+ private Matrix3 particleDrawMatrix;
public ParticleSpewerDrawNode(Sprite source)
: base(source)
@@ -105,6 +112,7 @@ namespace osu.Game.Graphics.Particles
currentTime = (float)Source.Time.Current;
gravity = Source.ParticleGravity;
+ particleDrawMatrix = Source.ParticleParent.DrawInfo.Matrix;
}
protected override void Blit(Action vertexAction)
@@ -127,9 +135,8 @@ 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 width = Texture.DisplayWidth * scale;
+ var height = Texture.DisplayHeight * scale;
var rect = new RectangleF(
pos.X - width / 2,
@@ -158,7 +165,7 @@ namespace osu.Game.Graphics.Particles
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;
- return new Vector2(x, y);
+ return Vector2Extensions.Transform(new Vector2(x, y), particleDrawMatrix);
}
}