mirror of
https://github.com/ppy/osu
synced 2025-02-17 02:26:48 +00:00
Simplify implementation
This commit is contained in:
parent
7015cf0b1b
commit
b604eb6262
@ -2,7 +2,6 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Rulesets.Taiko.UI;
|
||||
@ -13,9 +12,6 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
||||
[TestFixture]
|
||||
public class TestSceneDrumTouchInputArea : OsuTestScene
|
||||
{
|
||||
[Cached]
|
||||
private TaikoInputManager taikoInputManager = new TaikoInputManager(new TaikoRuleset().RulesetInfo);
|
||||
|
||||
private DrumTouchInputArea drumTouchInputArea = null!;
|
||||
|
||||
[SetUpSteps]
|
||||
@ -23,19 +19,22 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
||||
{
|
||||
AddStep("create drum", () =>
|
||||
{
|
||||
Children = new Drawable[]
|
||||
Child = new TaikoInputManager(new TaikoRuleset().RulesetInfo)
|
||||
{
|
||||
new InputDrum
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Height = 0.5f,
|
||||
},
|
||||
drumTouchInputArea = new DrumTouchInputArea
|
||||
{
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
Height = 0.5f,
|
||||
new InputDrum
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Height = 0.2f,
|
||||
},
|
||||
drumTouchInputArea = new DrumTouchInputArea
|
||||
{
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
@ -39,8 +39,6 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
|
||||
private SkinnableDrawable scroller;
|
||||
|
||||
private DrumTouchInputArea drumTouchInputArea;
|
||||
|
||||
public DrawableTaikoRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null)
|
||||
: base(ruleset, beatmap, mods)
|
||||
{
|
||||
@ -59,8 +57,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
Depth = float.MaxValue
|
||||
});
|
||||
|
||||
if ((drumTouchInputArea = CreateDrumTouchInputArea()) != null)
|
||||
KeyBindingInputManager.Add(drumTouchInputArea);
|
||||
KeyBindingInputManager.Add(new DrumTouchInputArea());
|
||||
}
|
||||
|
||||
protected override void UpdateAfterChildren()
|
||||
@ -79,8 +76,6 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
return ControlPoints[result];
|
||||
}
|
||||
|
||||
public DrumTouchInputArea CreateDrumTouchInputArea() => new DrumTouchInputArea();
|
||||
|
||||
public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new TaikoPlayfieldAdjustmentContainer
|
||||
{
|
||||
LockPlayfieldAspect = { BindTarget = LockPlayfieldAspect }
|
||||
|
@ -1,7 +1,6 @@
|
||||
// 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.Diagnostics;
|
||||
using osu.Framework.Allocation;
|
||||
@ -13,152 +12,132 @@ using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Graphics;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osuTK.Input;
|
||||
|
||||
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 circular boundary which distinguishes "centre" from "rim" hits, and also displays input.
|
||||
/// An overlay that captures and displays osu!taiko mouse and touch 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 offscreen_percent = 0.35f;
|
||||
|
||||
private readonly TouchInputDrum touchInputDrum;
|
||||
private readonly Circle drumBackground;
|
||||
private readonly Circle outerCircle;
|
||||
|
||||
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 TaikoAction mouseAction;
|
||||
private readonly Dictionary<TouchSource, TaikoAction> trackedTouches = new Dictionary<TouchSource, TaikoAction>();
|
||||
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 Dictionary<TouchSource, TaikoAction> touchActions = new Dictionary<TouchSource, TaikoAction>(Enum.GetNames(typeof(TouchSource)).Length);
|
||||
private readonly Container mainContent;
|
||||
|
||||
private readonly Container visibleComponents;
|
||||
private readonly Circle centreCircle;
|
||||
|
||||
public DrumTouchInputArea()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
RelativePositionAxes = Axes.Both;
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = 300;
|
||||
|
||||
Masking = true;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
visibleComponents = new Container
|
||||
mainContent = new Container
|
||||
{
|
||||
Alpha = 0.0f,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RelativePositionAxes = Axes.Both,
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
Height = 2,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
drumBackground = new Circle
|
||||
outerCircle = new Circle
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RelativePositionAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
FillMode = FillMode.Fit,
|
||||
Alpha = 0.9f,
|
||||
},
|
||||
touchInputDrum = new TouchInputDrum
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = 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]
|
||||
private void load(TaikoInputManager taikoInputManager, OsuColour colours)
|
||||
{
|
||||
Debug.Assert(taikoInputManager?.KeyBindingContainer != null);
|
||||
Debug.Assert(taikoInputManager.KeyBindingContainer != null);
|
||||
|
||||
keyBindingContainer = taikoInputManager.KeyBindingContainer;
|
||||
|
||||
drumBackground.Colour = colours.Gray0;
|
||||
outerCircle.Colour = colours.Gray0;
|
||||
}
|
||||
|
||||
protected override bool OnMouseDown(MouseDownEvent e)
|
||||
{
|
||||
ShowTouchControls();
|
||||
mouseAction = getTaikoActionFromInput(e.ScreenSpaceMouseDownPosition);
|
||||
keyBindingContainer?.TriggerPressed(mouseAction);
|
||||
mainContent.Show();
|
||||
|
||||
TaikoAction taikoAction = getTaikoActionFromInput(e.ScreenSpaceMouseDownPosition);
|
||||
|
||||
trackedMouseButtons.Add(e.Button, taikoAction);
|
||||
keyBindingContainer.TriggerPressed(taikoAction);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void OnMouseUp(MouseUpEvent e)
|
||||
{
|
||||
keyBindingContainer?.TriggerReleased(mouseAction);
|
||||
keyBindingContainer.TriggerReleased(trackedMouseButtons[e.Button]);
|
||||
trackedMouseButtons.Remove(e.Button);
|
||||
base.OnMouseUp(e);
|
||||
}
|
||||
|
||||
protected override bool OnTouchDown(TouchDownEvent e)
|
||||
{
|
||||
ShowTouchControls();
|
||||
mainContent.Show();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
protected override void OnTouchUp(TouchUpEvent e)
|
||||
{
|
||||
keyBindingContainer?.TriggerReleased(touchActions[e.Touch.Source]);
|
||||
touchActions.Remove(e.Touch.Source);
|
||||
keyBindingContainer.TriggerReleased(trackedTouches[e.Touch.Source]);
|
||||
trackedTouches.Remove(e.Touch.Source);
|
||||
base.OnTouchUp(e);
|
||||
}
|
||||
|
||||
protected override bool OnKeyDown(KeyDownEvent e)
|
||||
{
|
||||
HideTouchControls();
|
||||
mainContent.Hide();
|
||||
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)
|
||||
{
|
||||
bool centreHit = inputIsCenterHit(inputPosition);
|
||||
bool leftSide = inputIsOnLeftSide(inputPosition);
|
||||
bool centreHit = centreCircle.ScreenSpaceDrawQuad.Contains(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)
|
||||
{
|
||||
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;
|
||||
return centreHit ? TaikoAction.RightCentre : TaikoAction.RightRim;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
inputDrum = new InputDrum()
|
||||
inputDrum = new InputDrum
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
|
@ -11,7 +11,6 @@ using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Skinning;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.UI
|
||||
@ -34,7 +33,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.InputDrum), _ => new Container
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
FillMode = FillMode.Fit,
|
||||
@ -64,7 +63,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
CentreAction = TaikoAction.RightCentre
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user