1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-28 02:02:53 +08:00

Slow down legacy followcircle animations

This commit is contained in:
goodtrailer 2022-07-03 13:51:30 -07:00
parent 50a5462446
commit e6a05ce3e2
5 changed files with 175 additions and 18 deletions

View File

@ -319,13 +319,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
const float fade_out_time = 450;
// intentionally pile on an extra FadeOut to make it happen much faster.
Ball.FadeOut(fade_out_time / 4, Easing.Out);
switch (state)
{
case ArmedState.Hit:
Ball.ScaleTo(HitObject.Scale * 1.4f, fade_out_time, Easing.Out);
if (SliderBody?.SnakingOut.Value == true)
Body.FadeOut(40); // short fade to allow for any body colour to smoothly disappear.
break;

View File

@ -23,6 +23,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
public class DrawableSliderBall : CircularContainer, ISliderProgress, IRequireHighFrequencyMousePosition, IHasAccentColour
{
public const float FOLLOW_AREA = 2.4f;
public Func<OsuAction?> GetInitialHitAction;
public Color4 AccentColour
@ -31,7 +33,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
set => ball.Colour = value;
}
private Drawable followCircle;
private Drawable followCircleReceptor;
private DrawableSlider drawableSlider;
private Drawable ball;
@ -47,12 +48,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Children = new[]
{
followCircle = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderFollowCircle), _ => new DefaultFollowCircle())
new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderFollowCircle), _ => new DefaultFollowCircle())
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Alpha = 0,
},
followCircleReceptor = new CircularContainer
{
@ -103,10 +103,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
tracking = value;
followCircleReceptor.Scale = new Vector2(tracking ? 2.4f : 1f);
followCircle.ScaleTo(tracking ? 2.4f : 1f, 300, Easing.OutQuint);
followCircle.FadeTo(tracking ? 1f : 0, 300, Easing.OutQuint);
followCircleReceptor.Scale = new Vector2(tracking ? FOLLOW_AREA : 1f);
}
}

View File

@ -1,17 +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.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osuTK.Graphics;
namespace osu.Game.Rulesets.Osu.Skinning.Default
{
public class DefaultFollowCircle : CompositeDrawable
{
[Resolved(canBeNull: true)]
private DrawableHitObject? parentObject { get; set; }
public DefaultFollowCircle()
{
Alpha = 0f;
RelativeSizeAxes = Axes.Both;
InternalChild = new CircularContainer
@ -29,5 +37,47 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
}
};
}
[BackgroundDependencyLoader]
private void load()
{
if (parentObject != null)
{
var slider = (DrawableSlider)parentObject;
slider.Tracking.BindValueChanged(trackingChanged, true);
}
}
protected override void LoadComplete()
{
base.LoadComplete();
if (parentObject != null)
{
parentObject.ApplyCustomUpdateState += updateStateTransforms;
updateStateTransforms(parentObject, parentObject.State.Value);
}
}
private void trackingChanged(ValueChangedEvent<bool> tracking)
{
const float scale_duration = 300f;
const float fade_duration = 300f;
this.ScaleTo(tracking.NewValue ? DrawableSliderBall.FOLLOW_AREA : 1f, scale_duration, Easing.OutQuint)
.FadeTo(tracking.NewValue ? 1f : 0, fade_duration, Easing.OutQuint);
}
private void updateStateTransforms(DrawableHitObject drawableObject, ArmedState state)
{
if (drawableObject is not DrawableSlider)
return;
const float fade_time = 450f;
using (BeginAbsoluteSequence(drawableObject.HitStateUpdateTime))
// intentionally pile on an extra FadeOut to make it happen much faster.
this.FadeOut(fade_time / 4, Easing.Out);
}
}
}

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@ -19,13 +17,14 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
{
public class DefaultSliderBall : CompositeDrawable
{
private Box box;
private Box box = null!;
[Resolved(canBeNull: true)]
private DrawableHitObject? parentObject { get; set; }
[BackgroundDependencyLoader]
private void load(DrawableHitObject drawableObject, ISkinSource skin)
private void load(ISkinSource skin)
{
var slider = (DrawableSlider)drawableObject;
RelativeSizeAxes = Axes.Both;
float radius = skin.GetConfig<OsuSkinConfiguration, float>(OsuSkinConfiguration.SliderPathRadius)?.Value ?? OsuHitObject.OBJECT_RADIUS;
@ -51,10 +50,60 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
}
};
slider.Tracking.BindValueChanged(trackingChanged, true);
if (parentObject != null)
{
var slider = (DrawableSlider)parentObject;
slider.Tracking.BindValueChanged(trackingChanged, true);
}
}
protected override void LoadComplete()
{
base.LoadComplete();
if (parentObject != null)
{
parentObject.ApplyCustomUpdateState += updateStateTransforms;
updateStateTransforms(parentObject, parentObject.State.Value);
}
}
private void trackingChanged(ValueChangedEvent<bool> tracking) =>
box.FadeTo(tracking.NewValue ? 0.3f : 0.05f, 200, Easing.OutQuint);
private void updateStateTransforms(DrawableHitObject drawableObject, ArmedState state)
{
if (drawableObject is not DrawableSlider)
return;
const float fade_out_time = 450f;
using (BeginAbsoluteSequence(drawableObject.StateUpdateTime))
{
this.ScaleTo(1f)
.FadeIn();
}
using (BeginAbsoluteSequence(drawableObject.HitStateUpdateTime))
{
// intentionally pile on an extra FadeOut to make it happen much faster
this.FadeOut(fade_out_time / 4, Easing.Out);
switch (state)
{
case ArmedState.Hit:
this.ScaleTo(1.4f, fade_out_time, Easing.Out);
break;
}
}
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (parentObject != null)
parentObject.ApplyCustomUpdateState -= updateStateTransforms;
}
}
}

View File

@ -1,13 +1,21 @@
// 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 System.Diagnostics;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Objects.Drawables;
namespace osu.Game.Rulesets.Osu.Skinning.Legacy
{
public class LegacyFollowCircle : CompositeDrawable
{
[Resolved(canBeNull: true)]
private DrawableHitObject? parentObject { get; set; }
public LegacyFollowCircle(Drawable animationContent)
{
// follow circles are 2x the hitcircle resolution in legacy skins (since they are scaled down from >1x
@ -15,8 +23,65 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
animationContent.Anchor = Anchor.Centre;
animationContent.Origin = Anchor.Centre;
Alpha = 0f;
RelativeSizeAxes = Axes.Both;
InternalChild = animationContent;
}
[BackgroundDependencyLoader]
private void load()
{
if (parentObject != null)
{
var slider = (DrawableSlider)parentObject;
slider.Tracking.BindValueChanged(trackingChanged, true);
}
}
protected override void LoadComplete()
{
base.LoadComplete();
if (parentObject != null)
{
parentObject.ApplyCustomUpdateState += updateStateTransforms;
updateStateTransforms(parentObject, parentObject.State.Value);
}
}
private void trackingChanged(ValueChangedEvent<bool> tracking)
{
Debug.Assert(parentObject != null);
if (parentObject.Judged)
return;
const float scale_duration = 180f;
const float fade_duration = 90f;
double maxScaleDuration = parentObject.HitStateUpdateTime - Time.Current;
double realScaleDuration = scale_duration;
if (tracking.NewValue && maxScaleDuration < realScaleDuration)
realScaleDuration = maxScaleDuration;
double realFadeDuration = fade_duration * realScaleDuration / fade_duration;
this.ScaleTo(tracking.NewValue ? DrawableSliderBall.FOLLOW_AREA : 1f, realScaleDuration, Easing.OutQuad)
.FadeTo(tracking.NewValue ? 1f : 0f, realFadeDuration, Easing.OutQuad);
}
private void updateStateTransforms(DrawableHitObject drawableObject, ArmedState state)
{
if (drawableObject is not DrawableSlider)
return;
const float shrink_duration = 200f;
const float fade_duration = 240f;
using (BeginAbsoluteSequence(drawableObject.HitStateUpdateTime))
{
this.ScaleTo(DrawableSliderBall.FOLLOW_AREA * 0.8f, shrink_duration, Easing.OutQuint)
.FadeOut(fade_duration, Easing.InQuint);
}
}
}
}