mirror of
https://github.com/osukey/osukey.git
synced 2025-07-02 00:40:09 +09:00
Pool caught objects and dropped objects
This commit is contained in:
@ -73,7 +73,10 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
|
|
||||||
SetContents(() =>
|
SetContents(() =>
|
||||||
{
|
{
|
||||||
var droppedObjectContainer = new Container();
|
var droppedObjectContainer = new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both
|
||||||
|
};
|
||||||
|
|
||||||
return new CatchInputManager(catchRuleset)
|
return new CatchInputManager(catchRuleset)
|
||||||
{
|
{
|
||||||
|
@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
|
|||||||
[Cached(typeof(IHasCatchObjectState))]
|
[Cached(typeof(IHasCatchObjectState))]
|
||||||
public abstract class CaughtObject : SkinnableDrawable, IHasCatchObjectState
|
public abstract class CaughtObject : SkinnableDrawable, IHasCatchObjectState
|
||||||
{
|
{
|
||||||
public CatchHitObject HitObject { get; private set; }
|
public PalpableCatchHitObject HitObject { get; private set; }
|
||||||
public Bindable<Color4> AccentColour { get; } = new Bindable<Color4>();
|
public Bindable<Color4> AccentColour { get; } = new Bindable<Color4>();
|
||||||
public Bindable<bool> HyperDash { get; } = new Bindable<bool>();
|
public Bindable<bool> HyperDash { get; } = new Bindable<bool>();
|
||||||
|
|
||||||
@ -29,7 +29,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
|
|||||||
protected CaughtObject(CatchSkinComponents skinComponent, Func<ISkinComponent, Drawable> defaultImplementation)
|
protected CaughtObject(CatchSkinComponents skinComponent, Func<ISkinComponent, Drawable> defaultImplementation)
|
||||||
: base(new CatchSkinComponent(skinComponent), defaultImplementation)
|
: base(new CatchSkinComponent(skinComponent), defaultImplementation)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre;
|
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.None;
|
RelativeSizeAxes = Axes.None;
|
||||||
@ -44,6 +43,17 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
|
|||||||
AccentColour.Value = objectState.AccentColour.Value;
|
AccentColour.Value = objectState.AccentColour.Value;
|
||||||
HyperDash.Value = objectState.HyperDash.Value;
|
HyperDash.Value = objectState.HyperDash.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void FreeAfterUse()
|
||||||
|
{
|
||||||
|
ClearTransforms();
|
||||||
|
|
||||||
|
Alpha = 1;
|
||||||
|
LifetimeStart = double.MinValue;
|
||||||
|
LifetimeEnd = double.MaxValue;
|
||||||
|
|
||||||
|
base.FreeAfterUse();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CaughtFruit : CaughtObject, IHasFruitState
|
public class CaughtFruit : CaughtObject, IHasFruitState
|
||||||
|
@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
|
|||||||
{
|
{
|
||||||
public interface IHasCatchObjectState
|
public interface IHasCatchObjectState
|
||||||
{
|
{
|
||||||
CatchHitObject HitObject { get; }
|
PalpableCatchHitObject HitObject { get; }
|
||||||
Bindable<Color4> AccentColour { get; }
|
Bindable<Color4> AccentColour { get; }
|
||||||
Bindable<bool> HyperDash { get; }
|
Bindable<bool> HyperDash { get; }
|
||||||
|
|
||||||
|
@ -108,6 +108,10 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
private readonly DrawablePool<HitExplosion> hitExplosionPool;
|
private readonly DrawablePool<HitExplosion> hitExplosionPool;
|
||||||
private readonly Container<HitExplosion> hitExplosionContainer;
|
private readonly Container<HitExplosion> hitExplosionContainer;
|
||||||
|
|
||||||
|
private readonly DrawablePool<CaughtFruit> caughtFruitPool;
|
||||||
|
private readonly DrawablePool<CaughtBanana> caughtBananaPool;
|
||||||
|
private readonly DrawablePool<CaughtDroplet> caughtDropletPool;
|
||||||
|
|
||||||
public Catcher([NotNull] Container trailsTarget, [NotNull] Container droppedObjectTarget, BeatmapDifficulty difficulty = null)
|
public Catcher([NotNull] Container trailsTarget, [NotNull] Container droppedObjectTarget, BeatmapDifficulty difficulty = null)
|
||||||
{
|
{
|
||||||
this.trailsTarget = trailsTarget;
|
this.trailsTarget = trailsTarget;
|
||||||
@ -124,6 +128,10 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
InternalChildren = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
hitExplosionPool = new DrawablePool<HitExplosion>(10),
|
hitExplosionPool = new DrawablePool<HitExplosion>(10),
|
||||||
|
caughtFruitPool = new DrawablePool<CaughtFruit>(50),
|
||||||
|
caughtBananaPool = new DrawablePool<CaughtBanana>(100),
|
||||||
|
// less capacity is needed compared to fruit because droplet is not stacked
|
||||||
|
caughtDropletPool = new DrawablePool<CaughtDroplet>(25),
|
||||||
caughtFruitContainer = new Container<CaughtObject>
|
caughtFruitContainer = new Container<CaughtObject>
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
@ -452,11 +460,12 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
|
|
||||||
private void placeCaughtObject(DrawablePalpableHasCatchHitObject drawableObject, Vector2 position)
|
private void placeCaughtObject(DrawablePalpableHasCatchHitObject drawableObject, Vector2 position)
|
||||||
{
|
{
|
||||||
var caughtObject = createCaughtObject(drawableObject.HitObject);
|
var caughtObject = getCaughtObject(drawableObject.HitObject);
|
||||||
|
|
||||||
if (caughtObject == null) return;
|
if (caughtObject == null) return;
|
||||||
|
|
||||||
caughtObject.CopyFrom(drawableObject);
|
caughtObject.CopyFrom(drawableObject);
|
||||||
|
caughtObject.Anchor = Anchor.TopCentre;
|
||||||
caughtObject.Position = position;
|
caughtObject.Position = position;
|
||||||
caughtObject.Scale /= 2;
|
caughtObject.Scale /= 2;
|
||||||
|
|
||||||
@ -494,52 +503,62 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
hitExplosionContainer.Add(hitExplosion);
|
hitExplosionContainer.Add(hitExplosion);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CaughtObject createCaughtObject(PalpableCatchHitObject source)
|
private CaughtObject getCaughtObject(PalpableCatchHitObject source)
|
||||||
{
|
{
|
||||||
switch (source)
|
switch (source)
|
||||||
{
|
{
|
||||||
case Fruit _:
|
case Fruit _:
|
||||||
return new CaughtFruit();
|
return caughtFruitPool.Get();
|
||||||
|
|
||||||
case Banana _:
|
case Banana _:
|
||||||
return new CaughtBanana();
|
return caughtBananaPool.Get();
|
||||||
|
|
||||||
case Droplet _:
|
case Droplet _:
|
||||||
return new CaughtDroplet();
|
return caughtDropletPool.Get();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private CaughtObject getDroppedObject(CaughtObject caughtObject)
|
||||||
|
{
|
||||||
|
var droppedObject = getCaughtObject(caughtObject.HitObject);
|
||||||
|
|
||||||
|
droppedObject.CopyFrom(caughtObject);
|
||||||
|
droppedObject.Anchor = Anchor.TopLeft;
|
||||||
|
droppedObject.Position = caughtFruitContainer.ToSpaceOfOtherDrawable(caughtObject.DrawPosition, droppedObjectTarget);
|
||||||
|
|
||||||
|
return droppedObject;
|
||||||
|
}
|
||||||
|
|
||||||
private void clearPlate(DroppedObjectAnimation animation)
|
private void clearPlate(DroppedObjectAnimation animation)
|
||||||
{
|
{
|
||||||
var caughtObjects = caughtFruitContainer.Children.ToArray();
|
var caughtObjects = caughtFruitContainer.Children.ToArray();
|
||||||
|
var droppedObjects = caughtObjects.Select(getDroppedObject).ToArray();
|
||||||
|
|
||||||
caughtFruitContainer.Clear(false);
|
caughtFruitContainer.Clear(false);
|
||||||
|
|
||||||
droppedObjectTarget.AddRange(caughtObjects);
|
droppedObjectTarget.AddRange(droppedObjects);
|
||||||
|
|
||||||
foreach (var caughtObject in caughtObjects)
|
foreach (var droppedObject in droppedObjects)
|
||||||
drop(caughtObject, animation);
|
applyDropAnimation(droppedObject, animation);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeFromPlate(CaughtObject caughtObject, DroppedObjectAnimation animation)
|
private void removeFromPlate(CaughtObject caughtObject, DroppedObjectAnimation animation)
|
||||||
{
|
{
|
||||||
|
var droppedObject = getDroppedObject(caughtObject);
|
||||||
|
|
||||||
if (!caughtFruitContainer.Remove(caughtObject))
|
if (!caughtFruitContainer.Remove(caughtObject))
|
||||||
throw new InvalidOperationException("Can only drop a caught object on the plate");
|
throw new InvalidOperationException("Can only drop a caught object on the plate");
|
||||||
|
|
||||||
droppedObjectTarget.Add(caughtObject);
|
droppedObjectTarget.Add(droppedObject);
|
||||||
|
|
||||||
drop(caughtObject, animation);
|
applyDropAnimation(droppedObject, animation);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drop(CaughtObject d, DroppedObjectAnimation animation)
|
private void applyDropAnimation(Drawable d, DroppedObjectAnimation animation)
|
||||||
{
|
{
|
||||||
var originalX = d.X * Scale.X;
|
|
||||||
|
|
||||||
d.Anchor = Anchor.TopLeft;
|
|
||||||
d.Position = caughtFruitContainer.ToSpaceOfOtherDrawable(d.DrawPosition, droppedObjectTarget);
|
|
||||||
|
|
||||||
switch (animation)
|
switch (animation)
|
||||||
{
|
{
|
||||||
case DroppedObjectAnimation.Drop:
|
case DroppedObjectAnimation.Drop:
|
||||||
@ -548,6 +567,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DroppedObjectAnimation.Explode:
|
case DroppedObjectAnimation.Explode:
|
||||||
|
var originalX = droppedObjectTarget.ToSpaceOfOtherDrawable(d.DrawPosition, caughtFruitContainer).X * Scale.X;
|
||||||
d.MoveToY(d.Y - 50, 250, Easing.OutSine).Then().MoveToY(d.Y + 50, 500, Easing.InSine);
|
d.MoveToY(d.Y - 50, 250, Easing.OutSine).Then().MoveToY(d.Y + 50, 500, Easing.InSine);
|
||||||
d.MoveToX(d.X + originalX * 6, 1000);
|
d.MoveToX(d.X + originalX * 6, 1000);
|
||||||
d.FadeOut(750);
|
d.FadeOut(750);
|
||||||
|
Reference in New Issue
Block a user