mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 12:57:36 +08:00
Move cursor particles under OsuCursorContainer
This commit is contained in:
parent
c2f7b01ca4
commit
99eff4f41f
@ -31,11 +31,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
|||||||
|
|
||||||
InternalChildren = new[]
|
InternalChildren = new[]
|
||||||
{
|
{
|
||||||
new LegacyCursorStarParticles
|
|
||||||
{
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
},
|
|
||||||
ExpandTarget = new NonPlayfieldSprite
|
ExpandTarget = new NonPlayfieldSprite
|
||||||
{
|
{
|
||||||
Texture = skin.GetTexture("cursor"),
|
Texture = skin.GetTexture("cursor"),
|
||||||
|
@ -4,11 +4,13 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osu.Framework.Input;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
|
using osu.Framework.Input.Events;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
|
||||||
using osu.Game.Graphics.Particles;
|
using osu.Game.Graphics.Particles;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.UI;
|
using osu.Game.Rulesets.Osu.UI;
|
||||||
@ -18,7 +20,7 @@ using osuTK;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||||
{
|
{
|
||||||
public class LegacyCursorStarParticles : BeatSyncedContainer, IKeyBindingHandler<OsuAction>
|
public class LegacyCursorStarParticles : CompositeDrawable, IKeyBindingHandler<OsuAction>
|
||||||
{
|
{
|
||||||
private StarParticleSpewer breakSpewer;
|
private StarParticleSpewer breakSpewer;
|
||||||
private StarParticleSpewer kiaiSpewer;
|
private StarParticleSpewer kiaiSpewer;
|
||||||
@ -64,12 +66,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
|||||||
{
|
{
|
||||||
breakSpewer.Active.BindTarget = player.IsBreakTime;
|
breakSpewer.Active.BindTarget = player.IsBreakTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (osuPlayfield != null)
|
|
||||||
{
|
|
||||||
breakSpewer.ParticleParent = osuPlayfield;
|
|
||||||
kiaiSpewer.ParticleParent = osuPlayfield;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
@ -116,7 +112,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (leftPressed && rightPressed)
|
if (leftPressed && rightPressed)
|
||||||
breakSpewer.Direction = SpewDirection.Both;
|
breakSpewer.Direction = SpewDirection.Omni;
|
||||||
else if (leftPressed)
|
else if (leftPressed)
|
||||||
breakSpewer.Direction = SpewDirection.Left;
|
breakSpewer.Direction = SpewDirection.Left;
|
||||||
else if (rightPressed)
|
else if (rightPressed)
|
||||||
@ -125,13 +121,14 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
|||||||
breakSpewer.Direction = SpewDirection.None;
|
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_min = 300;
|
||||||
private const int particle_lifetime_max = 1000;
|
private const int particle_lifetime_max = 1000;
|
||||||
|
|
||||||
public SpewDirection Direction { get; set; }
|
public SpewDirection Direction { get; set; }
|
||||||
|
|
||||||
|
protected override bool CanSpawnParticles => base.CanSpawnParticles && cursorScreenPosition.HasValue;
|
||||||
protected override float ParticleGravity => 240;
|
protected override float ParticleGravity => 240;
|
||||||
|
|
||||||
public StarParticleSpewer(Texture texture, int perSecond)
|
public StarParticleSpewer(Texture texture, int perSecond)
|
||||||
@ -140,48 +137,52 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
|||||||
Active.BindValueChanged(_ => resetVelocityCalculation());
|
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;
|
protected override bool OnMouseMove(MouseMoveEvent e)
|
||||||
private double lastVelocityCalculation;
|
|
||||||
private Vector2 positionDifference;
|
|
||||||
private Vector2? lastPosition;
|
|
||||||
|
|
||||||
protected override void Update()
|
|
||||||
{
|
{
|
||||||
base.Update();
|
if (cursorScreenPosition == null)
|
||||||
|
|
||||||
if (lastPosition != null)
|
|
||||||
{
|
{
|
||||||
positionDifference += (positionInParent - lastPosition.Value);
|
cursorScreenPosition = e.ScreenSpaceMousePosition;
|
||||||
lastVelocityCalculation += Clock.ElapsedFrameTime;
|
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;
|
totalPosDifference = Vector2.Zero;
|
||||||
lastVelocityCalculation = 0;
|
velocityFrameLength = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return base.OnMouseMove(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
|
||||||
|
|
||||||
private void resetVelocityCalculation()
|
private void resetVelocityCalculation()
|
||||||
{
|
{
|
||||||
positionDifference = Vector2.Zero;
|
cursorScreenPosition = null;
|
||||||
lastVelocityCalculation = 0;
|
totalPosDifference = Vector2.Zero;
|
||||||
lastPosition = null;
|
velocityFrameLength = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override FallingParticle SpawnParticle()
|
protected override FallingParticle SpawnParticle()
|
||||||
{
|
{
|
||||||
var p = base.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.Duration = RNG.NextSingle(particle_lifetime_min, particle_lifetime_max);
|
||||||
p.StartAngle = (float)(RNG.NextDouble() * 4 - 2);
|
p.StartAngle = (float)(RNG.NextDouble() * 4 - 2);
|
||||||
p.EndAngle = RNG.NextSingle(-2f, 2f);
|
p.EndAngle = RNG.NextSingle(-2f, 2f);
|
||||||
@ -207,7 +208,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SpewDirection.Both:
|
case SpewDirection.Omni:
|
||||||
p.Velocity = new Vector2(
|
p.Velocity = new Vector2(
|
||||||
RNG.NextSingle(-460f, 460f),
|
RNG.NextSingle(-460f, 460f),
|
||||||
RNG.NextSingle(-160f, 160f)
|
RNG.NextSingle(-160f, 160f)
|
||||||
@ -215,7 +216,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Velocity += screenVelocity * 40;
|
p.Velocity += cursorVelocity * 40;
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@ -226,7 +227,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
|||||||
None,
|
None,
|
||||||
Left,
|
Left,
|
||||||
Right,
|
Right,
|
||||||
Both,
|
Omni,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ using osu.Framework.Input.Bindings;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Rulesets.Osu.Configuration;
|
using osu.Game.Rulesets.Osu.Configuration;
|
||||||
|
using osu.Game.Rulesets.Osu.Skinning.Legacy;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
@ -42,7 +43,15 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
InternalChild = fadeContainer = new Container
|
InternalChild = fadeContainer = new Container
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
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,
|
||||||
|
},
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,22 +26,16 @@ namespace osu.Game.Graphics.Particles
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly BindableBool Active = new BindableBool();
|
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 bool HasActiveParticles => Active.Value || (lastParticleAdded + maxLifetime) > Time.Current;
|
||||||
public override bool IsPresent => base.IsPresent && HasActiveParticles;
|
public override bool IsPresent => base.IsPresent && HasActiveParticles;
|
||||||
|
|
||||||
|
protected virtual bool CanSpawnParticles => true;
|
||||||
protected virtual float ParticleGravity => 0;
|
protected virtual float ParticleGravity => 0;
|
||||||
|
|
||||||
protected ParticleSpewer(Texture texture, int perSecond, double maxLifetime)
|
protected ParticleSpewer(Texture texture, int perSecond, double maxLifetime)
|
||||||
{
|
{
|
||||||
Texture = texture;
|
Texture = texture;
|
||||||
Blending = BlendingParameters.Additive;
|
Blending = BlendingParameters.Additive;
|
||||||
ParticleParent = this;
|
|
||||||
|
|
||||||
particles = new FallingParticle[perSecond * (int)Math.Ceiling(maxLifetime / 1000)];
|
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.
|
// this can happen when seeking in replays.
|
||||||
if (lastParticleAdded > Time.Current) lastParticleAdded = 0;
|
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);
|
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);
|
protected override DrawNode CreateDrawNode() => new ParticleSpewerDrawNode(this);
|
||||||
|
|
||||||
# region DrawNode
|
# region DrawNode
|
||||||
@ -96,7 +85,6 @@ namespace osu.Game.Graphics.Particles
|
|||||||
|
|
||||||
private float currentTime;
|
private float currentTime;
|
||||||
private float gravity;
|
private float gravity;
|
||||||
private Matrix3 particleDrawMatrix;
|
|
||||||
|
|
||||||
public ParticleSpewerDrawNode(Sprite source)
|
public ParticleSpewerDrawNode(Sprite source)
|
||||||
: base(source)
|
: base(source)
|
||||||
@ -112,7 +100,6 @@ namespace osu.Game.Graphics.Particles
|
|||||||
|
|
||||||
currentTime = (float)Source.Time.Current;
|
currentTime = (float)Source.Time.Current;
|
||||||
gravity = Source.ParticleGravity;
|
gravity = Source.ParticleGravity;
|
||||||
particleDrawMatrix = Source.ParticleParent.DrawInfo.Matrix;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Blit(Action<TexturedVertex2D> vertexAction)
|
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 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;
|
||||||
|
|
||||||
return Vector2Extensions.Transform(new Vector2(x, y), particleDrawMatrix);
|
return Vector2Extensions.Transform(new Vector2(x, y), DrawInfo.Matrix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user