Move catcher movement logic of Catcher to CatcherArea

This commit is contained in:
ekrctb 2021-06-11 15:39:06 +09:00
parent 385554b01a
commit 7f7c2c73e0
4 changed files with 99 additions and 72 deletions

View File

@ -33,13 +33,13 @@ namespace osu.Game.Rulesets.Catch.Mods
private class MouseInputHelper : Drawable, IKeyBindingHandler<CatchAction>, IRequireHighFrequencyMousePosition private class MouseInputHelper : Drawable, IKeyBindingHandler<CatchAction>, IRequireHighFrequencyMousePosition
{ {
private readonly Catcher catcher; private readonly CatcherArea catcherArea;
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
public MouseInputHelper(CatchPlayfield playfield) public MouseInputHelper(CatchPlayfield playfield)
{ {
catcher = playfield.CatcherArea.MovableCatcher; catcherArea = playfield.CatcherArea;
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
} }
@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Catch.Mods
protected override bool OnMouseMove(MouseMoveEvent e) protected override bool OnMouseMove(MouseMoveEvent e)
{ {
catcher.UpdatePosition(e.MousePosition.X / DrawSize.X * CatchPlayfield.WIDTH); catcherArea.SetCatcherPosition(e.MousePosition.X / DrawSize.X * CatchPlayfield.WIDTH);
return base.OnMouseMove(e); return base.OnMouseMove(e);
} }
} }

View File

@ -10,7 +10,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Pooling; using osu.Framework.Graphics.Pooling;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Framework.Input.Bindings;
using osu.Framework.Utils; using osu.Framework.Utils;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Configuration; using osu.Game.Configuration;
@ -26,7 +25,7 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Catch.UI namespace osu.Game.Rulesets.Catch.UI
{ {
public class Catcher : SkinReloadableDrawable, IKeyBindingHandler<CatchAction> public class Catcher : SkinReloadableDrawable
{ {
/// <summary> /// <summary>
/// The default colour used to tint hyper-dash fruit, along with the moving catcher, its trail /// The default colour used to tint hyper-dash fruit, along with the moving catcher, its trail
@ -54,6 +53,11 @@ namespace osu.Game.Rulesets.Catch.UI
/// </summary> /// </summary>
public const double BASE_SPEED = 1.0; public const double BASE_SPEED = 1.0;
/// <summary>
/// The current speed of the catcher.
/// </summary>
public double Speed => (Dashing ? 1 : 0.5) * BASE_SPEED * hyperDashModifier;
/// <summary> /// <summary>
/// The amount by which caught fruit should be offset from the plate surface to make them look visually "caught". /// The amount by which caught fruit should be offset from the plate surface to make them look visually "caught".
/// </summary> /// </summary>
@ -96,7 +100,7 @@ namespace osu.Game.Rulesets.Catch.UI
public bool Dashing public bool Dashing
{ {
get => dashing; get => dashing;
protected set set
{ {
if (value == dashing) return; if (value == dashing) return;
@ -106,6 +110,12 @@ namespace osu.Game.Rulesets.Catch.UI
} }
} }
public Direction VisualDirection
{
get => Scale.X > 0 ? Direction.Right : Direction.Left;
set => Scale = new Vector2((value == Direction.Right ? 1 : -1) * Math.Abs(Scale.X), Scale.Y);
}
/// <summary> /// <summary>
/// Width of the area that can be used to attempt catches during gameplay. /// Width of the area that can be used to attempt catches during gameplay.
/// </summary> /// </summary>
@ -116,8 +126,6 @@ namespace osu.Game.Rulesets.Catch.UI
private Color4 hyperDashColour = DEFAULT_HYPER_DASH_COLOUR; private Color4 hyperDashColour = DEFAULT_HYPER_DASH_COLOUR;
private Color4 hyperDashEndGlowColour = DEFAULT_HYPER_DASH_COLOUR; private Color4 hyperDashEndGlowColour = DEFAULT_HYPER_DASH_COLOUR;
private int currentDirection;
private double hyperDashModifier = 1; private double hyperDashModifier = 1;
private int hyperDashDirection; private int hyperDashDirection;
private float hyperDashTargetPosition; private float hyperDashTargetPosition;
@ -315,55 +323,6 @@ namespace osu.Game.Rulesets.Catch.UI
} }
} }
public void UpdatePosition(float position)
{
position = Math.Clamp(position, 0, CatchPlayfield.WIDTH);
if (position == X)
return;
Scale = new Vector2(Math.Abs(Scale.X) * (position > X ? 1 : -1), Scale.Y);
X = position;
}
public bool OnPressed(CatchAction action)
{
switch (action)
{
case CatchAction.MoveLeft:
currentDirection--;
return true;
case CatchAction.MoveRight:
currentDirection++;
return true;
case CatchAction.Dash:
Dashing = true;
return true;
}
return false;
}
public void OnReleased(CatchAction action)
{
switch (action)
{
case CatchAction.MoveLeft:
currentDirection++;
break;
case CatchAction.MoveRight:
currentDirection--;
break;
case CatchAction.Dash:
Dashing = false;
break;
}
}
/// <summary> /// <summary>
/// Drop any fruit off the plate. /// Drop any fruit off the plate.
/// </summary> /// </summary>
@ -405,15 +364,6 @@ namespace osu.Game.Rulesets.Catch.UI
{ {
base.Update(); base.Update();
if (currentDirection == 0) return;
var direction = Math.Sign(currentDirection);
var dashModifier = Dashing ? 1 : 0.5;
var speed = BASE_SPEED * dashModifier * hyperDashModifier;
UpdatePosition((float)(X + direction * Clock.ElapsedFrameTime * speed));
// Correct overshooting. // Correct overshooting.
if ((hyperDashDirection > 0 && hyperDashTargetPosition < X) || if ((hyperDashDirection > 0 && hyperDashTargetPosition < X) ||
(hyperDashDirection < 0 && hyperDashTargetPosition > X)) (hyperDashDirection < 0 && hyperDashTargetPosition > X))

View File

@ -1,8 +1,10 @@
// 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 osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Bindings;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Catch.Judgements;
using osu.Game.Rulesets.Catch.Objects.Drawables; using osu.Game.Rulesets.Catch.Objects.Drawables;
@ -14,13 +16,20 @@ using osuTK;
namespace osu.Game.Rulesets.Catch.UI namespace osu.Game.Rulesets.Catch.UI
{ {
public class CatcherArea : Container public class CatcherArea : Container, IKeyBindingHandler<CatchAction>
{ {
public const float CATCHER_SIZE = 106.75f; public const float CATCHER_SIZE = 106.75f;
public readonly Catcher MovableCatcher; public readonly Catcher MovableCatcher;
private readonly CatchComboDisplay comboDisplay; private readonly CatchComboDisplay comboDisplay;
/// <summary>
/// <c>-1</c> when only left button is pressed.
/// <c>1</c> when only right button is pressed.
/// <c>0</c> when none or both left and right buttons are pressed.
/// </summary>
private int currentDirection;
public CatcherArea(Container<CaughtObject> droppedObjectContainer, BeatmapDifficulty difficulty = null) public CatcherArea(Container<CaughtObject> droppedObjectContainer, BeatmapDifficulty difficulty = null)
{ {
Size = new Vector2(CatchPlayfield.WIDTH, CATCHER_SIZE); Size = new Vector2(CatchPlayfield.WIDTH, CATCHER_SIZE);
@ -63,16 +72,73 @@ namespace osu.Game.Rulesets.Catch.UI
MovableCatcher.OnRevertResult(hitObject, result); MovableCatcher.OnRevertResult(hitObject, result);
} }
protected override void Update()
{
base.Update();
var replayState = (GetContainingInputManager().CurrentState as RulesetInputManagerInputState<CatchAction>)?.LastReplayState as CatchFramedReplayInputHandler.CatchReplayState;
SetCatcherPosition(
replayState?.CatcherX ??
(float)(MovableCatcher.X + MovableCatcher.Speed * currentDirection * Clock.ElapsedFrameTime));
}
protected override void UpdateAfterChildren() protected override void UpdateAfterChildren()
{ {
base.UpdateAfterChildren(); base.UpdateAfterChildren();
var state = (GetContainingInputManager().CurrentState as RulesetInputManagerInputState<CatchAction>)?.LastReplayState as CatchFramedReplayInputHandler.CatchReplayState;
if (state?.CatcherX != null)
MovableCatcher.X = state.CatcherX.Value;
comboDisplay.X = MovableCatcher.X; comboDisplay.X = MovableCatcher.X;
} }
public void SetCatcherPosition(float X)
{
float lastPosition = MovableCatcher.X;
float newPosition = Math.Clamp(X, 0, CatchPlayfield.WIDTH);
MovableCatcher.X = newPosition;
if (lastPosition < newPosition)
MovableCatcher.VisualDirection = Direction.Right;
else if (lastPosition > newPosition)
MovableCatcher.VisualDirection = Direction.Left;
}
public bool OnPressed(CatchAction action)
{
switch (action)
{
case CatchAction.MoveLeft:
currentDirection--;
return true;
case CatchAction.MoveRight:
currentDirection++;
return true;
case CatchAction.Dash:
MovableCatcher.Dashing = true;
return true;
}
return false;
}
public void OnReleased(CatchAction action)
{
switch (action)
{
case CatchAction.MoveLeft:
currentDirection++;
break;
case CatchAction.MoveRight:
currentDirection--;
break;
case CatchAction.Dash:
MovableCatcher.Dashing = false;
break;
}
}
} }
} }

View File

@ -0,0 +1,11 @@
// 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 Direction
{
Right = 1,
Left = -1
}
}