2022-12-11 09:17:50 +08:00
|
|
|
|
// 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;
|
|
|
|
|
using osu.Framework.Allocation;
|
|
|
|
|
using osu.Framework.Graphics.Containers;
|
|
|
|
|
using osu.Game.Skinning;
|
|
|
|
|
using osu.Framework.Graphics.Sprites;
|
|
|
|
|
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
|
|
|
|
using osu.Game.Rulesets.Taiko.Objects;
|
|
|
|
|
using osu.Game.Audio;
|
|
|
|
|
using osuTK;
|
|
|
|
|
using osu.Game.Rulesets.Objects.Drawables;
|
2025-01-31 17:51:35 +08:00
|
|
|
|
using osu.Framework.Extensions.ObjectExtensions;
|
2025-01-31 19:55:29 +08:00
|
|
|
|
using System;
|
2025-02-11 22:20:36 +08:00
|
|
|
|
using System.Globalization;
|
2025-02-12 17:55:57 +08:00
|
|
|
|
using osu.Framework.Utils;
|
2022-12-11 09:17:50 +08:00
|
|
|
|
|
|
|
|
|
namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
|
|
|
|
|
{
|
2025-01-31 17:51:35 +08:00
|
|
|
|
public partial class LegacySwell : Container
|
2022-12-11 09:17:50 +08:00
|
|
|
|
{
|
2025-02-12 17:55:57 +08:00
|
|
|
|
private const float scale_adjust = 768f / 480;
|
2025-02-12 18:30:30 +08:00
|
|
|
|
private static readonly Vector2 swell_display_position = new Vector2(250f, 100f);
|
2025-02-12 17:55:57 +08:00
|
|
|
|
|
2025-01-31 17:51:35 +08:00
|
|
|
|
private DrawableSwell drawableSwell = null!;
|
|
|
|
|
|
2022-12-11 09:17:50 +08:00
|
|
|
|
private Container bodyContainer = null!;
|
2025-01-31 16:55:39 +08:00
|
|
|
|
private Sprite warning = null!;
|
2022-12-11 09:17:50 +08:00
|
|
|
|
private Sprite spinnerCircle = null!;
|
2025-01-31 19:55:29 +08:00
|
|
|
|
private Sprite approachCircle = null!;
|
2022-12-11 09:17:50 +08:00
|
|
|
|
private Sprite clearAnimation = null!;
|
2025-02-12 20:19:55 +08:00
|
|
|
|
private SkinnableSound clearSample = null!;
|
2025-01-31 19:55:29 +08:00
|
|
|
|
private LegacySpriteText remainingHitsText = null!;
|
2022-12-11 09:17:50 +08:00
|
|
|
|
|
|
|
|
|
private bool samplePlayed;
|
|
|
|
|
|
2025-02-12 18:20:27 +08:00
|
|
|
|
private int numHits;
|
|
|
|
|
|
2022-12-11 09:17:50 +08:00
|
|
|
|
public LegacySwell()
|
|
|
|
|
{
|
|
|
|
|
Anchor = Anchor.Centre;
|
|
|
|
|
Origin = Anchor.Centre;
|
|
|
|
|
RelativeSizeAxes = Axes.Both;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[BackgroundDependencyLoader]
|
2025-02-11 22:20:36 +08:00
|
|
|
|
private void load(DrawableHitObject hitObject, ISkinSource skin)
|
2022-12-11 09:17:50 +08:00
|
|
|
|
{
|
2025-02-01 13:34:52 +08:00
|
|
|
|
Children = new Drawable[]
|
2022-12-11 09:17:50 +08:00
|
|
|
|
{
|
2025-02-01 13:34:52 +08:00
|
|
|
|
warning = new Sprite
|
2022-12-11 09:17:50 +08:00
|
|
|
|
{
|
2025-02-01 13:34:52 +08:00
|
|
|
|
Texture = skin.GetTexture("spinner-warning"),
|
|
|
|
|
Anchor = Anchor.Centre,
|
|
|
|
|
Origin = Anchor.Centre,
|
|
|
|
|
Scale = skin.GetTexture("spinner-warning") != null ? Vector2.One : new Vector2(0.18f),
|
|
|
|
|
},
|
|
|
|
|
new Container
|
|
|
|
|
{
|
|
|
|
|
Anchor = Anchor.Centre,
|
|
|
|
|
Origin = Anchor.Centre,
|
2025-02-12 18:30:30 +08:00
|
|
|
|
Position = swell_display_position, // ballparked to be horizontally centred on 4:3 resolution
|
2022-12-11 09:17:50 +08:00
|
|
|
|
|
2025-02-01 13:34:52 +08:00
|
|
|
|
Children = new Drawable[]
|
|
|
|
|
{
|
|
|
|
|
bodyContainer = new Container
|
2022-12-11 09:17:50 +08:00
|
|
|
|
{
|
2025-02-01 13:34:52 +08:00
|
|
|
|
Anchor = Anchor.Centre,
|
|
|
|
|
Origin = Anchor.Centre,
|
|
|
|
|
Alpha = 0,
|
|
|
|
|
|
|
|
|
|
Children = new Drawable[]
|
2025-01-31 16:55:39 +08:00
|
|
|
|
{
|
2025-02-01 13:34:52 +08:00
|
|
|
|
spinnerCircle = new Sprite
|
|
|
|
|
{
|
|
|
|
|
Texture = skin.GetTexture("spinner-circle"),
|
|
|
|
|
Anchor = Anchor.Centre,
|
|
|
|
|
Origin = Anchor.Centre,
|
|
|
|
|
Scale = new Vector2(0.8f),
|
|
|
|
|
},
|
|
|
|
|
approachCircle = new Sprite
|
|
|
|
|
{
|
|
|
|
|
Texture = skin.GetTexture("spinner-approachcircle"),
|
|
|
|
|
Anchor = Anchor.Centre,
|
|
|
|
|
Origin = Anchor.Centre,
|
|
|
|
|
Scale = new Vector2(1.86f * 0.8f),
|
2025-02-12 17:55:57 +08:00
|
|
|
|
Alpha = 0.8f,
|
2025-02-01 13:34:52 +08:00
|
|
|
|
},
|
2025-02-12 17:55:57 +08:00
|
|
|
|
remainingHitsText = new LegacySpriteText(LegacyFont.Score)
|
2025-02-01 13:34:52 +08:00
|
|
|
|
{
|
|
|
|
|
Anchor = Anchor.Centre,
|
|
|
|
|
Origin = Anchor.Centre,
|
2025-02-12 17:55:57 +08:00
|
|
|
|
Position = new Vector2(0f, 130f),
|
2025-02-01 13:34:52 +08:00
|
|
|
|
Scale = Vector2.One,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
clearAnimation = new Sprite
|
|
|
|
|
{
|
|
|
|
|
Texture = skin.GetTexture("spinner-osu"),
|
|
|
|
|
Anchor = Anchor.Centre,
|
|
|
|
|
Origin = Anchor.Centre,
|
|
|
|
|
Alpha = 0,
|
2025-02-12 17:55:57 +08:00
|
|
|
|
Y = -40,
|
2025-02-01 13:34:52 +08:00
|
|
|
|
},
|
2022-12-11 09:17:50 +08:00
|
|
|
|
},
|
2025-02-01 13:34:52 +08:00
|
|
|
|
},
|
2025-02-12 20:19:55 +08:00
|
|
|
|
clearSample = new SkinnableSound(new SampleInfo("spinner-osu")),
|
2022-12-11 09:17:50 +08:00
|
|
|
|
};
|
|
|
|
|
|
2025-01-31 17:51:35 +08:00
|
|
|
|
drawableSwell = (DrawableSwell)hitObject;
|
|
|
|
|
drawableSwell.UpdateHitProgress += animateSwellProgress;
|
|
|
|
|
drawableSwell.ApplyCustomUpdateState += updateStateTransforms;
|
2022-12-11 09:17:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-02-12 18:20:27 +08:00
|
|
|
|
private void animateSwellProgress(int numHits)
|
|
|
|
|
{
|
|
|
|
|
this.numHits = numHits;
|
|
|
|
|
remainingHitsText.Text = (drawableSwell.HitObject.RequiredHits - numHits).ToString(CultureInfo.InvariantCulture);
|
|
|
|
|
spinnerCircle.Scale = new Vector2(Math.Min(0.94f, spinnerCircle.Scale.X + 0.02f));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void Update()
|
2022-12-11 09:17:50 +08:00
|
|
|
|
{
|
2025-02-12 18:20:27 +08:00
|
|
|
|
base.Update();
|
|
|
|
|
|
|
|
|
|
int requiredHits = drawableSwell.HitObject.RequiredHits;
|
2025-02-11 21:01:32 +08:00
|
|
|
|
int remainingHits = requiredHits - numHits;
|
2025-02-12 18:20:27 +08:00
|
|
|
|
remainingHitsText.Scale = new Vector2((float)Interpolation.DampContinuously(
|
|
|
|
|
remainingHitsText.Scale.X, 1.6f - (0.6f * ((float)remainingHits / requiredHits)), 17.5, Math.Abs(Time.Elapsed)));
|
|
|
|
|
|
|
|
|
|
spinnerCircle.Rotation = (float)Interpolation.DampContinuously(spinnerCircle.Rotation, 180f * numHits, 130, Math.Abs(Time.Elapsed));
|
|
|
|
|
spinnerCircle.Scale = new Vector2((float)Interpolation.DampContinuously(
|
|
|
|
|
spinnerCircle.Scale.X, 0.8f, 120, Math.Abs(Time.Elapsed)));
|
2022-12-11 09:17:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-01-31 17:51:35 +08:00
|
|
|
|
private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state)
|
2022-12-11 09:17:50 +08:00
|
|
|
|
{
|
2025-01-31 20:48:29 +08:00
|
|
|
|
if (!(drawableHitObject is DrawableSwell))
|
2025-01-31 17:51:35 +08:00
|
|
|
|
return;
|
2022-12-11 09:17:50 +08:00
|
|
|
|
|
2025-01-31 17:51:35 +08:00
|
|
|
|
Swell swell = drawableSwell.HitObject;
|
2022-12-11 09:17:50 +08:00
|
|
|
|
|
2025-01-31 17:51:35 +08:00
|
|
|
|
using (BeginAbsoluteSequence(swell.StartTime))
|
2022-12-11 09:17:50 +08:00
|
|
|
|
{
|
2025-01-31 17:51:35 +08:00
|
|
|
|
if (state == ArmedState.Idle)
|
2022-12-11 09:17:50 +08:00
|
|
|
|
{
|
2025-01-31 19:55:29 +08:00
|
|
|
|
remainingHitsText.Text = $"{swell.RequiredHits}";
|
2025-01-31 17:51:35 +08:00
|
|
|
|
samplePlayed = false;
|
2022-12-11 09:17:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-02-11 22:20:36 +08:00
|
|
|
|
const double body_transition_duration = 200;
|
2025-01-31 17:51:35 +08:00
|
|
|
|
|
2025-02-12 18:30:30 +08:00
|
|
|
|
warning.MoveTo(swell_display_position, body_transition_duration)
|
|
|
|
|
.ScaleTo(3, body_transition_duration, Easing.Out)
|
|
|
|
|
.FadeOut(body_transition_duration);
|
|
|
|
|
|
2025-01-31 17:51:35 +08:00
|
|
|
|
bodyContainer.FadeIn(body_transition_duration);
|
2025-01-31 19:55:29 +08:00
|
|
|
|
approachCircle.ResizeTo(0.1f * 0.8f, swell.Duration);
|
2022-12-11 09:17:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-01-31 17:51:35 +08:00
|
|
|
|
using (BeginAbsoluteSequence(drawableSwell.HitStateUpdateTime))
|
2022-12-11 09:17:50 +08:00
|
|
|
|
{
|
2025-01-31 17:51:35 +08:00
|
|
|
|
const double clear_transition_duration = 300;
|
2025-01-31 19:55:29 +08:00
|
|
|
|
const double clear_fade_in = 120;
|
2025-01-31 17:51:35 +08:00
|
|
|
|
|
2025-02-11 22:20:36 +08:00
|
|
|
|
bodyContainer.FadeOut(clear_transition_duration, Easing.OutQuad);
|
|
|
|
|
spinnerCircle.ScaleTo(spinnerCircle.Scale.X + 0.05f, clear_transition_duration, Easing.OutQuad);
|
2025-01-31 17:51:35 +08:00
|
|
|
|
|
|
|
|
|
if (state == ArmedState.Hit)
|
|
|
|
|
{
|
|
|
|
|
if (!samplePlayed)
|
|
|
|
|
{
|
2025-02-12 20:19:55 +08:00
|
|
|
|
clearSample.Play();
|
2025-01-31 17:51:35 +08:00
|
|
|
|
samplePlayed = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
clearAnimation
|
2025-02-12 17:55:57 +08:00
|
|
|
|
.MoveToOffset(new Vector2(0, -90 * scale_adjust), clear_fade_in * 2, Easing.Out)
|
2025-01-31 19:55:29 +08:00
|
|
|
|
.ScaleTo(0.4f)
|
|
|
|
|
.ScaleTo(1f, clear_fade_in * 2, Easing.Out)
|
2025-02-12 17:55:57 +08:00
|
|
|
|
.FadeIn()
|
2025-01-31 19:55:29 +08:00
|
|
|
|
.Delay(clear_fade_in * 3)
|
|
|
|
|
.FadeOut(clear_fade_in * 2.5);
|
2025-01-31 17:51:35 +08:00
|
|
|
|
}
|
2022-12-11 09:17:50 +08:00
|
|
|
|
}
|
2025-01-31 17:51:35 +08:00
|
|
|
|
}
|
2022-12-11 09:17:50 +08:00
|
|
|
|
|
2025-01-31 17:51:35 +08:00
|
|
|
|
protected override void Dispose(bool isDisposing)
|
|
|
|
|
{
|
|
|
|
|
base.Dispose(isDisposing);
|
2022-12-11 09:17:50 +08:00
|
|
|
|
|
2025-01-31 17:51:35 +08:00
|
|
|
|
if (drawableSwell.IsNotNull())
|
|
|
|
|
{
|
|
|
|
|
drawableSwell.UpdateHitProgress -= animateSwellProgress;
|
|
|
|
|
drawableSwell.ApplyCustomUpdateState -= updateStateTransforms;
|
|
|
|
|
}
|
2022-12-11 09:17:50 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|