1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-15 04:52:57 +08:00

Merge pull request #13545 from frenzibyte/legacy-spinner-approach-circle

Add support for legacy spinner approach circles
This commit is contained in:
Dean Herbert 2021-06-21 18:52:06 +09:00 committed by GitHub
commit 5b9bf54f1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 73 additions and 12 deletions

View File

@ -11,6 +11,7 @@ using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Skinning;
namespace osu.Game.Rulesets.Osu.Mods
{
@ -110,6 +111,9 @@ namespace osu.Game.Rulesets.Osu.Mods
// hide elements we don't care about.
// todo: hide background
spinner.Body.OnSkinChanged += () => hideSpinnerApproachCircle(spinner);
hideSpinnerApproachCircle(spinner);
using (spinner.BeginAbsoluteSequence(fadeStartTime))
spinner.FadeOut(fadeDuration);
@ -160,5 +164,15 @@ namespace osu.Game.Rulesets.Osu.Mods
}
}
}
private static void hideSpinnerApproachCircle(DrawableSpinner spinner)
{
var approachCircle = (spinner.Body.Drawable as IHasApproachCircle)?.ApproachCircle;
if (approachCircle == null)
return;
using (spinner.BeginAbsoluteSequence(spinner.HitObject.StartTime - spinner.HitObject.TimePreempt))
approachCircle.Hide();
}
}
}

View File

@ -12,6 +12,7 @@ using osu.Framework.Input.Bindings;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Judgements;
using osu.Game.Rulesets.Osu.Skinning;
using osu.Game.Rulesets.Osu.Skinning.Default;
using osu.Game.Rulesets.Scoring;
using osu.Game.Skinning;
@ -19,7 +20,7 @@ using osuTK;
namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
public class DrawableHitCircle : DrawableOsuHitObject, IHasMainCirclePiece
public class DrawableHitCircle : DrawableOsuHitObject, IHasMainCirclePiece, IHasApproachCircle
{
public OsuAction? HitAction => HitArea.HitAction;
protected virtual OsuSkinComponents CirclePieceComponent => OsuSkinComponents.HitCircle;
@ -28,6 +29,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
public HitReceptor HitArea { get; private set; }
public SkinnableDrawable CirclePiece { get; private set; }
Drawable IHasApproachCircle.ApproachCircle => ApproachCircle;
private Container scaleContainer;
private InputManager inputManager;

View File

@ -29,6 +29,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
public new OsuSpinnerJudgementResult Result => (OsuSpinnerJudgementResult)base.Result;
public SkinnableDrawable Body { get; private set; }
public SpinnerRotationTracker RotationTracker { get; private set; }
private SpinnerSpmCalculator spmCalculator;
@ -86,7 +88,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
RelativeSizeAxes = Axes.Y,
Children = new Drawable[]
{
new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SpinnerBody), _ => new DefaultSpinner()),
Body = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SpinnerBody), _ => new DefaultSpinner()),
RotationTracker = new SpinnerRotationTracker(this)
}
},

View File

@ -10,7 +10,6 @@ namespace osu.Game.Rulesets.Osu
Cursor,
CursorTrail,
SliderScorePoint,
ApproachCircle,
ReverseArrow,
HitCircleText,
SliderHeadHitCircle,

View File

@ -0,0 +1,18 @@
// 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;
namespace osu.Game.Rulesets.Osu.Skinning
{
/// <summary>
/// A common interface between implementations which provide an approach circle.
/// </summary>
public interface IHasApproachCircle
{
/// <summary>
/// The approach circle drawable.
/// </summary>
Drawable ApproachCircle { get; }
}
}

View File

@ -55,28 +55,40 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Texture = source.GetTexture("spinner-bottom")
Texture = source.GetTexture("spinner-bottom"),
},
discTop = new Sprite
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Texture = source.GetTexture("spinner-top")
Texture = source.GetTexture("spinner-top"),
},
fixedMiddle = new Sprite
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Texture = source.GetTexture("spinner-middle")
Texture = source.GetTexture("spinner-middle"),
},
spinningMiddle = new Sprite
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Texture = source.GetTexture("spinner-middle2")
}
Texture = source.GetTexture("spinner-middle2"),
},
}
});
if (!(source.FindProvider(s => s.GetTexture("spinner-top") != null) is DefaultLegacySkin))
{
AddInternal(ApproachCircle = new Sprite
{
Anchor = Anchor.TopCentre,
Origin = Anchor.Centre,
Texture = source.GetTexture("spinner-approachcircle"),
Scale = new Vector2(SPRITE_SCALE * 1.86f),
Y = SPINNER_Y_CENTRE,
});
}
}
protected override void UpdateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state)

View File

@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
{
spinnerBlink = source.GetConfig<OsuSkinConfiguration, bool>(OsuSkinConfiguration.SpinnerNoBlink)?.Value != true;
AddRangeInternal(new Drawable[]
AddRangeInternal(new[]
{
new Sprite
{
@ -68,6 +68,14 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
Origin = Anchor.TopLeft,
Scale = new Vector2(SPRITE_SCALE)
}
},
ApproachCircle = new Sprite
{
Anchor = Anchor.TopCentre,
Origin = Anchor.Centre,
Texture = source.GetTexture("spinner-approachcircle"),
Scale = new Vector2(SPRITE_SCALE * 1.86f),
Y = SPINNER_Y_CENTRE,
}
});
}

View File

@ -15,8 +15,10 @@ using osuTK;
namespace osu.Game.Rulesets.Osu.Skinning.Legacy
{
public abstract class LegacySpinner : CompositeDrawable
public abstract class LegacySpinner : CompositeDrawable, IHasApproachCircle
{
public const float SPRITE_SCALE = 0.625f;
/// <remarks>
/// All constants are in osu!stable's gamefield space, which is shifted 16px downwards.
/// This offset is negated in both osu!stable and osu!lazer to bring all constants into window-space.
@ -26,12 +28,12 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
protected const float SPINNER_Y_CENTRE = SPINNER_TOP_OFFSET + 219f;
protected const float SPRITE_SCALE = 0.625f;
private const float spm_hide_offset = 50f;
protected DrawableSpinner DrawableSpinner { get; private set; }
public Drawable ApproachCircle { get; protected set; }
private Sprite spin;
private Sprite clear;
@ -175,6 +177,9 @@ 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 * 0.1f, d.HitObject.Duration);
double spinFadeOutLength = Math.Min(400, d.HitObject.Duration);
using (BeginAbsoluteSequence(drawableHitObject.HitStateUpdateTime - spinFadeOutLength, true))