mirror of
https://github.com/ppy/osu.git
synced 2025-03-28 09:37:23 +08:00
Merge pull request #13336 from ekrctb/pdwl-catch-explosion
Fix catch hit lighting not always showing when a replay is rewound
This commit is contained in:
commit
bde0071de8
@ -216,7 +216,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
AddStep("enable hit lighting", () => config.SetValue(OsuSetting.HitLighting, true));
|
AddStep("enable hit lighting", () => config.SetValue(OsuSetting.HitLighting, true));
|
||||||
AddStep("catch fruit", () => attemptCatch(new Fruit()));
|
AddStep("catch fruit", () => attemptCatch(new Fruit()));
|
||||||
AddAssert("correct hit lighting colour", () =>
|
AddAssert("correct hit lighting colour", () =>
|
||||||
catcher.ChildrenOfType<HitExplosion>().First()?.ObjectColour == fruitColour);
|
catcher.ChildrenOfType<HitExplosion>().First()?.Entry?.ObjectColour == fruitColour);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -126,8 +126,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
private float hyperDashTargetPosition;
|
private float hyperDashTargetPosition;
|
||||||
private Bindable<bool> hitLighting;
|
private Bindable<bool> hitLighting;
|
||||||
|
|
||||||
private readonly DrawablePool<HitExplosion> hitExplosionPool;
|
private readonly HitExplosionContainer hitExplosionContainer;
|
||||||
private readonly Container<HitExplosion> hitExplosionContainer;
|
|
||||||
|
|
||||||
private readonly DrawablePool<CaughtFruit> caughtFruitPool;
|
private readonly DrawablePool<CaughtFruit> caughtFruitPool;
|
||||||
private readonly DrawablePool<CaughtBanana> caughtBananaPool;
|
private readonly DrawablePool<CaughtBanana> caughtBananaPool;
|
||||||
@ -148,7 +147,6 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
|
|
||||||
InternalChildren = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
hitExplosionPool = new DrawablePool<HitExplosion>(10),
|
|
||||||
caughtFruitPool = new DrawablePool<CaughtFruit>(50),
|
caughtFruitPool = new DrawablePool<CaughtFruit>(50),
|
||||||
caughtBananaPool = new DrawablePool<CaughtBanana>(100),
|
caughtBananaPool = new DrawablePool<CaughtBanana>(100),
|
||||||
// less capacity is needed compared to fruit because droplet is not stacked
|
// less capacity is needed compared to fruit because droplet is not stacked
|
||||||
@ -173,7 +171,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Alpha = 0,
|
Alpha = 0,
|
||||||
},
|
},
|
||||||
hitExplosionContainer = new Container<HitExplosion>
|
hitExplosionContainer = new HitExplosionContainer
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.BottomCentre,
|
Origin = Anchor.BottomCentre,
|
||||||
@ -297,7 +295,6 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
|
|
||||||
caughtObjectContainer.RemoveAll(d => d.HitObject == drawableObject.HitObject);
|
caughtObjectContainer.RemoveAll(d => d.HitObject == drawableObject.HitObject);
|
||||||
droppedObjectTarget.RemoveAll(d => d.HitObject == drawableObject.HitObject);
|
droppedObjectTarget.RemoveAll(d => d.HitObject == drawableObject.HitObject);
|
||||||
hitExplosionContainer.RemoveAll(d => d.HitObject == drawableObject.HitObject);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -508,15 +505,8 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addLighting(CatchHitObject hitObject, float x, Color4 colour)
|
private void addLighting(CatchHitObject hitObject, float x, Color4 colour) =>
|
||||||
{
|
hitExplosionContainer.Add(new HitExplosionEntry(Time.Current, x, hitObject.Scale, colour, hitObject.RandomSeed));
|
||||||
HitExplosion hitExplosion = hitExplosionPool.Get();
|
|
||||||
hitExplosion.HitObject = hitObject;
|
|
||||||
hitExplosion.X = x;
|
|
||||||
hitExplosion.Scale = new Vector2(hitObject.Scale);
|
|
||||||
hitExplosion.ObjectColour = colour;
|
|
||||||
hitExplosionContainer.Add(hitExplosion);
|
|
||||||
}
|
|
||||||
|
|
||||||
private CaughtObject getCaughtObject(PalpableCatchHitObject source)
|
private CaughtObject getCaughtObject(PalpableCatchHitObject source)
|
||||||
{
|
{
|
||||||
|
@ -5,31 +5,16 @@ using osu.Framework.Extensions.Color4Extensions;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Effects;
|
using osu.Framework.Graphics.Effects;
|
||||||
using osu.Framework.Graphics.Pooling;
|
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Objects.Pooling;
|
||||||
|
using osu.Game.Utils;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.UI
|
namespace osu.Game.Rulesets.Catch.UI
|
||||||
{
|
{
|
||||||
public class HitExplosion : PoolableDrawable
|
public class HitExplosion : PoolableDrawableWithLifetime<HitExplosionEntry>
|
||||||
{
|
{
|
||||||
private Color4 objectColour;
|
|
||||||
public CatchHitObject HitObject;
|
|
||||||
|
|
||||||
public Color4 ObjectColour
|
|
||||||
{
|
|
||||||
get => objectColour;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (objectColour == value) return;
|
|
||||||
|
|
||||||
objectColour = value;
|
|
||||||
onColourChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly CircularContainer largeFaint;
|
private readonly CircularContainer largeFaint;
|
||||||
private readonly CircularContainer smallFaint;
|
private readonly CircularContainer smallFaint;
|
||||||
private readonly CircularContainer directionalGlow1;
|
private readonly CircularContainer directionalGlow1;
|
||||||
@ -83,9 +68,19 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void PrepareForUse()
|
protected override void OnApply(HitExplosionEntry entry)
|
||||||
{
|
{
|
||||||
base.PrepareForUse();
|
X = entry.Position;
|
||||||
|
Scale = new Vector2(entry.Scale);
|
||||||
|
setColour(entry.ObjectColour);
|
||||||
|
|
||||||
|
using (BeginAbsoluteSequence(entry.LifetimeStart))
|
||||||
|
applyTransforms(entry.RNGSeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyTransforms(int randomSeed)
|
||||||
|
{
|
||||||
|
ClearTransforms(true);
|
||||||
|
|
||||||
const double duration = 400;
|
const double duration = 400;
|
||||||
|
|
||||||
@ -96,14 +91,13 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
.FadeOut(duration * 2);
|
.FadeOut(duration * 2);
|
||||||
|
|
||||||
const float angle_variangle = 15; // should be less than 45
|
const float angle_variangle = 15; // should be less than 45
|
||||||
directionalGlow1.Rotation = RNG.NextSingle(-angle_variangle, angle_variangle);
|
directionalGlow1.Rotation = StatelessRNG.NextSingle(-angle_variangle, angle_variangle, randomSeed, 4);
|
||||||
directionalGlow2.Rotation = RNG.NextSingle(-angle_variangle, angle_variangle);
|
directionalGlow2.Rotation = StatelessRNG.NextSingle(-angle_variangle, angle_variangle, randomSeed, 5);
|
||||||
|
|
||||||
this.FadeInFromZero(50).Then().FadeOut(duration, Easing.Out);
|
this.FadeInFromZero(50).Then().FadeOut(duration, Easing.Out).Expire();
|
||||||
Expire(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onColourChanged()
|
private void setColour(Color4 objectColour)
|
||||||
{
|
{
|
||||||
const float roundness = 100;
|
const float roundness = 100;
|
||||||
|
|
||||||
|
22
osu.Game.Rulesets.Catch/UI/HitExplosionContainer.cs
Normal file
22
osu.Game.Rulesets.Catch/UI/HitExplosionContainer.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Graphics.Pooling;
|
||||||
|
using osu.Game.Rulesets.Objects.Pooling;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.UI
|
||||||
|
{
|
||||||
|
public class HitExplosionContainer : PooledDrawableWithLifetimeContainer<HitExplosionEntry, HitExplosion>
|
||||||
|
{
|
||||||
|
protected override bool RemoveRewoundEntry => true;
|
||||||
|
|
||||||
|
private readonly DrawablePool<HitExplosion> pool;
|
||||||
|
|
||||||
|
public HitExplosionContainer()
|
||||||
|
{
|
||||||
|
AddInternal(pool = new DrawablePool<HitExplosion>(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override HitExplosion GetDrawable(HitExplosionEntry entry) => pool.Get(d => d.Apply(entry));
|
||||||
|
}
|
||||||
|
}
|
25
osu.Game.Rulesets.Catch/UI/HitExplosionEntry.cs
Normal file
25
osu.Game.Rulesets.Catch/UI/HitExplosionEntry.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Graphics.Performance;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.UI
|
||||||
|
{
|
||||||
|
public class HitExplosionEntry : LifetimeEntry
|
||||||
|
{
|
||||||
|
public readonly float Position;
|
||||||
|
public readonly float Scale;
|
||||||
|
public readonly Color4 ObjectColour;
|
||||||
|
public readonly int RNGSeed;
|
||||||
|
|
||||||
|
public HitExplosionEntry(double startTime, float position, float scale, Color4 objectColour, int rngSeed)
|
||||||
|
{
|
||||||
|
LifetimeStart = startTime;
|
||||||
|
Position = position;
|
||||||
|
Scale = scale;
|
||||||
|
ObjectColour = objectColour;
|
||||||
|
RNGSeed = rngSeed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -75,5 +75,10 @@ namespace osu.Game.Utils
|
|||||||
/// </param>
|
/// </param>
|
||||||
public static float NextSingle(int seed, int series = 0) =>
|
public static float NextSingle(int seed, int series = 0) =>
|
||||||
(float)(NextULong(seed, series) & ((1 << 24) - 1)) / (1 << 24); // float has 24-bit precision
|
(float)(NextULong(seed, series) & ((1 << 24) - 1)) / (1 << 24); // float has 24-bit precision
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Compute a random floating point value between <paramref name="min"/> and <paramref name="max"/> from given seed and series number.
|
||||||
|
/// </summary>
|
||||||
|
public static float NextSingle(float min, float max, int seed, int series = 0) => min + NextSingle(seed, series) * (max - min);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user