1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 20:47:28 +08:00

Move cursor particles under OsuCursorContainer

This commit is contained in:
Opelkuh 2021-09-09 23:18:19 +02:00
parent c2f7b01ca4
commit 99eff4f41f
4 changed files with 53 additions and 61 deletions

View File

@ -31,11 +31,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
InternalChildren = new[]
{
new LegacyCursorStarParticles
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
ExpandTarget = new NonPlayfieldSprite
{
Texture = skin.GetTexture("cursor"),

View File

@ -4,11 +4,13 @@
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Textures;
using osu.Framework.Input;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Framework.Utils;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Particles;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Rulesets.Osu.UI;
@ -18,7 +20,7 @@ using osuTK;
namespace osu.Game.Rulesets.Osu.Skinning.Legacy
{
public class LegacyCursorStarParticles : BeatSyncedContainer, IKeyBindingHandler<OsuAction>
public class LegacyCursorStarParticles : CompositeDrawable, IKeyBindingHandler<OsuAction>
{
private StarParticleSpewer breakSpewer;
private StarParticleSpewer kiaiSpewer;
@ -64,12 +66,6 @@ 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()
@ -116,7 +112,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
}
if (leftPressed && rightPressed)
breakSpewer.Direction = SpewDirection.Both;
breakSpewer.Direction = SpewDirection.Omni;
else if (leftPressed)
breakSpewer.Direction = SpewDirection.Left;
else if (rightPressed)
@ -125,13 +121,14 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
breakSpewer.Direction = SpewDirection.None;
}
private class StarParticleSpewer : ParticleSpewer
private class StarParticleSpewer : ParticleSpewer, IRequireHighFrequencyMousePosition
{
private const int particle_lifetime_min = 300;
private const int particle_lifetime_max = 1000;
public SpewDirection Direction { get; set; }
protected override bool CanSpawnParticles => base.CanSpawnParticles && cursorScreenPosition.HasValue;
protected override float ParticleGravity => 240;
public StarParticleSpewer(Texture texture, int perSecond)
@ -140,48 +137,52 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
Active.BindValueChanged(_ => resetVelocityCalculation());
}
private Vector2 positionInParent => ToSpaceOfOtherDrawable(OriginPosition, ParticleParent);
private Vector2? cursorScreenPosition;
private Vector2 cursorVelocity;
private Vector2 screenVelocity;
private const double max_velocity_frame_length = 15;
private double velocityFrameLength;
private Vector2 totalPosDifference;
private const double velocity_calculation_delay = 15;
private double lastVelocityCalculation;
private Vector2 positionDifference;
private Vector2? lastPosition;
protected override void Update()
protected override bool OnMouseMove(MouseMoveEvent e)
{
base.Update();
if (lastPosition != null)
if (cursorScreenPosition == null)
{
positionDifference += (positionInParent - lastPosition.Value);
lastVelocityCalculation += Clock.ElapsedFrameTime;
cursorScreenPosition = e.ScreenSpaceMousePosition;
return base.OnMouseMove(e);
}
lastPosition = positionInParent;
// calculate cursor velocity.
totalPosDifference += e.ScreenSpaceMousePosition - cursorScreenPosition.Value;
cursorScreenPosition = e.ScreenSpaceMousePosition;
if (lastVelocityCalculation > velocity_calculation_delay)
velocityFrameLength += Clock.ElapsedFrameTime;
if (velocityFrameLength > max_velocity_frame_length)
{
screenVelocity = positionDifference / (float)lastVelocityCalculation;
cursorVelocity = totalPosDifference / (float)velocityFrameLength;
positionDifference = Vector2.Zero;
lastVelocityCalculation = 0;
totalPosDifference = Vector2.Zero;
velocityFrameLength = 0;
}
return base.OnMouseMove(e);
}
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
private void resetVelocityCalculation()
{
positionDifference = Vector2.Zero;
lastVelocityCalculation = 0;
lastPosition = null;
cursorScreenPosition = null;
totalPosDifference = Vector2.Zero;
velocityFrameLength = 0;
}
protected override FallingParticle SpawnParticle()
{
var p = base.SpawnParticle();
p.StartPosition = positionInParent;
p.StartPosition = ToLocalSpace(cursorScreenPosition ?? Vector2.Zero);
p.Duration = RNG.NextSingle(particle_lifetime_min, particle_lifetime_max);
p.StartAngle = (float)(RNG.NextDouble() * 4 - 2);
p.EndAngle = RNG.NextSingle(-2f, 2f);
@ -207,7 +208,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
);
break;
case SpewDirection.Both:
case SpewDirection.Omni:
p.Velocity = new Vector2(
RNG.NextSingle(-460f, 460f),
RNG.NextSingle(-160f, 160f)
@ -215,7 +216,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
break;
}
p.Velocity += screenVelocity * 40;
p.Velocity += cursorVelocity * 40;
return p;
}
@ -226,7 +227,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
None,
Left,
Right,
Both,
Omni,
}
}
}

View File

@ -11,6 +11,7 @@ using osu.Framework.Input.Bindings;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Rulesets.Osu.Configuration;
using osu.Game.Rulesets.Osu.Skinning.Legacy;
using osu.Game.Rulesets.UI;
using osu.Game.Screens.Play;
using osu.Game.Skinning;
@ -42,7 +43,15 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
InternalChild = fadeContainer = new Container
{
RelativeSizeAxes = Axes.Both,
Child = cursorTrail = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.CursorTrail), _ => new DefaultCursorTrail(), confineMode: ConfineMode.NoScaling)
Children = new[]
{
cursorTrail = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.CursorTrail), _ => new DefaultCursorTrail(), confineMode: ConfineMode.NoScaling),
new LegacyCursorStarParticles()
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
}
};
}

View File

@ -26,22 +26,16 @@ namespace osu.Game.Graphics.Particles
/// </summary>
public readonly BindableBool Active = new BindableBool();
/// <summary>
/// <see cref="Drawable"/> whose DrawInfo will be used to draw each particle.
/// Defaults to the <see cref="ParticleSpewer"/> itself.
/// </summary>
public IDrawable ParticleParent;
public bool HasActiveParticles => Active.Value || (lastParticleAdded + maxLifetime) > Time.Current;
public override bool IsPresent => base.IsPresent && HasActiveParticles;
protected virtual bool CanSpawnParticles => true;
protected virtual float ParticleGravity => 0;
protected ParticleSpewer(Texture texture, int perSecond, double maxLifetime)
{
Texture = texture;
Blending = BlendingParameters.Additive;
ParticleParent = this;
particles = new FallingParticle[perSecond * (int)Math.Ceiling(maxLifetime / 1000)];
@ -57,9 +51,12 @@ namespace osu.Game.Graphics.Particles
// this can happen when seeking in replays.
if (lastParticleAdded > Time.Current) lastParticleAdded = 0;
if (Active.Value && Time.Current > lastParticleAdded + cooldown)
if (Active.Value && CanSpawnParticles && Time.Current > lastParticleAdded + cooldown)
{
addParticle(SpawnParticle());
particles[currentIndex] = SpawnParticle();
currentIndex = (currentIndex + 1) % particles.Length;
lastParticleAdded = Time.Current;
}
Invalidate(Invalidation.DrawNode);
@ -76,14 +73,6 @@ namespace osu.Game.Graphics.Particles
};
}
private void addParticle(FallingParticle fallingParticle)
{
particles[currentIndex] = fallingParticle;
currentIndex = (currentIndex + 1) % particles.Length;
lastParticleAdded = Time.Current;
}
protected override DrawNode CreateDrawNode() => new ParticleSpewerDrawNode(this);
# region DrawNode
@ -96,7 +85,6 @@ namespace osu.Game.Graphics.Particles
private float currentTime;
private float gravity;
private Matrix3 particleDrawMatrix;
public ParticleSpewerDrawNode(Sprite source)
: base(source)
@ -112,7 +100,6 @@ namespace osu.Game.Graphics.Particles
currentTime = (float)Source.Time.Current;
gravity = Source.ParticleGravity;
particleDrawMatrix = Source.ParticleParent.DrawInfo.Matrix;
}
protected override void Blit(Action<TexturedVertex2D> vertexAction)
@ -165,7 +152,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 Vector2Extensions.Transform(new Vector2(x, y), particleDrawMatrix);
return Vector2Extensions.Transform(new Vector2(x, y), DrawInfo.Matrix);
}
}