mirror of
https://github.com/ppy/osu.git
synced 2026-05-21 05:09:57 +08:00
remove ISkinnableSwell
This commit removes ISkinnableSwell for taiko swell animations. In place of it, an event named UpdateHitProgress is added to DrawableSwell, and the skin swells are converted to listen to said event and ApplyCustomUpdateState, like how spinner skinning is implemented for std.
This commit is contained in:
@@ -38,6 +38,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
/// </summary>
|
||||
public bool MustAlternate { get; internal set; } = true;
|
||||
|
||||
public event Action<int, int> UpdateHitProgress;
|
||||
|
||||
public DrawableSwell()
|
||||
: this(null)
|
||||
{
|
||||
@@ -123,7 +125,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
|
||||
int numHits = ticks.Count(r => r.IsHit);
|
||||
|
||||
(MainPiece.Drawable as ISkinnableSwell)?.AnimateSwellProgress(this, numHits);
|
||||
UpdateHitProgress?.Invoke(numHits, HitObject.RequiredHits);
|
||||
|
||||
if (numHits == HitObject.RequiredHits)
|
||||
ApplyMaxResult();
|
||||
@@ -158,7 +160,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
{
|
||||
base.UpdateStartTimeStateTransforms();
|
||||
|
||||
(MainPiece.Drawable as ISkinnableSwell)?.AnimateSwellStart(this);
|
||||
}
|
||||
|
||||
protected override void UpdateHitStateTransforms(ArmedState state)
|
||||
@@ -178,7 +179,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
LifetimeEnd = Time.Current + clear_animation_duration;
|
||||
HandleUserInput = false;
|
||||
|
||||
(MainPiece.Drawable as ISkinnableSwell)?.AnimateSwellCompletion(state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
// 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.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Objects
|
||||
{
|
||||
public interface ISkinnableSwell
|
||||
{
|
||||
void AnimateSwellProgress(DrawableTaikoHitObject<Swell> swell, int numHits);
|
||||
|
||||
void AnimateSwellCompletion(ArmedState state);
|
||||
|
||||
void AnimateSwellStart(DrawableTaikoHitObject<Swell> swell);
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
using System;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
@@ -15,13 +16,15 @@ using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Skinning.Default
|
||||
{
|
||||
public partial class DefaultSwell : Container, ISkinnableSwell
|
||||
public partial class DefaultSwell : Container
|
||||
{
|
||||
private const float target_ring_thick_border = 1.4f;
|
||||
private const float target_ring_thin_border = 1f;
|
||||
private const float target_ring_scale = 5f;
|
||||
private const float inner_ring_alpha = 0.65f;
|
||||
|
||||
private DrawableSwell drawableSwell = null!;
|
||||
|
||||
private readonly Container bodyContainer;
|
||||
private readonly CircularContainer targetRing;
|
||||
private readonly CircularContainer expandingRing;
|
||||
@@ -102,6 +105,17 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default
|
||||
});
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(DrawableHitObject hitObject, OsuColour colours)
|
||||
{
|
||||
drawableSwell = (DrawableSwell)hitObject;
|
||||
drawableSwell.UpdateHitProgress += animateSwellProgress;
|
||||
drawableSwell.ApplyCustomUpdateState += updateStateTransforms;
|
||||
|
||||
expandingRing.Colour = colours.YellowLight;
|
||||
targetRing.BorderColour = colours.YellowDark.Opacity(0.25f);
|
||||
}
|
||||
|
||||
protected virtual Drawable CreateCentreCircle()
|
||||
{
|
||||
return new SwellCirclePiece()
|
||||
@@ -111,18 +125,11 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
private void animateSwellProgress(int numHits, int requiredHits)
|
||||
{
|
||||
expandingRing.Colour = colours.YellowLight;
|
||||
targetRing.BorderColour = colours.YellowDark.Opacity(0.25f);
|
||||
}
|
||||
float completion = (float)numHits / requiredHits;
|
||||
|
||||
public void AnimateSwellProgress(DrawableTaikoHitObject<Swell> swell, int numHits)
|
||||
{
|
||||
float completion = (float)numHits / swell.HitObject.RequiredHits;
|
||||
|
||||
centreCircle.RotateTo((float)(completion * swell.HitObject.Duration / 8), 4000, Easing.OutQuint);
|
||||
centreCircle.RotateTo((float)(completion * drawableSwell.HitObject.Duration / 8), 4000, Easing.OutQuint);
|
||||
|
||||
expandingRing.ScaleTo(1f + Math.Min(target_ring_scale - 1f, (target_ring_scale - 1f) * completion * 1.3f), 260, Easing.OutQuint);
|
||||
|
||||
@@ -132,23 +139,42 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default
|
||||
.FadeTo(completion / 8, 2000, Easing.OutQuint);
|
||||
}
|
||||
|
||||
public void AnimateSwellCompletion(ArmedState state)
|
||||
private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state)
|
||||
{
|
||||
const double transition_duration = 300;
|
||||
if (!(drawableHitObject is DrawableSwell drawableSwell))
|
||||
return;
|
||||
|
||||
bodyContainer.FadeOut(transition_duration, Easing.OutQuad);
|
||||
bodyContainer.ScaleTo(1.4f, transition_duration);
|
||||
centreCircle.FadeOut(transition_duration, Easing.OutQuad);
|
||||
Swell swell = drawableSwell.HitObject;
|
||||
|
||||
using (BeginAbsoluteSequence(swell.StartTime))
|
||||
{
|
||||
if (state == ArmedState.Idle)
|
||||
expandingRing.FadeTo(0);
|
||||
|
||||
const double ring_appear_offset = 100;
|
||||
|
||||
targetRing.Delay(ring_appear_offset).ScaleTo(target_ring_scale, 400, Easing.OutQuint);
|
||||
}
|
||||
|
||||
using (BeginAbsoluteSequence(drawableSwell.HitStateUpdateTime))
|
||||
{
|
||||
const double transition_duration = 300;
|
||||
|
||||
bodyContainer.FadeOut(transition_duration, Easing.OutQuad);
|
||||
bodyContainer.ScaleTo(1.4f, transition_duration);
|
||||
centreCircle.FadeOut(transition_duration, Easing.OutQuad);
|
||||
}
|
||||
}
|
||||
|
||||
public void AnimateSwellStart(DrawableTaikoHitObject<Swell> swell)
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
if (swell.IsHit == false)
|
||||
expandingRing.FadeTo(0);
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
const double ring_appear_offset = 100;
|
||||
|
||||
targetRing.Delay(ring_appear_offset).ScaleTo(target_ring_scale, 400, Easing.OutQuint);
|
||||
if (drawableSwell.IsNotNull())
|
||||
{
|
||||
drawableSwell.UpdateHitProgress -= animateSwellProgress;
|
||||
drawableSwell.ApplyCustomUpdateState -= updateStateTransforms;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,14 @@ using osu.Framework.Audio.Sample;
|
||||
using osu.Game.Audio;
|
||||
using osuTK;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Framework.Extensions.ObjectExtensions;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
|
||||
{
|
||||
public partial class LegacySwell : Container, ISkinnableSwell
|
||||
public partial class LegacySwell : Container
|
||||
{
|
||||
private DrawableSwell drawableSwell = null!;
|
||||
|
||||
private Container bodyContainer = null!;
|
||||
private Sprite warning = null!;
|
||||
private Sprite spinnerCircle = null!;
|
||||
@@ -35,7 +38,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(ISkinSource skin, SkinManager skinManager)
|
||||
private void load(DrawableHitObject hitObject, ISkinSource skin, SkinManager skinManager)
|
||||
{
|
||||
Child = new Container
|
||||
{
|
||||
@@ -96,49 +99,71 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
|
||||
}
|
||||
};
|
||||
|
||||
drawableSwell = (DrawableSwell)hitObject;
|
||||
drawableSwell.UpdateHitProgress += animateSwellProgress;
|
||||
drawableSwell.ApplyCustomUpdateState += updateStateTransforms;
|
||||
clearSample = skin.GetSample(new SampleInfo("spinner-osu"));
|
||||
}
|
||||
|
||||
public void AnimateSwellProgress(DrawableTaikoHitObject<Swell> swell, int numHits)
|
||||
private void animateSwellProgress(int numHits, int requiredHits)
|
||||
{
|
||||
remainingHitsCountdown.Text = $"{swell.HitObject.RequiredHits - numHits}";
|
||||
remainingHitsCountdown.Text = $"{requiredHits - numHits}";
|
||||
spinnerCircle.RotateTo(180f * numHits, 1000, Easing.OutQuint);
|
||||
}
|
||||
|
||||
public void AnimateSwellCompletion(ArmedState state)
|
||||
private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state)
|
||||
{
|
||||
const double clear_transition_duration = 300;
|
||||
if (!(drawableHitObject is DrawableSwell drawableSwell))
|
||||
return;
|
||||
|
||||
bodyContainer.FadeOut(clear_transition_duration, Easing.OutQuad);
|
||||
Swell swell = drawableSwell.HitObject;
|
||||
|
||||
if (state == ArmedState.Hit)
|
||||
using (BeginAbsoluteSequence(swell.StartTime))
|
||||
{
|
||||
if (!samplePlayed)
|
||||
if (state == ArmedState.Idle)
|
||||
{
|
||||
clearSample?.Play();
|
||||
samplePlayed = true;
|
||||
remainingHitsCountdown.Text = $"{swell.RequiredHits}";
|
||||
samplePlayed = false;
|
||||
}
|
||||
|
||||
clearAnimation
|
||||
.FadeIn(clear_transition_duration, Easing.InQuad)
|
||||
.ScaleTo(0.8f, clear_transition_duration, Easing.InQuad)
|
||||
.Delay(700).FadeOut(200, Easing.OutQuad);
|
||||
const double body_transition_duration = 100;
|
||||
|
||||
warning.FadeOut(body_transition_duration);
|
||||
bodyContainer.FadeIn(body_transition_duration);
|
||||
shrinkingRing.ResizeTo(0.1f, swell.Duration);
|
||||
}
|
||||
|
||||
using (BeginAbsoluteSequence(drawableSwell.HitStateUpdateTime))
|
||||
{
|
||||
const double clear_transition_duration = 300;
|
||||
|
||||
bodyContainer.FadeOut(clear_transition_duration, Easing.OutQuad);
|
||||
|
||||
if (state == ArmedState.Hit)
|
||||
{
|
||||
if (!samplePlayed)
|
||||
{
|
||||
clearSample?.Play();
|
||||
samplePlayed = true;
|
||||
}
|
||||
|
||||
clearAnimation
|
||||
.FadeIn(clear_transition_duration, Easing.InQuad)
|
||||
.ScaleTo(0.8f, clear_transition_duration, Easing.InQuad)
|
||||
.Delay(700).FadeOut(200, Easing.OutQuad);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AnimateSwellStart(DrawableTaikoHitObject<Swell> swell)
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
if (swell.IsHit == false)
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (drawableSwell.IsNotNull())
|
||||
{
|
||||
remainingHitsCountdown.Text = $"{swell.HitObject.RequiredHits}";
|
||||
samplePlayed = false;
|
||||
drawableSwell.UpdateHitProgress -= animateSwellProgress;
|
||||
drawableSwell.ApplyCustomUpdateState -= updateStateTransforms;
|
||||
}
|
||||
|
||||
const double body_transition_duration = 100;
|
||||
|
||||
warning.FadeOut(body_transition_duration);
|
||||
bodyContainer.FadeIn(body_transition_duration);
|
||||
shrinkingRing.ResizeTo(0.1f, swell.HitObject.Duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user