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); } }