diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index c635aab5f5..d712ffd92a 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -111,7 +111,7 @@ namespace osu.Game.Rulesets.Osu.Mods // todo: hide background using (spinner.BeginAbsoluteSequence(hitObject.StartTime - hitObject.TimePreempt)) - spinner.HideApproachCircle(); + spinner.ApproachCircle.Hide(); using (spinner.BeginAbsoluteSequence(fadeStartTime)) spinner.FadeOut(fadeDuration); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 942cc52c50..4507b1520c 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -29,6 +29,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables public new OsuSpinnerJudgementResult Result => (OsuSpinnerJudgementResult)base.Result; + public SkinnableDrawable ApproachCircle { get; private set; } + public SpinnerRotationTracker RotationTracker { get; private set; } private SpinnerSpmCalculator spmCalculator; @@ -42,8 +44,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private const float spinning_sample_initial_frequency = 1.0f; private const float spinning_sample_modulated_base_frequency = 0.5f; - internal readonly Bindable ApproachCircleVisibility = new Bindable(Visibility.Visible); - /// /// The amount of bonus score gained from spinning after the required number of spins, for display purposes. /// @@ -88,7 +88,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables RelativeSizeAxes = Axes.Y, Children = new Drawable[] { - new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SpinnerBody), _ => new DefaultSpinner()), + ApproachCircle = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SpinnerApproachCircle)), + new SkinnableSpinnerBody(ApproachCircle.CreateProxy(), _ => new DefaultSpinner()), RotationTracker = new SpinnerRotationTracker(this) } }, @@ -287,11 +288,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables updateBonusScore(); } - /// - /// Hides the spinner's approach circle if it has one. - /// - public void HideApproachCircle() => this.TransformBindableTo(ApproachCircleVisibility, Visibility.Hidden); - private static readonly int score_per_tick = new SpinnerBonusTick.OsuSpinnerBonusTickJudgement().MaxNumericResult; private int wholeSpins; diff --git a/osu.Game.Rulesets.Osu/OsuSkinComponents.cs b/osu.Game.Rulesets.Osu/OsuSkinComponents.cs index fcb544fa5b..687fc1f966 100644 --- a/osu.Game.Rulesets.Osu/OsuSkinComponents.cs +++ b/osu.Game.Rulesets.Osu/OsuSkinComponents.cs @@ -10,7 +10,6 @@ namespace osu.Game.Rulesets.Osu Cursor, CursorTrail, SliderScorePoint, - ApproachCircle, ReverseArrow, HitCircleText, SliderHeadHitCircle, @@ -19,5 +18,6 @@ namespace osu.Game.Rulesets.Osu SliderBall, SliderBody, SpinnerBody, + SpinnerApproachCircle, } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs index 5b0c2d405b..f32caab8ac 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs @@ -32,7 +32,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy protected DrawableSpinner DrawableSpinner { get; private set; } - private Drawable approachCircle; private Sprite spin; private Sprite clear; @@ -61,7 +60,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy RelativeSizeAxes = Axes.Both, Children = new[] { - approachCircle = getSpinnerApproachCircle(source), spin = new Sprite { Anchor = Anchor.TopCentre, @@ -104,28 +102,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy }.With(s => s.Font = s.Font.With(fixedWidth: false)), } }); - - static Drawable getSpinnerApproachCircle(ISkinSource source) - { - var spinnerProvider = source.FindProvider(s => - s.GetTexture("spinner-circle") != null || - s.GetTexture("spinner-top") != null); - - if (spinnerProvider is DefaultLegacySkin) - return Empty(); - - return new Sprite - { - Anchor = Anchor.TopCentre, - Origin = Anchor.Centre, - Texture = source.GetTexture("spinner-approachcircle"), - Scale = new Vector2(SPRITE_SCALE * 1.86f), - Y = SPINNER_Y_CENTRE, - }; - } } - private IBindable approachCircleVisibility; private IBindable gainedBonus; private IBindable spinsPerMinute; @@ -135,12 +113,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy { base.LoadComplete(); - approachCircleVisibility = DrawableSpinner.ApproachCircleVisibility.GetBoundCopy(); - approachCircleVisibility.BindValueChanged(v => - { - approachCircle.Alpha = v.NewValue == Visibility.Hidden ? 0 : 1; - }, true); - gainedBonus = DrawableSpinner.GainedBonus.GetBoundCopy(); gainedBonus.BindValueChanged(bonus => { @@ -204,9 +176,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy spmCounter.MoveToOffset(new Vector2(0, -spm_hide_offset), d.HitObject.TimeFadeIn, Easing.Out); } - using (BeginAbsoluteSequence(d.HitObject.StartTime)) - approachCircle.ScaleTo(SPRITE_SCALE * 1.86f).ScaleTo(SPRITE_SCALE * 0.1f, d.HitObject.Duration); - double spinFadeOutLength = Math.Min(400, d.HitObject.Duration); using (BeginAbsoluteSequence(drawableHitObject.HitStateUpdateTime - spinFadeOutLength, true)) diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinnerApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinnerApproachCircle.cs new file mode 100644 index 0000000000..92454cefa3 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinnerApproachCircle.cs @@ -0,0 +1,64 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using JetBrains.Annotations; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Osu.Objects.Drawables; +using osu.Game.Skinning; +using osuTK; +using static osu.Game.Rulesets.Osu.Skinning.Legacy.LegacySpinner; + +namespace osu.Game.Rulesets.Osu.Skinning.Legacy +{ + public class LegacySpinnerApproachCircle : CompositeDrawable + { + private DrawableSpinner drawableSpinner; + + [CanBeNull] + private Sprite sprite; + + [BackgroundDependencyLoader] + private void load(DrawableHitObject drawableHitObject, ISkinSource source) + { + drawableSpinner = (DrawableSpinner)drawableHitObject; + + AutoSizeAxes = Axes.Both; + + var spinnerProvider = source.FindProvider(s => + s.GetTexture("spinner-circle") != null || + s.GetTexture("spinner-top") != null); + + if (spinnerProvider is DefaultLegacySkin) + return; + + InternalChild = sprite = new Sprite + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Texture = source.GetTexture("spinner-approachcircle"), + Scale = new Vector2(SPRITE_SCALE * 1.86f), + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + drawableSpinner.ApplyCustomUpdateState += updateStateTransforms; + updateStateTransforms(drawableSpinner, drawableSpinner.State.Value); + } + + private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state) + { + if (!(drawableHitObject is DrawableSpinner spinner)) + return; + + using (BeginAbsoluteSequence(spinner.HitObject.StartTime)) + sprite?.ScaleTo(SPRITE_SCALE * 0.1f, spinner.HitObject.Duration); + } + } +} diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs index 3267b48ebf..a8c42a3773 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs @@ -121,6 +121,12 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy return new LegacyOldStyleSpinner(); return null; + + case OsuSkinComponents.SpinnerApproachCircle: + if (Source.GetTexture("spinner-approachcircle") != null) + return new LegacySpinnerApproachCircle(); + + return null; } }