mirror of
https://github.com/ppy/osu.git
synced 2025-01-13 15:52:54 +08:00
Merge pull request #25191 from frenzibyte/velocity-based-ball-animation
Apply velocity into legacy slider ball animation rate
This commit is contained in:
commit
a648b32519
@ -1,35 +1,39 @@
|
||||
// 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;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Animations;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||
using osu.Game.Skinning;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||
{
|
||||
public partial class LegacySliderBall : CompositeDrawable
|
||||
{
|
||||
private readonly Drawable animationContent;
|
||||
|
||||
private readonly ISkin skin;
|
||||
|
||||
[Resolved(canBeNull: true)]
|
||||
private DrawableHitObject? parentObject { get; set; }
|
||||
|
||||
public Color4 BallColour => animationContent.Colour;
|
||||
|
||||
private Sprite layerNd = null!;
|
||||
private Sprite layerSpec = null!;
|
||||
|
||||
public LegacySliderBall(Drawable animationContent, ISkin skin)
|
||||
private TextureAnimation ballAnimation = null!;
|
||||
private Texture[] ballTextures = null!;
|
||||
|
||||
public Color4 BallColour => ballAnimation.Colour;
|
||||
|
||||
public LegacySliderBall(ISkin skin)
|
||||
{
|
||||
this.animationContent = animationContent;
|
||||
this.skin = skin;
|
||||
|
||||
AutoSizeAxes = Axes.Both;
|
||||
@ -38,30 +42,39 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
var ballColour = skin.GetConfig<OsuSkinColour, Color4>(OsuSkinColour.SliderBall)?.Value ?? Color4.White;
|
||||
Vector2 maxSize = OsuLegacySkinTransformer.MAX_FOLLOW_CIRCLE_AREA_SIZE;
|
||||
|
||||
InternalChildren = new[]
|
||||
var ballColour = skin.GetConfig<OsuSkinColour, Color4>(OsuSkinColour.SliderBall)?.Value ?? Color4.White;
|
||||
ballTextures = skin.GetTextures("sliderb", default, default, true, "", maxSize, out _);
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
layerNd = new Sprite
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Texture = skin.GetTexture("sliderb-nd")?.WithMaximumSize(OsuLegacySkinTransformer.MAX_FOLLOW_CIRCLE_AREA_SIZE),
|
||||
Texture = skin.GetTexture("sliderb-nd")?.WithMaximumSize(maxSize),
|
||||
Colour = new Color4(5, 5, 5, 255),
|
||||
},
|
||||
LegacyColourCompatibility.ApplyWithDoubledAlpha(animationContent.With(d =>
|
||||
ballAnimation = new LegacySkinExtensions.SkinnableTextureAnimation
|
||||
{
|
||||
d.Anchor = Anchor.Centre;
|
||||
d.Origin = Anchor.Centre;
|
||||
}), ballColour),
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Colour = ballColour,
|
||||
},
|
||||
layerSpec = new Sprite
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Texture = skin.GetTexture("sliderb-spec")?.WithMaximumSize(OsuLegacySkinTransformer.MAX_FOLLOW_CIRCLE_AREA_SIZE),
|
||||
Texture = skin.GetTexture("sliderb-spec")?.WithMaximumSize(maxSize),
|
||||
Blending = BlendingParameters.Additive,
|
||||
},
|
||||
};
|
||||
|
||||
if (parentObject != null)
|
||||
parentObject.HitObjectApplied += onHitObjectApplied;
|
||||
|
||||
onHitObjectApplied(parentObject);
|
||||
}
|
||||
|
||||
private readonly IBindable<Color4> accentColour = new Bindable<Color4>();
|
||||
@ -78,7 +91,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||
if (skin.GetConfig<SkinConfiguration.LegacySetting, bool>(SkinConfiguration.LegacySetting.AllowSliderBallTint)?.Value == true)
|
||||
{
|
||||
accentColour.BindTo(parentObject.AccentColour);
|
||||
accentColour.BindValueChanged(a => animationContent.Colour = a.NewValue, true);
|
||||
accentColour.BindValueChanged(a => ballAnimation.Colour = a.NewValue, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -94,6 +107,26 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||
layerSpec.Rotation = -appliedRotation;
|
||||
}
|
||||
|
||||
private void onHitObjectApplied(DrawableHitObject? drawableObject = null)
|
||||
{
|
||||
double frameDelay;
|
||||
|
||||
if (drawableObject?.HitObject != null)
|
||||
{
|
||||
DrawableSlider drawableSlider = (DrawableSlider)drawableObject;
|
||||
|
||||
frameDelay = Math.Max(
|
||||
0.15 / drawableSlider.HitObject.Velocity * LegacySkinExtensions.SIXTY_FRAME_TIME,
|
||||
LegacySkinExtensions.SIXTY_FRAME_TIME);
|
||||
}
|
||||
else
|
||||
frameDelay = LegacySkinExtensions.SIXTY_FRAME_TIME;
|
||||
|
||||
ballAnimation.ClearFrames();
|
||||
foreach (var texture in ballTextures)
|
||||
ballAnimation.AddFrame(texture, frameDelay);
|
||||
}
|
||||
|
||||
private void updateStateTransforms(DrawableHitObject drawableObject, ArmedState _)
|
||||
{
|
||||
// Gets called by slider ticks, tails, etc., leading to duplicated
|
||||
@ -114,7 +147,10 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (parentObject != null)
|
||||
{
|
||||
parentObject.HitObjectApplied -= onHitObjectApplied;
|
||||
parentObject.ApplyCustomUpdateState -= updateStateTransforms;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,13 +59,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||
return null;
|
||||
|
||||
case OsuSkinComponents.SliderBall:
|
||||
var sliderBallContent = this.GetAnimation("sliderb", true, true, animationSeparator: "", maxSize: MAX_FOLLOW_CIRCLE_AREA_SIZE);
|
||||
|
||||
// todo: slider ball has a custom frame delay based on velocity
|
||||
// Math.Max((150 / Velocity) * GameBase.SIXTY_FRAME_TIME, GameBase.SIXTY_FRAME_TIME);
|
||||
|
||||
if (sliderBallContent != null)
|
||||
return new LegacySliderBall(sliderBallContent, this);
|
||||
if (GetTexture("sliderb") != null || GetTexture("sliderb0") != null)
|
||||
return new LegacySliderBall(this);
|
||||
|
||||
return null;
|
||||
|
||||
|
@ -200,7 +200,11 @@ namespace osu.Game.Skinning
|
||||
}
|
||||
}
|
||||
|
||||
private const double default_frame_time = 1000 / 60d;
|
||||
/// <summary>
|
||||
/// The frame length of each frame at a 60 FPS rate.
|
||||
/// Default frame rate for legacy skin animations.
|
||||
/// </summary>
|
||||
public const double SIXTY_FRAME_TIME = 1000 / 60d;
|
||||
|
||||
private static double getFrameLength(ISkin source, bool applyConfigFrameRate, Texture[] textures)
|
||||
{
|
||||
@ -214,7 +218,7 @@ namespace osu.Game.Skinning
|
||||
return 1000f / textures.Length;
|
||||
}
|
||||
|
||||
return default_frame_time;
|
||||
return SIXTY_FRAME_TIME;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user