mirror of
https://github.com/ppy/osu.git
synced 2025-02-22 17:22:58 +08:00
Add nested osu! hitobject pooling
This commit is contained in:
parent
1ea526b5ef
commit
3f78d81386
@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
private OsuInputManager osuActionInputManager;
|
private OsuInputManager osuActionInputManager;
|
||||||
internal OsuInputManager OsuActionInputManager => osuActionInputManager ??= GetContainingInputManager() as OsuInputManager;
|
internal OsuInputManager OsuActionInputManager => osuActionInputManager ??= GetContainingInputManager() as OsuInputManager;
|
||||||
|
|
||||||
protected virtual void Shake(double maximumLength) => shakeContainer.Shake(maximumLength);
|
public virtual void Shake(double maximumLength) => shakeContainer.Shake(maximumLength);
|
||||||
|
|
||||||
protected override void UpdateInitialTransforms()
|
protected override void UpdateInitialTransforms()
|
||||||
{
|
{
|
||||||
|
@ -164,10 +164,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
{
|
{
|
||||||
base.ClearNestedHitObjects();
|
base.ClearNestedHitObjects();
|
||||||
|
|
||||||
headContainer.Clear();
|
headContainer.Clear(false);
|
||||||
tailContainer.Clear();
|
tailContainer.Clear(false);
|
||||||
repeatContainer.Clear();
|
repeatContainer.Clear(false);
|
||||||
tickContainer.Clear();
|
tickContainer.Clear(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
|
protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
|
||||||
@ -178,17 +178,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
return new DrawableSliderTail(tail);
|
return new DrawableSliderTail(tail);
|
||||||
|
|
||||||
case SliderHeadCircle head:
|
case SliderHeadCircle head:
|
||||||
return new DrawableSliderHead(HitObject, head)
|
return new DrawableSliderHead(head);
|
||||||
{
|
|
||||||
OnShake = Shake,
|
|
||||||
CheckHittable = (d, t) => CheckHittable?.Invoke(d, t) ?? true
|
|
||||||
};
|
|
||||||
|
|
||||||
case SliderTick tick:
|
case SliderTick tick:
|
||||||
return new DrawableSliderTick(tick) { Position = tick.Position - HitObject.Position };
|
return new DrawableSliderTick(tick);
|
||||||
|
|
||||||
case SliderRepeat repeat:
|
case SliderRepeat repeat:
|
||||||
return new DrawableSliderRepeat(repeat, this) { Position = repeat.Position - HitObject.Position };
|
return new DrawableSliderRepeat(repeat);
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.CreateNestedHitObject(hitObject);
|
return base.CreateNestedHitObject(hitObject);
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||||
@ -14,21 +16,43 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
protected override OsuSkinComponents CirclePieceComponent => OsuSkinComponents.SliderHeadHitCircle;
|
protected override OsuSkinComponents CirclePieceComponent => OsuSkinComponents.SliderHeadHitCircle;
|
||||||
|
|
||||||
private readonly Slider slider;
|
private DrawableSlider drawableSlider;
|
||||||
|
|
||||||
public DrawableSliderHead(Slider slider, SliderHeadCircle h)
|
private Slider slider => drawableSlider?.HitObject;
|
||||||
|
|
||||||
|
public DrawableSliderHead()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public DrawableSliderHead(SliderHeadCircle h)
|
||||||
: base(h)
|
: base(h)
|
||||||
{
|
{
|
||||||
this.slider = slider;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
pathVersion.BindTo(slider.Path.Version);
|
|
||||||
|
|
||||||
PositionBindable.BindValueChanged(_ => updatePosition());
|
PositionBindable.BindValueChanged(_ => updatePosition());
|
||||||
pathVersion.BindValueChanged(_ => updatePosition(), true);
|
pathVersion.BindValueChanged(_ => updatePosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnFree(HitObject hitObject)
|
||||||
|
{
|
||||||
|
base.OnFree(hitObject);
|
||||||
|
|
||||||
|
pathVersion.UnbindFrom(drawableSlider.PathVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnParentReceived(DrawableHitObject parent)
|
||||||
|
{
|
||||||
|
base.OnParentReceived(parent);
|
||||||
|
|
||||||
|
drawableSlider = (DrawableSlider)parent;
|
||||||
|
|
||||||
|
pathVersion.BindTo(drawableSlider.PathVersion);
|
||||||
|
|
||||||
|
OnShake = drawableSlider.Shake;
|
||||||
|
CheckHittable = (d, t) => drawableSlider.CheckHittable?.Invoke(d, t) ?? true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
@ -44,8 +68,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
public Action<double> OnShake;
|
public Action<double> OnShake;
|
||||||
|
|
||||||
protected override void Shake(double maximumLength) => OnShake?.Invoke(maximumLength);
|
public override void Shake(double maximumLength) => OnShake?.Invoke(maximumLength);
|
||||||
|
|
||||||
private void updatePosition() => Position = HitObject.Position - slider.Position;
|
private void updatePosition()
|
||||||
|
{
|
||||||
|
if (slider != null)
|
||||||
|
Position = HitObject.Position - slider.Position;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
{
|
{
|
||||||
public class DrawableSliderRepeat : DrawableOsuHitObject, ITrackSnaking
|
public class DrawableSliderRepeat : DrawableOsuHitObject, ITrackSnaking
|
||||||
{
|
{
|
||||||
private readonly SliderRepeat sliderRepeat;
|
public new SliderRepeat HitObject => (SliderRepeat)base.HitObject;
|
||||||
private readonly DrawableSlider drawableSlider;
|
|
||||||
|
|
||||||
private double animDuration;
|
private double animDuration;
|
||||||
|
|
||||||
@ -27,11 +26,16 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
public override bool DisplayResult => false;
|
public override bool DisplayResult => false;
|
||||||
|
|
||||||
public DrawableSliderRepeat(SliderRepeat sliderRepeat, DrawableSlider drawableSlider)
|
private DrawableSlider drawableSlider;
|
||||||
|
|
||||||
|
public DrawableSliderRepeat()
|
||||||
|
: base(null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public DrawableSliderRepeat(SliderRepeat sliderRepeat)
|
||||||
: base(sliderRepeat)
|
: base(sliderRepeat)
|
||||||
{
|
{
|
||||||
this.sliderRepeat = sliderRepeat;
|
|
||||||
this.drawableSlider = drawableSlider;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -53,18 +57,27 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ScaleBindable.BindValueChanged(scale => scaleContainer.Scale = new Vector2(scale.NewValue), true);
|
ScaleBindable.BindValueChanged(scale => scaleContainer.Scale = new Vector2(scale.NewValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnParentReceived(DrawableHitObject parent)
|
||||||
|
{
|
||||||
|
base.OnParentReceived(parent);
|
||||||
|
|
||||||
|
drawableSlider = (DrawableSlider)parent;
|
||||||
|
|
||||||
|
Position = HitObject.Position - drawableSlider.Position;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
||||||
{
|
{
|
||||||
if (sliderRepeat.StartTime <= Time.Current)
|
if (HitObject.StartTime <= Time.Current)
|
||||||
ApplyResult(r => r.Type = drawableSlider.Tracking.Value ? r.Judgement.MaxResult : r.Judgement.MinResult);
|
ApplyResult(r => r.Type = drawableSlider.Tracking.Value ? r.Judgement.MaxResult : r.Judgement.MinResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateInitialTransforms()
|
protected override void UpdateInitialTransforms()
|
||||||
{
|
{
|
||||||
animDuration = Math.Min(300, sliderRepeat.SpanDuration);
|
animDuration = Math.Min(300, HitObject.SpanDuration);
|
||||||
|
|
||||||
this.Animate(
|
this.Animate(
|
||||||
d => d.FadeIn(animDuration),
|
d => d.FadeIn(animDuration),
|
||||||
@ -100,7 +113,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
// When the repeat is hit, the arrow should fade out on spot rather than following the slider
|
// When the repeat is hit, the arrow should fade out on spot rather than following the slider
|
||||||
if (IsHit) return;
|
if (IsHit) return;
|
||||||
|
|
||||||
bool isRepeatAtEnd = sliderRepeat.RepeatIndex % 2 == 0;
|
bool isRepeatAtEnd = HitObject.RepeatIndex % 2 == 0;
|
||||||
List<Vector2> curve = ((PlaySliderBody)drawableSlider.Body.Drawable).CurrentCurve;
|
List<Vector2> curve = ((PlaySliderBody)drawableSlider.Body.Drawable).CurrentCurve;
|
||||||
|
|
||||||
Position = isRepeatAtEnd ? end : start;
|
Position = isRepeatAtEnd ? end : start;
|
||||||
|
@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
{
|
{
|
||||||
public class DrawableSliderTail : DrawableOsuHitObject, IRequireTracking, ITrackSnaking
|
public class DrawableSliderTail : DrawableOsuHitObject, IRequireTracking, ITrackSnaking
|
||||||
{
|
{
|
||||||
private readonly SliderTailCircle tailCircle;
|
public new SliderTailCircle HitObject => (SliderTailCircle)base.HitObject;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The judgement text is provided by the <see cref="DrawableSlider"/>.
|
/// The judgement text is provided by the <see cref="DrawableSlider"/>.
|
||||||
@ -25,10 +25,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
private SkinnableDrawable circlePiece;
|
private SkinnableDrawable circlePiece;
|
||||||
private Container scaleContainer;
|
private Container scaleContainer;
|
||||||
|
|
||||||
|
public DrawableSliderTail()
|
||||||
|
: base(null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public DrawableSliderTail(SliderTailCircle tailCircle)
|
public DrawableSliderTail(SliderTailCircle tailCircle)
|
||||||
: base(tailCircle)
|
: base(tailCircle)
|
||||||
{
|
{
|
||||||
this.tailCircle = tailCircle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -52,7 +56,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
ScaleBindable.BindValueChanged(scale => scaleContainer.Scale = new Vector2(scale.NewValue), true);
|
ScaleBindable.BindValueChanged(scale => scaleContainer.Scale = new Vector2(scale.NewValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateInitialTransforms()
|
protected override void UpdateInitialTransforms()
|
||||||
@ -92,6 +96,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateSnakingPosition(Vector2 start, Vector2 end) =>
|
public void UpdateSnakingPosition(Vector2 start, Vector2 end) =>
|
||||||
Position = tailCircle.RepeatIndex % 2 == 0 ? end : start;
|
Position = HitObject.RepeatIndex % 2 == 0 ? end : start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
private SkinnableDrawable scaleContainer;
|
private SkinnableDrawable scaleContainer;
|
||||||
|
|
||||||
|
public DrawableSliderTick()
|
||||||
|
: base(null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public DrawableSliderTick(SliderTick sliderTick)
|
public DrawableSliderTick(SliderTick sliderTick)
|
||||||
: base(sliderTick)
|
: base(sliderTick)
|
||||||
{
|
{
|
||||||
@ -54,7 +59,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
};
|
};
|
||||||
|
|
||||||
ScaleBindable.BindValueChanged(scale => scaleContainer.Scale = new Vector2(scale.NewValue), true);
|
ScaleBindable.BindValueChanged(scale => scaleContainer.Scale = new Vector2(scale.NewValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnParentReceived(DrawableHitObject parent)
|
||||||
|
{
|
||||||
|
base.OnParentReceived(parent);
|
||||||
|
|
||||||
|
Position = HitObject.Position - ((DrawableSlider)parent).HitObject.Position;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
||||||
|
@ -160,7 +160,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
protected override void ClearNestedHitObjects()
|
protected override void ClearNestedHitObjects()
|
||||||
{
|
{
|
||||||
base.ClearNestedHitObjects();
|
base.ClearNestedHitObjects();
|
||||||
ticks.Clear();
|
ticks.Clear(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
|
protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
|
||||||
|
@ -5,6 +5,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
{
|
{
|
||||||
public class DrawableSpinnerBonusTick : DrawableSpinnerTick
|
public class DrawableSpinnerBonusTick : DrawableSpinnerTick
|
||||||
{
|
{
|
||||||
|
public DrawableSpinnerBonusTick()
|
||||||
|
: base(null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public DrawableSpinnerBonusTick(SpinnerBonusTick spinnerTick)
|
public DrawableSpinnerBonusTick(SpinnerBonusTick spinnerTick)
|
||||||
: base(spinnerTick)
|
: base(spinnerTick)
|
||||||
{
|
{
|
||||||
|
@ -7,6 +7,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
{
|
{
|
||||||
public override bool DisplayResult => false;
|
public override bool DisplayResult => false;
|
||||||
|
|
||||||
|
public DrawableSpinnerTick()
|
||||||
|
: base(null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public DrawableSpinnerTick(SpinnerTick spinnerTick)
|
public DrawableSpinnerTick(SpinnerTick spinnerTick)
|
||||||
: base(spinnerTick)
|
: base(spinnerTick)
|
||||||
{
|
{
|
||||||
|
@ -38,8 +38,16 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
registerPool<HitCircle, DrawableHitCircle>(10, 100);
|
registerPool<HitCircle, DrawableHitCircle>(10, 100);
|
||||||
|
|
||||||
registerPool<Slider, DrawableSlider>(10, 100);
|
registerPool<Slider, DrawableSlider>(10, 100);
|
||||||
|
registerPool<SliderHeadCircle, DrawableSliderHead>(10, 100);
|
||||||
|
registerPool<SliderTailCircle, DrawableSliderTail>(10, 100);
|
||||||
|
registerPool<SliderTick, DrawableSliderTick>(10, 100);
|
||||||
|
registerPool<SliderRepeat, DrawableSliderRepeat>(5, 50);
|
||||||
|
|
||||||
registerPool<Spinner, DrawableSpinner>(2, 20);
|
registerPool<Spinner, DrawableSpinner>(2, 20);
|
||||||
|
registerPool<SpinnerTick, DrawableSpinnerTick>(10, 100);
|
||||||
|
registerPool<SpinnerBonusTick, DrawableSpinnerBonusTick>(10, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerPool<TObject, TDrawable>(int initialSize, int? maximumSize = null)
|
private void registerPool<TObject, TDrawable>(int initialSize, int? maximumSize = null)
|
||||||
|
Loading…
Reference in New Issue
Block a user