mirror of
https://github.com/ppy/osu.git
synced 2024-11-06 09:47:52 +08:00
Merge pull request #10890 from peppy/legacy-jugement-match-stable-transforms
Adjust judgement animations to match stable
This commit is contained in:
commit
4213d6bdba
@ -24,7 +24,10 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
|||||||
if (hitWindows.IsHitResultAllowed(result))
|
if (hitWindows.IsHitResultAllowed(result))
|
||||||
{
|
{
|
||||||
AddStep("Show " + result.GetDescription(), () => SetContents(() =>
|
AddStep("Show " + result.GetDescription(), () => SetContents(() =>
|
||||||
new DrawableManiaJudgement(new JudgementResult(new HitObject(), new Judgement()) { Type = result }, null)
|
new DrawableManiaJudgement(new JudgementResult(new HitObject { StartTime = Time.Current }, new Judgement())
|
||||||
|
{
|
||||||
|
Type = result
|
||||||
|
}, null)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
|
@ -5,6 +5,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.UI
|
namespace osu.Game.Rulesets.Mania.UI
|
||||||
{
|
{
|
||||||
@ -19,22 +20,42 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override double FadeInDuration => 50;
|
protected override void ApplyMissAnimations()
|
||||||
|
{
|
||||||
|
if (!(JudgementBody.Drawable is DefaultManiaJudgementPiece))
|
||||||
|
{
|
||||||
|
// this is temporary logic until mania's skin transformer returns IAnimatableJudgements
|
||||||
|
JudgementBody.ScaleTo(1.6f);
|
||||||
|
JudgementBody.ScaleTo(1, 100, Easing.In);
|
||||||
|
|
||||||
|
JudgementBody.MoveTo(Vector2.Zero);
|
||||||
|
JudgementBody.MoveToOffset(new Vector2(0, 100), 800, Easing.InQuint);
|
||||||
|
|
||||||
|
JudgementBody.RotateTo(0);
|
||||||
|
JudgementBody.RotateTo(40, 800, Easing.InQuint);
|
||||||
|
JudgementBody.FadeOutFromOne(800);
|
||||||
|
|
||||||
|
LifetimeEnd = JudgementBody.LatestTransformEndTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
base.ApplyMissAnimations();
|
||||||
|
}
|
||||||
|
|
||||||
protected override void ApplyHitAnimations()
|
protected override void ApplyHitAnimations()
|
||||||
{
|
{
|
||||||
JudgementBody.ScaleTo(0.8f);
|
JudgementBody.ScaleTo(0.8f);
|
||||||
JudgementBody.ScaleTo(1, 250, Easing.OutElastic);
|
JudgementBody.ScaleTo(1, 250, Easing.OutElastic);
|
||||||
|
|
||||||
JudgementBody.Delay(FadeInDuration).ScaleTo(0.75f, 250);
|
JudgementBody.Delay(50)
|
||||||
this.Delay(FadeInDuration).FadeOut(200);
|
.ScaleTo(0.75f, 250)
|
||||||
|
.FadeOut(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Drawable CreateDefaultJudgement(HitResult result) => new ManiaJudgementPiece(result);
|
protected override Drawable CreateDefaultJudgement(HitResult result) => new DefaultManiaJudgementPiece(result);
|
||||||
|
|
||||||
private class ManiaJudgementPiece : DefaultJudgementPiece
|
private class DefaultManiaJudgementPiece : DefaultJudgementPiece
|
||||||
{
|
{
|
||||||
public ManiaJudgementPiece(HitResult result)
|
public DefaultManiaJudgementPiece(HitResult result)
|
||||||
: base(result)
|
: base(result)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -43,10 +43,8 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
showResult(HitResult.Great);
|
showResult(HitResult.Great);
|
||||||
|
|
||||||
AddUntilStep("judgements shown", () => this.ChildrenOfType<TestDrawableOsuJudgement>().Any());
|
AddUntilStep("judgements shown", () => this.ChildrenOfType<TestDrawableOsuJudgement>().Any());
|
||||||
AddAssert("judgement body immediately visible",
|
AddAssert("hit lighting has no transforms", () => this.ChildrenOfType<TestDrawableOsuJudgement>().All(judgement => !judgement.Lighting.Transforms.Any()));
|
||||||
() => this.ChildrenOfType<TestDrawableOsuJudgement>().All(judgement => judgement.JudgementBody.Alpha == 1));
|
AddAssert("hit lighting hidden", () => this.ChildrenOfType<TestDrawableOsuJudgement>().All(judgement => judgement.Lighting.Alpha == 0));
|
||||||
AddAssert("hit lighting hidden",
|
|
||||||
() => this.ChildrenOfType<TestDrawableOsuJudgement>().All(judgement => judgement.Lighting.Alpha == 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -57,10 +55,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
showResult(HitResult.Great);
|
showResult(HitResult.Great);
|
||||||
|
|
||||||
AddUntilStep("judgements shown", () => this.ChildrenOfType<TestDrawableOsuJudgement>().Any());
|
AddUntilStep("judgements shown", () => this.ChildrenOfType<TestDrawableOsuJudgement>().Any());
|
||||||
AddAssert("judgement body not immediately visible",
|
AddUntilStep("hit lighting shown", () => this.ChildrenOfType<TestDrawableOsuJudgement>().Any(judgement => judgement.Lighting.Alpha > 0));
|
||||||
() => this.ChildrenOfType<TestDrawableOsuJudgement>().All(judgement => judgement.JudgementBody.Alpha > 0 && judgement.JudgementBody.Alpha < 1));
|
|
||||||
AddAssert("hit lighting shown",
|
|
||||||
() => this.ChildrenOfType<TestDrawableOsuJudgement>().All(judgement => judgement.Lighting.Alpha > 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showResult(HitResult result)
|
private void showResult(HitResult result)
|
||||||
@ -89,7 +84,13 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
pool,
|
pool,
|
||||||
pool.Get(j => j.Apply(new JudgementResult(new HitObject(), new Judgement()) { Type = result }, null)).With(j =>
|
pool.Get(j => j.Apply(new JudgementResult(new HitObject
|
||||||
|
{
|
||||||
|
StartTime = Time.Current
|
||||||
|
}, new Judgement())
|
||||||
|
{
|
||||||
|
Type = result,
|
||||||
|
}, null)).With(j =>
|
||||||
{
|
{
|
||||||
j.Anchor = Anchor.Centre;
|
j.Anchor = Anchor.Centre;
|
||||||
j.Origin = Anchor.Centre;
|
j.Origin = Anchor.Centre;
|
||||||
@ -106,7 +107,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
private class TestDrawableOsuJudgement : DrawableOsuJudgement
|
private class TestDrawableOsuJudgement : DrawableOsuJudgement
|
||||||
{
|
{
|
||||||
public new SkinnableSprite Lighting => base.Lighting;
|
public new SkinnableSprite Lighting => base.Lighting;
|
||||||
public new Container JudgementBody => base.JudgementBody;
|
public new SkinnableDrawable JudgementBody => base.JudgementBody;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,26 +44,21 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private double fadeOutDelay;
|
|
||||||
protected override double FadeOutDelay => fadeOutDelay;
|
|
||||||
|
|
||||||
protected override void ApplyHitAnimations()
|
protected override void ApplyHitAnimations()
|
||||||
{
|
{
|
||||||
bool hitLightingEnabled = config.Get<bool>(OsuSetting.HitLighting);
|
bool hitLightingEnabled = config.Get<bool>(OsuSetting.HitLighting);
|
||||||
|
|
||||||
if (hitLightingEnabled)
|
Lighting.Alpha = 0;
|
||||||
{
|
|
||||||
JudgementBody.FadeIn().Delay(FadeInDuration).FadeOut(400);
|
|
||||||
|
|
||||||
|
if (hitLightingEnabled && Lighting.Drawable != null)
|
||||||
|
{
|
||||||
|
// todo: this animation changes slightly based on new/old legacy skin versions.
|
||||||
Lighting.ScaleTo(0.8f).ScaleTo(1.2f, 600, Easing.Out);
|
Lighting.ScaleTo(0.8f).ScaleTo(1.2f, 600, Easing.Out);
|
||||||
Lighting.FadeIn(200).Then().Delay(200).FadeOut(1000);
|
Lighting.FadeIn(200).Then().Delay(200).FadeOut(1000);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
JudgementBody.Alpha = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fadeOutDelay = hitLightingEnabled ? 1400 : base.FadeOutDelay;
|
// extend the lifetime to cover lighting fade
|
||||||
|
LifetimeEnd = Lighting.LatestTransformEndTime;
|
||||||
|
}
|
||||||
|
|
||||||
base.ApplyHitAnimations();
|
base.ApplyHitAnimations();
|
||||||
}
|
}
|
||||||
|
@ -47,18 +47,18 @@ namespace osu.Game.Rulesets.Judgements
|
|||||||
|
|
||||||
public virtual void PlayAnimation()
|
public virtual void PlayAnimation()
|
||||||
{
|
{
|
||||||
this.RotateTo(0);
|
|
||||||
this.MoveTo(Vector2.Zero);
|
|
||||||
|
|
||||||
switch (Result)
|
switch (Result)
|
||||||
{
|
{
|
||||||
case HitResult.Miss:
|
case HitResult.Miss:
|
||||||
this.ScaleTo(1.6f);
|
this.ScaleTo(1.6f);
|
||||||
this.ScaleTo(1, 100, Easing.In);
|
this.ScaleTo(1, 100, Easing.In);
|
||||||
|
|
||||||
|
this.MoveTo(Vector2.Zero);
|
||||||
this.MoveToOffset(new Vector2(0, 100), 800, Easing.InQuint);
|
this.MoveToOffset(new Vector2(0, 100), 800, Easing.InQuint);
|
||||||
|
|
||||||
|
this.RotateTo(0);
|
||||||
this.RotateTo(40, 800, Easing.InQuint);
|
this.RotateTo(40, 800, Easing.InQuint);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -66,6 +66,8 @@ namespace osu.Game.Rulesets.Judgements
|
|||||||
this.ScaleTo(1, 500, Easing.OutElastic);
|
this.ScaleTo(1, 500, Easing.OutElastic);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.FadeOutFromOne(800);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Framework.Graphics.Pooling;
|
using osu.Framework.Graphics.Pooling;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
@ -25,18 +25,23 @@ namespace osu.Game.Rulesets.Judgements
|
|||||||
|
|
||||||
public DrawableHitObject JudgedObject { get; private set; }
|
public DrawableHitObject JudgedObject { get; private set; }
|
||||||
|
|
||||||
protected Container JudgementBody { get; private set; }
|
public override bool RemoveCompletedTransforms => false;
|
||||||
|
|
||||||
private SkinnableDrawable skinnableJudgement;
|
protected SkinnableDrawable JudgementBody { get; private set; }
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private ISkinSource skinSource { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Duration of initial fade in.
|
/// Duration of initial fade in.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[Obsolete("Apply any animations manually via ApplyHitAnimations / ApplyMissAnimations. Defaults were moved inside skinned components.")]
|
||||||
protected virtual double FadeInDuration => 100;
|
protected virtual double FadeInDuration => 100;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Duration to wait until fade out begins. Defaults to <see cref="FadeInDuration"/>.
|
/// Duration to wait until fade out begins. Defaults to <see cref="FadeInDuration"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[Obsolete("Apply any animations manually via ApplyHitAnimations / ApplyMissAnimations. Defaults were moved inside skinned components.")]
|
||||||
protected virtual double FadeOutDelay => FadeInDuration;
|
protected virtual double FadeOutDelay => FadeInDuration;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -62,10 +67,32 @@ namespace osu.Game.Rulesets.Judgements
|
|||||||
prepareDrawables();
|
prepareDrawables();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
skinSource.SourceChanged += onSkinChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onSkinChanged()
|
||||||
|
{
|
||||||
|
// on a skin change, the child component will update but not get correctly triggered to play its animation.
|
||||||
|
// we need to trigger a reinitialisation to make things right.
|
||||||
|
currentDrawableType = null;
|
||||||
|
|
||||||
|
PrepareForUse();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
base.Dispose(isDisposing);
|
||||||
|
|
||||||
|
if (skinSource != null)
|
||||||
|
skinSource.SourceChanged -= onSkinChanged;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Apply top-level animations to the current judgement when successfully hit.
|
/// Apply top-level animations to the current judgement when successfully hit.
|
||||||
/// Generally used for fading, defaulting to a simple fade out based on <see cref="FadeOutDelay"/>.
|
/// If displaying components which require lifetime extensions, manually adjusting <see cref="Drawable.LifetimeEnd"/> is required.
|
||||||
/// This will be used to calculate the lifetime of the judgement.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// For animating the actual "default skin" judgement itself, it is recommended to use <see cref="CreateDefaultJudgement"/>.
|
/// For animating the actual "default skin" judgement itself, it is recommended to use <see cref="CreateDefaultJudgement"/>.
|
||||||
@ -73,13 +100,11 @@ namespace osu.Game.Rulesets.Judgements
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
protected virtual void ApplyHitAnimations()
|
protected virtual void ApplyHitAnimations()
|
||||||
{
|
{
|
||||||
this.Delay(FadeOutDelay).FadeOut(400);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Apply top-level animations to the current judgement when missed.
|
/// Apply top-level animations to the current judgement when missed.
|
||||||
/// Generally used for fading, defaulting to a simple fade out based on <see cref="FadeOutDelay"/>.
|
/// If displaying components which require lifetime extensions, manually adjusting <see cref="Drawable.LifetimeEnd"/> is required.
|
||||||
/// This will be used to calculate the lifetime of the judgement.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// For animating the actual "default skin" judgement itself, it is recommended to use <see cref="CreateDefaultJudgement"/>.
|
/// For animating the actual "default skin" judgement itself, it is recommended to use <see cref="CreateDefaultJudgement"/>.
|
||||||
@ -87,7 +112,6 @@ namespace osu.Game.Rulesets.Judgements
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
protected virtual void ApplyMissAnimations()
|
protected virtual void ApplyMissAnimations()
|
||||||
{
|
{
|
||||||
this.Delay(600).FadeOut(200);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -109,32 +133,46 @@ namespace osu.Game.Rulesets.Judgements
|
|||||||
|
|
||||||
prepareDrawables();
|
prepareDrawables();
|
||||||
|
|
||||||
// not sure if this should remain going forward.
|
runAnimation();
|
||||||
skinnableJudgement.ResetAnimation();
|
}
|
||||||
|
|
||||||
this.FadeInFromZero(FadeInDuration, Easing.OutQuint);
|
private void runAnimation()
|
||||||
|
{
|
||||||
|
ClearTransforms(true);
|
||||||
|
LifetimeStart = Result.TimeAbsolute;
|
||||||
|
|
||||||
switch (Result.Type)
|
using (BeginAbsoluteSequence(Result.TimeAbsolute, true))
|
||||||
{
|
{
|
||||||
case HitResult.None:
|
// not sure if this should remain going forward.
|
||||||
break;
|
JudgementBody.ResetAnimation();
|
||||||
|
|
||||||
case HitResult.Miss:
|
switch (Result.Type)
|
||||||
ApplyMissAnimations();
|
{
|
||||||
break;
|
case HitResult.None:
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
case HitResult.Miss:
|
||||||
ApplyHitAnimations();
|
ApplyMissAnimations();
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
default:
|
||||||
|
ApplyHitAnimations();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (JudgementBody.Drawable is IAnimatableJudgement animatable)
|
||||||
|
{
|
||||||
|
var drawableAnimation = (Drawable)animatable;
|
||||||
|
|
||||||
if (skinnableJudgement.Drawable is IAnimatableJudgement animatable)
|
|
||||||
{
|
|
||||||
using (BeginAbsoluteSequence(Result.TimeAbsolute))
|
|
||||||
animatable.PlayAnimation();
|
animatable.PlayAnimation();
|
||||||
}
|
|
||||||
|
|
||||||
Expire(true);
|
// a derived version of DrawableJudgement may be proposing a lifetime.
|
||||||
|
// if not adjusted (or the skinned portion requires greater bounds than calculated) use the skinned source's lifetime.
|
||||||
|
double lastTransformTime = drawableAnimation.LatestTransformEndTime;
|
||||||
|
if (LifetimeEnd == double.MaxValue || lastTransformTime > LifetimeEnd)
|
||||||
|
LifetimeEnd = lastTransformTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private HitResult? currentDrawableType;
|
private HitResult? currentDrawableType;
|
||||||
@ -151,13 +189,11 @@ namespace osu.Game.Rulesets.Judgements
|
|||||||
if (JudgementBody != null)
|
if (JudgementBody != null)
|
||||||
RemoveInternal(JudgementBody);
|
RemoveInternal(JudgementBody);
|
||||||
|
|
||||||
AddInternal(JudgementBody = new Container
|
AddInternal(JudgementBody = new SkinnableDrawable(new GameplaySkinComponent<HitResult>(type), _ =>
|
||||||
|
CreateDefaultJudgement(type), confineMode: ConfineMode.NoScaling)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Child = skinnableJudgement = new SkinnableDrawable(new GameplaySkinComponent<HitResult>(type), _ =>
|
|
||||||
CreateDefaultJudgement(type), confineMode: ConfineMode.NoScaling)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
currentDrawableType = type;
|
currentDrawableType = type;
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Judgements
|
namespace osu.Game.Rulesets.Judgements
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A skinnable judgement element which supports playing an animation from the current point in time.
|
/// A skinnable judgement element which supports playing an animation from the current point in time.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IAnimatableJudgement
|
public interface IAnimatableJudgement : IDrawable
|
||||||
{
|
{
|
||||||
void PlayAnimation();
|
void PlayAnimation();
|
||||||
}
|
}
|
||||||
|
@ -1,58 +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.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.Animations;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Game.Rulesets.Judgements;
|
|
||||||
using osu.Game.Rulesets.Scoring;
|
|
||||||
using osuTK;
|
|
||||||
|
|
||||||
namespace osu.Game.Skinning
|
|
||||||
{
|
|
||||||
public class LegacyJudgementPiece : CompositeDrawable, IAnimatableJudgement
|
|
||||||
{
|
|
||||||
private readonly HitResult result;
|
|
||||||
|
|
||||||
public LegacyJudgementPiece(HitResult result, Drawable drawable)
|
|
||||||
{
|
|
||||||
this.result = result;
|
|
||||||
|
|
||||||
AutoSizeAxes = Axes.Both;
|
|
||||||
Origin = Anchor.Centre;
|
|
||||||
|
|
||||||
InternalChild = drawable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void PlayAnimation()
|
|
||||||
{
|
|
||||||
var animation = InternalChild as IFramedAnimation;
|
|
||||||
|
|
||||||
animation?.GotoFrame(0);
|
|
||||||
|
|
||||||
this.RotateTo(0);
|
|
||||||
this.MoveTo(Vector2.Zero);
|
|
||||||
|
|
||||||
// legacy judgements don't play any transforms if they are an animation.
|
|
||||||
if (animation?.FrameCount > 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (result)
|
|
||||||
{
|
|
||||||
case HitResult.Miss:
|
|
||||||
this.ScaleTo(1.6f);
|
|
||||||
this.ScaleTo(1, 100, Easing.In);
|
|
||||||
|
|
||||||
this.MoveToOffset(new Vector2(0, 100), 800, Easing.InQuint);
|
|
||||||
|
|
||||||
this.RotateTo(40, 800, Easing.InQuint);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
this.ScaleTo(0.9f);
|
|
||||||
this.ScaleTo(1, 500, Easing.OutElastic);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
103
osu.Game/Skinning/LegacyJudgementPieceNew.cs
Normal file
103
osu.Game/Skinning/LegacyJudgementPieceNew.cs
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
// 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.Graphics;
|
||||||
|
using osu.Framework.Graphics.Animations;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Utils;
|
||||||
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Skinning
|
||||||
|
{
|
||||||
|
public class LegacyJudgementPieceNew : CompositeDrawable, IAnimatableJudgement
|
||||||
|
{
|
||||||
|
private readonly HitResult result;
|
||||||
|
|
||||||
|
private readonly LegacyJudgementPieceOld temporaryOldStyle;
|
||||||
|
|
||||||
|
private readonly Drawable mainPiece;
|
||||||
|
|
||||||
|
public LegacyJudgementPieceNew(HitResult result, Func<Drawable> createMainDrawable, Func<Drawable> createParticleDrawable)
|
||||||
|
{
|
||||||
|
this.result = result;
|
||||||
|
|
||||||
|
AutoSizeAxes = Axes.Both;
|
||||||
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
|
InternalChildren = new[]
|
||||||
|
{
|
||||||
|
mainPiece = createMainDrawable().With(d =>
|
||||||
|
{
|
||||||
|
d.Anchor = Anchor.Centre;
|
||||||
|
d.Origin = Anchor.Centre;
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
if (result != HitResult.Miss)
|
||||||
|
{
|
||||||
|
//new judgement shows old as a temporary effect
|
||||||
|
AddInternal(temporaryOldStyle = new LegacyJudgementPieceOld(result, createMainDrawable, 1.05f)
|
||||||
|
{
|
||||||
|
Blending = BlendingParameters.Additive,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PlayAnimation()
|
||||||
|
{
|
||||||
|
var animation = mainPiece as IFramedAnimation;
|
||||||
|
|
||||||
|
animation?.GotoFrame(0);
|
||||||
|
|
||||||
|
const double fade_in_length = 120;
|
||||||
|
const double fade_out_delay = 500;
|
||||||
|
const double fade_out_length = 600;
|
||||||
|
|
||||||
|
this.FadeInFromZero(fade_in_length);
|
||||||
|
this.Delay(fade_out_delay).FadeOut(fade_out_length);
|
||||||
|
|
||||||
|
// new style non-miss judgements show the original style temporarily, with additive colour.
|
||||||
|
if (temporaryOldStyle != null)
|
||||||
|
{
|
||||||
|
temporaryOldStyle.PlayAnimation();
|
||||||
|
|
||||||
|
temporaryOldStyle.Hide();
|
||||||
|
temporaryOldStyle.Delay(-16)
|
||||||
|
.FadeTo(0.5f, 56, Easing.Out).Then()
|
||||||
|
.FadeOut(300);
|
||||||
|
}
|
||||||
|
|
||||||
|
// legacy judgements don't play any transforms if they are an animation.
|
||||||
|
if (animation?.FrameCount > 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case HitResult.Miss:
|
||||||
|
this.ScaleTo(1.6f);
|
||||||
|
this.ScaleTo(1, 100, Easing.In);
|
||||||
|
|
||||||
|
//todo: this only applies to osu! ruleset apparently.
|
||||||
|
this.MoveTo(new Vector2(0, -2));
|
||||||
|
this.MoveToOffset(new Vector2(0, 20), fade_out_delay + fade_out_length, Easing.In);
|
||||||
|
|
||||||
|
float rotation = RNG.NextSingle(-8.6f, 8.6f);
|
||||||
|
|
||||||
|
this.RotateTo(0);
|
||||||
|
this.RotateTo(rotation, fade_in_length)
|
||||||
|
.Then().RotateTo(rotation * 2, fade_out_delay + fade_out_length - fade_in_length, Easing.In);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
mainPiece.ScaleTo(0.9f);
|
||||||
|
mainPiece.ScaleTo(1.05f, fade_out_delay + fade_out_length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
73
osu.Game/Skinning/LegacyJudgementPieceOld.cs
Normal file
73
osu.Game/Skinning/LegacyJudgementPieceOld.cs
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// 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.Graphics;
|
||||||
|
using osu.Framework.Graphics.Animations;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Utils;
|
||||||
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
|
namespace osu.Game.Skinning
|
||||||
|
{
|
||||||
|
public class LegacyJudgementPieceOld : CompositeDrawable, IAnimatableJudgement
|
||||||
|
{
|
||||||
|
private readonly HitResult result;
|
||||||
|
|
||||||
|
private readonly float finalScale;
|
||||||
|
|
||||||
|
public LegacyJudgementPieceOld(HitResult result, Func<Drawable> createMainDrawable, float finalScale = 1f)
|
||||||
|
{
|
||||||
|
this.result = result;
|
||||||
|
this.finalScale = finalScale;
|
||||||
|
|
||||||
|
AutoSizeAxes = Axes.Both;
|
||||||
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
|
InternalChild = createMainDrawable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void PlayAnimation()
|
||||||
|
{
|
||||||
|
var animation = InternalChild as IFramedAnimation;
|
||||||
|
|
||||||
|
animation?.GotoFrame(0);
|
||||||
|
|
||||||
|
const double fade_in_length = 120;
|
||||||
|
const double fade_out_delay = 500;
|
||||||
|
const double fade_out_length = 600;
|
||||||
|
|
||||||
|
this.FadeInFromZero(fade_in_length);
|
||||||
|
this.Delay(fade_out_delay).FadeOut(fade_out_length);
|
||||||
|
|
||||||
|
// legacy judgements don't play any transforms if they are an animation.
|
||||||
|
if (animation?.FrameCount > 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case HitResult.Miss:
|
||||||
|
this.ScaleTo(1.6f);
|
||||||
|
this.ScaleTo(1, 100, Easing.In);
|
||||||
|
|
||||||
|
float rotation = RNG.NextSingle(-8.6f, 8.6f);
|
||||||
|
|
||||||
|
this.RotateTo(0);
|
||||||
|
this.RotateTo(rotation, fade_in_length)
|
||||||
|
.Then().RotateTo(rotation * 2, fade_out_delay + fade_out_length - fade_in_length, Easing.In);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
this.ScaleTo(0.6f).Then()
|
||||||
|
.ScaleTo(1.1f, fade_in_length * 0.8f).Then()
|
||||||
|
// this is actually correct to match stable; there were overlapping transforms.
|
||||||
|
.ScaleTo(0.9f).Delay(fade_in_length * 0.2f)
|
||||||
|
.ScaleTo(1.1f).ScaleTo(0.9f, fade_in_length * 0.2f).Then()
|
||||||
|
.ScaleTo(0.95f).ScaleTo(finalScale, fade_in_length * 0.2f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -371,9 +371,16 @@ namespace osu.Game.Skinning
|
|||||||
}
|
}
|
||||||
|
|
||||||
case GameplaySkinComponent<HitResult> resultComponent:
|
case GameplaySkinComponent<HitResult> resultComponent:
|
||||||
var drawable = getJudgementAnimation(resultComponent.Component);
|
Func<Drawable> createDrawable = () => getJudgementAnimation(resultComponent.Component);
|
||||||
if (drawable != null)
|
|
||||||
return new LegacyJudgementPiece(resultComponent.Component, drawable);
|
// kind of wasteful that we throw this away, but should do for now.
|
||||||
|
if (createDrawable() != null)
|
||||||
|
{
|
||||||
|
if (Configuration.LegacyVersion > 1)
|
||||||
|
return new LegacyJudgementPieceNew(resultComponent.Component, createDrawable, () => getParticleDrawable(resultComponent.Component));
|
||||||
|
else
|
||||||
|
return new LegacyJudgementPieceOld(resultComponent.Component, createDrawable);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -381,6 +388,23 @@ namespace osu.Game.Skinning
|
|||||||
return this.GetAnimation(component.LookupName, false, false);
|
return this.GetAnimation(component.LookupName, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Drawable getParticleDrawable(HitResult result)
|
||||||
|
{
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case HitResult.Meh:
|
||||||
|
return this.GetAnimation("particle50", false, false);
|
||||||
|
|
||||||
|
case HitResult.Ok:
|
||||||
|
return this.GetAnimation("particle100", false, false);
|
||||||
|
|
||||||
|
case HitResult.Great:
|
||||||
|
return this.GetAnimation("particle300", false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private Drawable getJudgementAnimation(HitResult result)
|
private Drawable getJudgementAnimation(HitResult result)
|
||||||
{
|
{
|
||||||
switch (result)
|
switch (result)
|
||||||
|
Loading…
Reference in New Issue
Block a user