From 846cde53b3dd7c2dd79034cb0ef2e214228c976a Mon Sep 17 00:00:00 2001 From: Opelkuh <25430283+Opelkuh@users.noreply.github.com> Date: Sat, 18 Sep 2021 22:54:12 +0200 Subject: [PATCH] Add `RelativePositionAxes` support --- .../Gameplay/TestSceneParticleSpewer.cs | 25 +++++++++----- osu.Game/Graphics/ParticleSpewer.cs | 33 ++++++++++++++----- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneParticleSpewer.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneParticleSpewer.cs index c259718a7a..31cc505a0d 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneParticleSpewer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneParticleSpewer.cs @@ -28,8 +28,12 @@ namespace osu.Game.Tests.Visual.Gameplay Child = spewer = createSpewer(); AddToggleStep("toggle spawning", value => spewer.Active.Value = value); - AddSliderStep("particle gravity", 0f, 250f, 0f, value => spewer.Gravity = value); - AddSliderStep("particle velocity", 0f, 500f, 250f, value => spewer.MaxVelocity = value); + AddSliderStep("particle gravity", 0f, 1f, 0f, value => spewer.Gravity = value); + AddSliderStep("particle velocity", 0f, 1f, 0.25f, value => spewer.MaxVelocity = value); + AddStep("move to new location", () => + { + spewer.TransformTo(nameof(spewer.SpawnPosition), new Vector2(RNG.NextSingle(), RNG.NextSingle()), 1000, Easing.Out); + }); } [SetUpSteps] @@ -51,14 +55,15 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("is not present", () => !spewer.IsPresent); } - private TestParticleSpewer createSpewer() - { - return new TestParticleSpewer(skinManager.DefaultLegacySkin.GetTexture("star2")) + private TestParticleSpewer createSpewer() => + new TestParticleSpewer(skinManager.DefaultLegacySkin.GetTexture("star2")) { - Anchor = Anchor.Centre, Origin = Anchor.Centre, + RelativePositionAxes = Axes.Both, + RelativeSizeAxes = Axes.Both, + Position = new Vector2(0.5f), + Size = new Vector2(0.5f), }; - } private class TestParticleSpewer : ParticleSpewer { @@ -66,7 +71,10 @@ namespace osu.Game.Tests.Visual.Gameplay private const int rate = 250; public float Gravity; - public float MaxVelocity = 250; + + public float MaxVelocity = 0.25f; + + public Vector2 SpawnPosition { get; set; } = new Vector2(0.5f); protected override float ParticleGravity => Gravity; @@ -82,6 +90,7 @@ namespace osu.Game.Tests.Visual.Gameplay RNG.NextSingle(-MaxVelocity, MaxVelocity), RNG.NextSingle(-MaxVelocity, MaxVelocity) ), + StartPosition = SpawnPosition, Duration = RNG.NextSingle(lifetime), StartAngle = RNG.NextSingle(MathF.PI * 2), EndAngle = RNG.NextSingle(MathF.PI * 2), diff --git a/osu.Game/Graphics/ParticleSpewer.cs b/osu.Game/Graphics/ParticleSpewer.cs index c022fd4598..6bf9bff05a 100644 --- a/osu.Game/Graphics/ParticleSpewer.cs +++ b/osu.Game/Graphics/ParticleSpewer.cs @@ -3,6 +3,7 @@ using System; using osu.Framework.Bindables; +using osu.Framework.Extensions.EnumExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.OpenGL.Vertices; using osu.Framework.Graphics.Primitives; @@ -83,6 +84,8 @@ namespace osu.Game.Graphics private float currentTime; private float gravity; + private Axes relativePositionAxes; + private Vector2 sourceSize; public ParticleSpewerDrawNode(Sprite source) : base(source) @@ -98,6 +101,8 @@ namespace osu.Game.Graphics currentTime = (float)Source.Time.Current; gravity = Source.ParticleGravity; + relativePositionAxes = Source.RelativePositionAxes; + sourceSize = Source.DrawSize; } protected override void Blit(Action vertexAction) @@ -116,18 +121,11 @@ namespace osu.Game.Graphics var alpha = p.AlphaAtTime(timeSinceStart); if (alpha <= 0) continue; - var scale = p.ScaleAtTime(timeSinceStart); var pos = p.PositionAtTime(timeSinceStart, gravity); + var scale = p.ScaleAtTime(timeSinceStart); var angle = p.AngleAtTime(timeSinceStart); - var width = Texture.DisplayWidth * scale; - var height = Texture.DisplayHeight * scale; - - var rect = new RectangleF( - pos.X - width / 2, - pos.Y - height / 2, - width, - height); + var rect = createDrawRect(pos, scale); var quad = new Quad( transformPosition(rect.TopLeft, rect.Centre, angle), @@ -142,6 +140,23 @@ namespace osu.Game.Graphics } } + private RectangleF createDrawRect(Vector2 position, float scale) + { + var width = Texture.DisplayWidth * scale; + var height = Texture.DisplayHeight * scale; + + if (relativePositionAxes.HasFlagFast(Axes.X)) + position.X *= sourceSize.X; + if (relativePositionAxes.HasFlagFast(Axes.Y)) + position.Y *= sourceSize.Y; + + return new RectangleF( + position.X - width / 2, + position.Y - height / 2, + width, + height); + } + private Vector2 transformPosition(Vector2 pos, Vector2 centre, float angle) { float cos = MathF.Cos(angle);