1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 16:07:24 +08:00

Simplify implementation

This commit is contained in:
Dean Herbert 2022-07-22 16:18:22 +09:00
parent 7015cf0b1b
commit b604eb6262
5 changed files with 75 additions and 103 deletions

View File

@ -2,7 +2,6 @@
// 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 NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Rulesets.Taiko.UI; using osu.Game.Rulesets.Taiko.UI;
@ -13,9 +12,6 @@ namespace osu.Game.Rulesets.Taiko.Tests
[TestFixture] [TestFixture]
public class TestSceneDrumTouchInputArea : OsuTestScene public class TestSceneDrumTouchInputArea : OsuTestScene
{ {
[Cached]
private TaikoInputManager taikoInputManager = new TaikoInputManager(new TaikoRuleset().RulesetInfo);
private DrumTouchInputArea drumTouchInputArea = null!; private DrumTouchInputArea drumTouchInputArea = null!;
[SetUpSteps] [SetUpSteps]
@ -23,19 +19,22 @@ namespace osu.Game.Rulesets.Taiko.Tests
{ {
AddStep("create drum", () => AddStep("create drum", () =>
{ {
Children = new Drawable[] Child = new TaikoInputManager(new TaikoRuleset().RulesetInfo)
{ {
new InputDrum RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{ {
Anchor = Anchor.TopCentre, new InputDrum
Origin = Anchor.TopCentre, {
Height = 0.5f, Anchor = Anchor.TopCentre,
}, Origin = Anchor.TopCentre,
drumTouchInputArea = new DrumTouchInputArea Height = 0.2f,
{ },
Anchor = Anchor.BottomCentre, drumTouchInputArea = new DrumTouchInputArea
Origin = Anchor.BottomCentre, {
Height = 0.5f, Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
},
}, },
}; };
}); });

View File

@ -39,8 +39,6 @@ namespace osu.Game.Rulesets.Taiko.UI
private SkinnableDrawable scroller; private SkinnableDrawable scroller;
private DrumTouchInputArea drumTouchInputArea;
public DrawableTaikoRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null) public DrawableTaikoRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null)
: base(ruleset, beatmap, mods) : base(ruleset, beatmap, mods)
{ {
@ -59,8 +57,7 @@ namespace osu.Game.Rulesets.Taiko.UI
Depth = float.MaxValue Depth = float.MaxValue
}); });
if ((drumTouchInputArea = CreateDrumTouchInputArea()) != null) KeyBindingInputManager.Add(new DrumTouchInputArea());
KeyBindingInputManager.Add(drumTouchInputArea);
} }
protected override void UpdateAfterChildren() protected override void UpdateAfterChildren()
@ -79,8 +76,6 @@ namespace osu.Game.Rulesets.Taiko.UI
return ControlPoints[result]; return ControlPoints[result];
} }
public DrumTouchInputArea CreateDrumTouchInputArea() => new DrumTouchInputArea();
public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new TaikoPlayfieldAdjustmentContainer public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new TaikoPlayfieldAdjustmentContainer
{ {
LockPlayfieldAspect = { BindTarget = LockPlayfieldAspect } LockPlayfieldAspect = { BindTarget = LockPlayfieldAspect }

View File

@ -1,7 +1,6 @@
// 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.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using osu.Framework.Allocation; using osu.Framework.Allocation;
@ -13,152 +12,132 @@ using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Game.Graphics; using osu.Game.Graphics;
using osuTK; using osuTK;
using osuTK.Graphics;
using osuTK.Input;
namespace osu.Game.Rulesets.Taiko.UI namespace osu.Game.Rulesets.Taiko.UI
{ {
/// <summary> /// <summary>
/// An overlay that captures and displays Taiko mouse and touch input. /// An overlay that captures and displays osu!taiko mouse and touch input.
/// The boundaries of this overlay defines the interactable area for touch input.
/// A secondary InputDrum is attached by this overlay, which defines the circular boundary which distinguishes "centre" from "rim" hits, and also displays input.
/// </summary> /// </summary>
public class DrumTouchInputArea : Container public class DrumTouchInputArea : Container
{ {
// The percent of the drum that extends past the bottom of the screen (set to 0.0f to show the full drum) private readonly Circle outerCircle;
private const float offscreen_percent = 0.35f;
private readonly TouchInputDrum touchInputDrum;
private readonly Circle drumBackground;
private KeyBindingContainer<TaikoAction> keyBindingContainer = null!; private KeyBindingContainer<TaikoAction> keyBindingContainer = null!;
// Which Taiko action was pressed by the last OnMouseDown event, so that the corresponding action can be released OnMouseUp even if the cursor position moved private readonly Dictionary<TouchSource, TaikoAction> trackedTouches = new Dictionary<TouchSource, TaikoAction>();
private TaikoAction mouseAction; private readonly Dictionary<MouseButton, TaikoAction> trackedMouseButtons = new Dictionary<MouseButton, TaikoAction>();
// A map of (Finger Index OnTouchDown -> Which Taiko action was pressed), so that the corresponding action can be released OnTouchUp is released even if the touch position moved private readonly Container mainContent;
private readonly Dictionary<TouchSource, TaikoAction> touchActions = new Dictionary<TouchSource, TaikoAction>(Enum.GetNames(typeof(TouchSource)).Length);
private readonly Container visibleComponents; private readonly Circle centreCircle;
public DrumTouchInputArea() public DrumTouchInputArea()
{ {
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.X;
RelativePositionAxes = Axes.Both; Height = 300;
Masking = true;
Children = new Drawable[] Children = new Drawable[]
{ {
visibleComponents = new Container mainContent = new Container
{ {
Alpha = 0.0f,
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
RelativePositionAxes = Axes.Both, Height = 2,
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
Children = new Drawable[] Children = new Drawable[]
{ {
drumBackground = new Circle outerCircle = new Circle
{ {
RelativeSizeAxes = Axes.Both,
RelativePositionAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
FillMode = FillMode.Fit, FillMode = FillMode.Fit,
Alpha = 0.9f, RelativeSizeAxes = Axes.Both,
},
touchInputDrum = new TouchInputDrum
{
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
}, },
centreCircle = new Circle
{
FillMode = FillMode.Fit,
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(0.5f),
},
new Box
{
FillMode = FillMode.Fit,
RelativeSizeAxes = Axes.Y,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Colour = Color4.Black,
Width = 3,
},
} }
}, },
}; };
} }
protected override void LoadComplete()
{
Padding = new MarginPadding
{
Top = TaikoPlayfield.DEFAULT_HEIGHT * 2f, // Visual elements should start right below the playfield
Bottom = -touchInputDrum.DrawHeight * offscreen_percent, // The drum should go past the bottom of the screen so that it can be wider
};
}
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(TaikoInputManager taikoInputManager, OsuColour colours) private void load(TaikoInputManager taikoInputManager, OsuColour colours)
{ {
Debug.Assert(taikoInputManager?.KeyBindingContainer != null); Debug.Assert(taikoInputManager.KeyBindingContainer != null);
keyBindingContainer = taikoInputManager.KeyBindingContainer; keyBindingContainer = taikoInputManager.KeyBindingContainer;
drumBackground.Colour = colours.Gray0; outerCircle.Colour = colours.Gray0;
} }
protected override bool OnMouseDown(MouseDownEvent e) protected override bool OnMouseDown(MouseDownEvent e)
{ {
ShowTouchControls(); mainContent.Show();
mouseAction = getTaikoActionFromInput(e.ScreenSpaceMouseDownPosition);
keyBindingContainer?.TriggerPressed(mouseAction); TaikoAction taikoAction = getTaikoActionFromInput(e.ScreenSpaceMouseDownPosition);
trackedMouseButtons.Add(e.Button, taikoAction);
keyBindingContainer.TriggerPressed(taikoAction);
return true; return true;
} }
protected override void OnMouseUp(MouseUpEvent e) protected override void OnMouseUp(MouseUpEvent e)
{ {
keyBindingContainer?.TriggerReleased(mouseAction); keyBindingContainer.TriggerReleased(trackedMouseButtons[e.Button]);
trackedMouseButtons.Remove(e.Button);
base.OnMouseUp(e); base.OnMouseUp(e);
} }
protected override bool OnTouchDown(TouchDownEvent e) protected override bool OnTouchDown(TouchDownEvent e)
{ {
ShowTouchControls(); mainContent.Show();
TaikoAction taikoAction = getTaikoActionFromInput(e.ScreenSpaceTouchDownPosition); TaikoAction taikoAction = getTaikoActionFromInput(e.ScreenSpaceTouchDownPosition);
touchActions.Add(e.Touch.Source, taikoAction);
keyBindingContainer?.TriggerPressed(touchActions[e.Touch.Source]); trackedTouches.Add(e.Touch.Source, taikoAction);
keyBindingContainer.TriggerPressed(taikoAction);
return true; return true;
} }
protected override void OnTouchUp(TouchUpEvent e) protected override void OnTouchUp(TouchUpEvent e)
{ {
keyBindingContainer?.TriggerReleased(touchActions[e.Touch.Source]); keyBindingContainer.TriggerReleased(trackedTouches[e.Touch.Source]);
touchActions.Remove(e.Touch.Source); trackedTouches.Remove(e.Touch.Source);
base.OnTouchUp(e); base.OnTouchUp(e);
} }
protected override bool OnKeyDown(KeyDownEvent e) protected override bool OnKeyDown(KeyDownEvent e)
{ {
HideTouchControls(); mainContent.Hide();
return false; return false;
} }
public void ShowTouchControls()
{
visibleComponents.Animate(components => components.FadeIn(500, Easing.OutQuint));
}
public void HideTouchControls()
{
visibleComponents.Animate(components => components.FadeOut(2000, Easing.OutQuint));
}
private TaikoAction getTaikoActionFromInput(Vector2 inputPosition) private TaikoAction getTaikoActionFromInput(Vector2 inputPosition)
{ {
bool centreHit = inputIsCenterHit(inputPosition); bool centreHit = centreCircle.ScreenSpaceDrawQuad.Contains(inputPosition);
bool leftSide = inputIsOnLeftSide(inputPosition); bool leftSide = ToLocalSpace(inputPosition).X < DrawWidth / 2;
return centreHit ? (leftSide ? TaikoAction.LeftCentre : TaikoAction.RightCentre) : (leftSide ? TaikoAction.LeftRim : TaikoAction.RightRim); if (leftSide)
} return centreHit ? TaikoAction.LeftCentre : TaikoAction.LeftRim;
private bool inputIsOnLeftSide(Vector2 inputPosition) return centreHit ? TaikoAction.RightCentre : TaikoAction.RightRim;
{
Vector2 inputPositionToDrumCentreDelta = touchInputDrum.ToLocalSpace(inputPosition) - touchInputDrum.OriginPosition;
return inputPositionToDrumCentreDelta.X < 0f;
}
private bool inputIsCenterHit(Vector2 inputPosition)
{
Vector2 inputPositionToDrumCentreDelta = touchInputDrum.ToLocalSpace(inputPosition) - touchInputDrum.OriginPosition;
float inputDrumRadius = Math.Max(touchInputDrum.Width, touchInputDrum.DrawHeight) / 2f;
float centreRadius = (inputDrumRadius * touchInputDrum.CentreSize);
return inputPositionToDrumCentreDelta.Length <= centreRadius;
} }
} }
} }

View File

@ -66,7 +66,7 @@ namespace osu.Game.Rulesets.Taiko.UI
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load(OsuColour colours)
{ {
inputDrum = new InputDrum() inputDrum = new InputDrum
{ {
Anchor = Anchor.CentreLeft, Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft, Origin = Anchor.CentreLeft,

View File

@ -11,7 +11,6 @@ using osu.Framework.Graphics.Textures;
using osu.Framework.Input.Bindings; using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Skinning;
using osuTK; using osuTK;
namespace osu.Game.Rulesets.Taiko.UI namespace osu.Game.Rulesets.Taiko.UI
@ -34,7 +33,7 @@ namespace osu.Game.Rulesets.Taiko.UI
{ {
Children = new Drawable[] Children = new Drawable[]
{ {
new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.InputDrum), _ => new Container new Container
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit, FillMode = FillMode.Fit,
@ -64,7 +63,7 @@ namespace osu.Game.Rulesets.Taiko.UI
CentreAction = TaikoAction.RightCentre CentreAction = TaikoAction.RightCentre
} }
} }
}) }
}; };
} }