Add catcher kiai/fail animation states

This commit is contained in:
Dean Herbert 2020-03-10 15:26:39 +09:00
parent a6cf6207aa
commit 7069cef9ce
6 changed files with 134 additions and 14 deletions

View File

@ -10,9 +10,15 @@ using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Catch.Beatmaps;
using osu.Game.Rulesets.Catch.Judgements;
using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.Objects.Drawables; using osu.Game.Rulesets.Catch.Objects.Drawables;
using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
using osu.Game.Tests.Visual; using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests namespace osu.Game.Rulesets.Catch.Tests
@ -34,9 +40,41 @@ namespace osu.Game.Rulesets.Catch.Tests
CreatedDrawables.OfType<CatchInputManager>().Select(i => i.Child) CreatedDrawables.OfType<CatchInputManager>().Select(i => i.Child)
.OfType<TestCatcherArea>().ForEach(c => c.ToggleHyperDash(t))); .OfType<TestCatcherArea>().ForEach(c => c.ToggleHyperDash(t)));
AddRepeatStep("catch fruit", () => AddRepeatStep("catch fruit", () => catchFruit(new TestFruit(false)
this.ChildrenOfType<CatcherArea>().ForEach(area => {
area.MovableCatcher.PlaceOnPlate(new DrawableFruit(new TestSceneFruitObjects.TestCatchFruit(FruitVisualRepresentation.Grape)))), 20); X = this.ChildrenOfType<CatcherArea>().First().MovableCatcher.X
}), 20);
AddRepeatStep("catch fruit last in combo", () => catchFruit(new TestFruit(false)
{
X = this.ChildrenOfType<CatcherArea>().First().MovableCatcher.X,
LastInCombo = true,
}), 20);
AddRepeatStep("catch kiai fruit", () => catchFruit(new TestFruit(true)
{
X = this.ChildrenOfType<CatcherArea>().First().MovableCatcher.X,
}), 20);
AddRepeatStep("miss fruit", () => catchFruit(new Fruit
{
X = this.ChildrenOfType<CatcherArea>().First().MovableCatcher.X + 100,
LastInCombo = true,
}, true), 20);
}
private void catchFruit(Fruit fruit, bool miss = false)
{
this.ChildrenOfType<CatcherArea>().ForEach(area =>
{
DrawableFruit drawable = new DrawableFruit(fruit);
area.Add(drawable);
Schedule(() =>
{
area.AttemptCatch(fruit);
area.OnResult(drawable, new JudgementResult(fruit, new CatchJudgement()) { Type = miss ? HitResult.Miss : HitResult.Great });
drawable.Expire();
});
});
} }
private void createCatcher(float size) private void createCatcher(float size)
@ -47,7 +85,8 @@ namespace osu.Game.Rulesets.Catch.Tests
Child = new TestCatcherArea(new BeatmapDifficulty { CircleSize = size }) Child = new TestCatcherArea(new BeatmapDifficulty { CircleSize = size })
{ {
Anchor = Anchor.CentreLeft, Anchor = Anchor.CentreLeft,
Origin = Anchor.TopLeft Origin = Anchor.TopLeft,
CreateDrawableRepresentation = ((DrawableRuleset<CatchHitObject>)catchRuleset.CreateInstance().CreateDrawableRulesetWith(new CatchBeatmap())).CreateDrawableRepresentation
}, },
}); });
} }
@ -58,6 +97,17 @@ namespace osu.Game.Rulesets.Catch.Tests
catchRuleset = rulesets.GetRuleset(2); catchRuleset = rulesets.GetRuleset(2);
} }
public class TestFruit : Fruit
{
public TestFruit(bool kiai)
{
var kiaiCpi = new ControlPointInfo();
kiaiCpi.Add(0, new EffectControlPoint { KiaiMode = kiai });
ApplyDefaultsToSelf(kiaiCpi, new BeatmapDifficulty());
}
}
private class TestCatcherArea : CatcherArea private class TestCatcherArea : CatcherArea
{ {
public TestCatcherArea(BeatmapDifficulty beatmapDifficulty) public TestCatcherArea(BeatmapDifficulty beatmapDifficulty)

View File

@ -11,6 +11,8 @@ namespace osu.Game.Rulesets.Catch
FruitOrange, FruitOrange,
FruitPear, FruitPear,
Droplet, Droplet,
CatcherIdle CatcherIdle,
CatcherFail,
CatcherKiai
} }
} }

View File

@ -48,6 +48,14 @@ namespace osu.Game.Rulesets.Catch.Skinning
case CatchSkinComponents.CatcherIdle: case CatchSkinComponents.CatcherIdle:
return this.GetAnimation("fruit-catcher-idle", true, true, true) ?? return this.GetAnimation("fruit-catcher-idle", true, true, true) ??
this.GetAnimation("fruit-ryuuta", true, true, true); this.GetAnimation("fruit-ryuuta", true, true, true);
case CatchSkinComponents.CatcherFail:
return this.GetAnimation("fruit-catcher-fail", true, true, true) ??
this.GetAnimation("fruit-ryuuta", true, true, true);
case CatchSkinComponents.CatcherKiai:
return this.GetAnimation("fruit-catcher-kiai", true, true, true) ??
this.GetAnimation("fruit-ryuuta", true, true, true);
} }
return null; return null;

View File

@ -0,0 +1,12 @@
// 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.
namespace osu.Game.Rulesets.Catch.UI
{
public enum CatcherAnimationState
{
Idle,
Fail,
Kiai
}
}

View File

@ -155,11 +155,21 @@ namespace osu.Game.Rulesets.Catch.UI
Anchor = Anchor.TopCentre, Anchor = Anchor.TopCentre,
Origin = Anchor.BottomCentre, Origin = Anchor.BottomCentre,
}, },
createCatcherSprite().With(c =>
{
c.Anchor = Anchor.TopCentre;
})
}; };
updateCatcher();
}
private Drawable catcherSprite;
private void updateCatcher()
{
catcherSprite?.Expire();
Add(catcherSprite = createCatcherSprite().With(c =>
{
c.Anchor = Anchor.TopCentre;
}));
} }
private int currentDirection; private int currentDirection;
@ -222,7 +232,7 @@ namespace osu.Game.Rulesets.Catch.UI
Scheduler.AddDelayed(beginTrail, HyperDashing ? 25 : 50); Scheduler.AddDelayed(beginTrail, HyperDashing ? 25 : 50);
} }
private Drawable createCatcherSprite() => new CatcherSprite(); private Drawable createCatcherSprite() => new CatcherSprite(currentState);
/// <summary> /// <summary>
/// Add a caught fruit to the catcher's stack. /// Add a caught fruit to the catcher's stack.
@ -290,9 +300,25 @@ namespace osu.Game.Rulesets.Catch.UI
SetHyperDashState(); SetHyperDashState();
} }
if (validCatch)
updateState(fruit.Kiai ? CatcherAnimationState.Kiai : CatcherAnimationState.Idle);
else
updateState(CatcherAnimationState.Fail);
return validCatch; return validCatch;
} }
private void updateState(CatcherAnimationState state)
{
if (currentState == state)
return;
currentState = state;
updateCatcher();
}
private CatcherAnimationState currentState;
private double hyperDashModifier = 1; private double hyperDashModifier = 1;
private int hyperDashDirection; private int hyperDashDirection;
private float hyperDashTargetPosition; private float hyperDashTargetPosition;

View File

@ -14,9 +14,9 @@ namespace osu.Game.Rulesets.Catch.UI
{ {
protected override bool ApplySizeRestrictionsToDefault => true; protected override bool ApplySizeRestrictionsToDefault => true;
public CatcherSprite() public CatcherSprite(CatcherAnimationState state)
: base(new CatchSkinComponent(CatchSkinComponents.CatcherIdle), _ => : base(new CatchSkinComponent(componentFromState(state)), _ =>
new DefaultCatcherSprite(), confineMode: ConfineMode.ScaleDownToFit) new DefaultCatcherSprite(state), confineMode: ConfineMode.ScaleDownToFit)
{ {
RelativeSizeAxes = Axes.None; RelativeSizeAxes = Axes.None;
Size = new Vector2(CatcherArea.CATCHER_SIZE); Size = new Vector2(CatcherArea.CATCHER_SIZE);
@ -25,12 +25,34 @@ namespace osu.Game.Rulesets.Catch.UI
OriginPosition = new Vector2(0.5f, 0.06f) * CatcherArea.CATCHER_SIZE; OriginPosition = new Vector2(0.5f, 0.06f) * CatcherArea.CATCHER_SIZE;
} }
private static CatchSkinComponents componentFromState(CatcherAnimationState state)
{
switch (state)
{
case CatcherAnimationState.Fail:
return CatchSkinComponents.CatcherFail;
case CatcherAnimationState.Kiai:
return CatchSkinComponents.CatcherKiai;
default:
return CatchSkinComponents.CatcherIdle;
}
}
private class DefaultCatcherSprite : Sprite private class DefaultCatcherSprite : Sprite
{ {
private readonly CatcherAnimationState state;
public DefaultCatcherSprite(CatcherAnimationState state)
{
this.state = state;
}
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(TextureStore textures) private void load(TextureStore textures)
{ {
Texture = textures.Get("Gameplay/catch/fruit-catcher-idle"); Texture = textures.Get($"Gameplay/catch/fruit-catcher-{state.ToString().ToLower()}");
} }
} }
} }