mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 09:27:29 +08:00
Proof of Concept draft for Taiko touch input
This commit is contained in:
parent
6eb79c37d8
commit
a25b6e6a09
@ -2,11 +2,13 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.ComponentModel;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko
|
||||
{
|
||||
[Cached] // Used for touch input, see DrumTouchInputArea.
|
||||
public class TaikoInputManager : RulesetInputManager<TaikoAction>
|
||||
{
|
||||
public TaikoInputManager(RulesetInfo ruleset)
|
||||
|
@ -48,8 +48,6 @@ namespace osu.Game.Rulesets.Taiko
|
||||
|
||||
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) => new[]
|
||||
{
|
||||
new KeyBinding(InputKey.MouseLeft, TaikoAction.LeftCentre),
|
||||
new KeyBinding(InputKey.MouseRight, TaikoAction.LeftRim),
|
||||
new KeyBinding(InputKey.D, TaikoAction.LeftRim),
|
||||
new KeyBinding(InputKey.F, TaikoAction.LeftCentre),
|
||||
new KeyBinding(InputKey.J, TaikoAction.RightCentre),
|
||||
|
@ -52,6 +52,12 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Depth = float.MaxValue
|
||||
});
|
||||
|
||||
DrumTouchInputArea touchInput = new DrumTouchInputArea(Playfield) {
|
||||
RelativePositionAxes = Axes.Both,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
};
|
||||
Overlays.Add(touchInput);
|
||||
}
|
||||
|
||||
protected override void UpdateAfterChildren()
|
||||
|
141
osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs
Normal file
141
osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs
Normal file
@ -0,0 +1,141 @@
|
||||
// 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 osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// An overlay that captures and displays 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 circulary boundary which distinguishes "centre" from "rim" hits, and also displays input.
|
||||
/// </summary>
|
||||
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 const float overhangPercent = 0.33f;
|
||||
private readonly InputDrum touchInputDrum;
|
||||
|
||||
[Resolved(canBeNull: true)]
|
||||
private TaikoInputManager taikoInputManager { get; set; }
|
||||
|
||||
private KeyBindingContainer<TaikoAction> keyBindingContainer;
|
||||
|
||||
// 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 TaikoAction mouseAction;
|
||||
|
||||
// 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 Dictionary<TouchSource, TaikoAction> touchActions = new Dictionary<TouchSource, TaikoAction>(Enum.GetNames(typeof(TouchSource)).Length);
|
||||
|
||||
private Playfield playfield;
|
||||
|
||||
public DrumTouchInputArea(Playfield playfield) {
|
||||
this.playfield = playfield;
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
RelativePositionAxes = Axes.Both;
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box() {
|
||||
Alpha = 0.0f,
|
||||
Colour = new OsuColour().Blue,
|
||||
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RelativePositionAxes = Axes.Both,
|
||||
},
|
||||
new Container() {
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RelativePositionAxes = Axes.Both,
|
||||
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
touchInputDrum = new InputDrum(playfield.HitObjectContainer) {
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
}
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
keyBindingContainer = taikoInputManager?.KeyBindingContainer;
|
||||
|
||||
Padding = new MarginPadding {
|
||||
Top = playfield.ScreenSpaceDrawQuad.BottomLeft.Y,
|
||||
Bottom = -DrawHeight * overhangPercent,
|
||||
};
|
||||
}
|
||||
|
||||
protected override bool OnMouseDown(MouseDownEvent e)
|
||||
{
|
||||
mouseAction = getTaikoActionFromInput(e.ScreenSpaceMouseDownPosition);
|
||||
keyBindingContainer?.TriggerPressed(mouseAction);
|
||||
return base.OnMouseDown(e);
|
||||
}
|
||||
|
||||
protected override void OnMouseUp(MouseUpEvent e)
|
||||
{
|
||||
keyBindingContainer?.TriggerReleased(mouseAction);
|
||||
base.OnMouseUp(e);
|
||||
}
|
||||
|
||||
protected override bool OnTouchDown(TouchDownEvent e)
|
||||
{
|
||||
TaikoAction taikoAction = getTaikoActionFromInput(e.ScreenSpaceTouchDownPosition);
|
||||
if (touchActions.ContainsKey(e.Touch.Source)) {
|
||||
touchActions[e.Touch.Source] = taikoAction;
|
||||
}
|
||||
else {
|
||||
touchActions.Add(e.Touch.Source, taikoAction);
|
||||
}
|
||||
keyBindingContainer?.TriggerPressed(touchActions[e.Touch.Source]);
|
||||
|
||||
return base.OnTouchDown(e);
|
||||
}
|
||||
|
||||
protected override void OnTouchUp(TouchUpEvent e)
|
||||
{
|
||||
keyBindingContainer?.TriggerReleased(touchActions[e.Touch.Source]);
|
||||
base.OnTouchUp(e);
|
||||
}
|
||||
|
||||
private TaikoAction getTaikoActionFromInput(Vector2 inputPosition) {
|
||||
bool leftSide = inputIsOnLeftSide(inputPosition);
|
||||
bool centreHit = inputIsCenterHit(inputPosition);
|
||||
|
||||
return leftSide ?
|
||||
(centreHit ? TaikoAction.LeftCentre : TaikoAction.LeftRim) :
|
||||
(centreHit ? TaikoAction.RightCentre : TaikoAction.RightRim);
|
||||
}
|
||||
|
||||
private bool inputIsOnLeftSide(Vector2 inputPosition) {
|
||||
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 * InputDrum.centre_size);
|
||||
return inputPositionToDrumCentreDelta.Length <= centreRadius;
|
||||
}
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
/// </summary>
|
||||
internal class InputDrum : Container
|
||||
{
|
||||
public const float centre_size = 0.7f;
|
||||
private const float middle_split = 0.025f;
|
||||
|
||||
[Cached]
|
||||
@ -122,14 +123,14 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Size = new Vector2(0.7f)
|
||||
Size = new Vector2(centre_size)
|
||||
},
|
||||
centreHit = new Sprite
|
||||
{
|
||||
Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Size = new Vector2(0.7f),
|
||||
Size = new Vector2(centre_size),
|
||||
Alpha = 0,
|
||||
Blending = BlendingParameters.Additive
|
||||
}
|
||||
|
@ -144,6 +144,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
drumRollHitContainer.CreateProxy(),
|
||||
// new DrumTouchInputArea(this),
|
||||
};
|
||||
|
||||
RegisterPool<Hit, DrawableHit>(50);
|
||||
|
Loading…
Reference in New Issue
Block a user