Move catcher state changing logic to OnNewResult method

This commit is contained in:
ekrctb 2020-12-08 14:28:30 +09:00
parent 88db7823b2
commit 0213f77b4b
5 changed files with 60 additions and 28 deletions

View File

@ -1,6 +1,7 @@
// 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 System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
@ -12,8 +13,11 @@
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Configuration;
using osu.Game.Rulesets.Catch.Judgements;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.Objects.Drawables;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Scoring;
using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests
@ -169,7 +173,32 @@ private void attemptCatch(CatchHitObject hitObject, int count = 1)
hitObject.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
for (var i = 0; i < count; i++)
catcher.AttemptCatch(hitObject);
{
var drawableObject = createDrawableObject(hitObject);
var result = new JudgementResult(hitObject, new CatchJudgement())
{
Type = catcher.CanCatch(hitObject) ? HitResult.Great : HitResult.Miss
};
catcher.OnNewResult(drawableObject, result);
}
}
private DrawableCatchHitObject createDrawableObject(CatchHitObject hitObject)
{
switch (hitObject)
{
case Banana banana:
return new DrawableBanana(banana);
case Droplet droplet:
return new DrawableDroplet(droplet);
case Fruit fruit:
return new DrawableFruit(fruit);
default:
throw new ArgumentOutOfRangeException(nameof(hitObject));
}
}
public class TestCatcher : Catcher

View File

@ -58,10 +58,9 @@ private void attemptCatch(Fruit fruit)
Schedule(() =>
{
bool caught = area.AttemptCatch(fruit);
area.OnNewResult(drawable, new JudgementResult(fruit, new CatchJudgement())
{
Type = caught ? HitResult.Great : HitResult.Miss
Type = area.MovableCatcher.CanCatch(fruit) ? HitResult.Great : HitResult.Miss
});
drawable.Expire();

View File

@ -81,7 +81,7 @@ protected override void OnNewDrawableHitObject(DrawableHitObject d)
((DrawableCatchHitObject)d).CheckPosition = checkIfWeCanCatch;
}
private bool checkIfWeCanCatch(CatchHitObject obj) => CatcherArea.AttemptCatch(obj);
private bool checkIfWeCanCatch(CatchHitObject obj) => CatcherArea.MovableCatcher.CanCatch(obj);
private void onNewResult(DrawableHitObject judgedObject, JudgementResult result)
=> CatcherArea.OnNewResult((DrawableCatchHitObject)judgedObject, result);

View File

@ -17,6 +17,7 @@
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.Objects.Drawables;
using osu.Game.Rulesets.Catch.Skinning;
using osu.Game.Rulesets.Judgements;
using osu.Game.Skinning;
using osuTK;
using osuTK.Graphics;
@ -190,11 +191,9 @@ protected override void LoadComplete()
internal static float CalculateCatchWidth(BeatmapDifficulty difficulty) => CalculateCatchWidth(calculateScale(difficulty));
/// <summary>
/// Let the catcher attempt to catch a fruit.
/// Determine if this catcher can catch a <see cref="CatchHitObject"/> in the current position.
/// </summary>
/// <param name="hitObject">The fruit to catch.</param>
/// <returns>Whether the catch is possible.</returns>
public bool AttemptCatch(CatchHitObject hitObject)
public bool CanCatch(CatchHitObject hitObject)
{
if (!(hitObject is PalpableCatchHitObject fruit))
return false;
@ -205,21 +204,25 @@ public bool AttemptCatch(CatchHitObject hitObject)
var catchObjectPosition = fruit.X;
var catcherPosition = Position.X;
var validCatch =
catchObjectPosition >= catcherPosition - halfCatchWidth &&
catchObjectPosition <= catcherPosition + halfCatchWidth;
return catchObjectPosition >= catcherPosition - halfCatchWidth &&
catchObjectPosition <= catcherPosition + halfCatchWidth;
}
if (validCatch)
placeCaughtObject(fruit);
public void OnNewResult(DrawableCatchHitObject drawableObject, JudgementResult result)
{
if (!(drawableObject.HitObject is PalpableCatchHitObject hitObject)) return;
if (result.IsHit)
placeCaughtObject(hitObject);
// droplet doesn't affect the catcher state
if (fruit is TinyDroplet) return validCatch;
if (hitObject is TinyDroplet) return;
if (validCatch && fruit.HyperDash)
if (result.IsHit && hitObject.HyperDash)
{
var target = fruit.HyperDashTarget;
var timeDifference = target.StartTime - fruit.StartTime;
double positionDifference = target.X - catcherPosition;
var target = hitObject.HyperDashTarget;
var timeDifference = target.StartTime - hitObject.StartTime;
double positionDifference = target.X - X;
var velocity = positionDifference / Math.Max(1.0, timeDifference - 1000.0 / 60.0);
SetHyperDashState(Math.Abs(velocity), target.X);
@ -227,12 +230,14 @@ public bool AttemptCatch(CatchHitObject hitObject)
else
SetHyperDashState();
if (validCatch)
updateState(fruit.Kiai ? CatcherAnimationState.Kiai : CatcherAnimationState.Idle);
else if (!(fruit is Banana))
if (result.IsHit)
updateState(hitObject.Kiai ? CatcherAnimationState.Kiai : CatcherAnimationState.Idle);
else if (!(hitObject is Banana))
updateState(CatcherAnimationState.Fail);
}
return validCatch;
public void OnRevertResult(DrawableCatchHitObject fruit, JudgementResult result)
{
}
/// <summary>

View File

@ -5,7 +5,6 @@
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Judgements;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.Objects.Drawables;
using osu.Game.Rulesets.Catch.Replays;
using osu.Game.Rulesets.Judgements;
@ -42,6 +41,8 @@ public CatcherArea(Container droppedObjectContainer, BeatmapDifficulty difficult
public void OnNewResult(DrawableCatchHitObject hitObject, JudgementResult result)
{
MovableCatcher.OnNewResult(hitObject, result);
if (!result.Type.IsScorable())
return;
@ -56,12 +57,10 @@ public void OnNewResult(DrawableCatchHitObject hitObject, JudgementResult result
comboDisplay.OnNewResult(hitObject, result);
}
public void OnRevertResult(DrawableCatchHitObject fruit, JudgementResult result)
=> comboDisplay.OnRevertResult(fruit, result);
public bool AttemptCatch(CatchHitObject obj)
public void OnRevertResult(DrawableCatchHitObject hitObject, JudgementResult result)
{
return MovableCatcher.AttemptCatch(obj);
comboDisplay.OnRevertResult(hitObject, result);
MovableCatcher.OnRevertResult(hitObject, result);
}
protected override void UpdateAfterChildren()