mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 21:43:22 +08:00
Make osu! touch input aware of the distance travelled of a non-direct touch
This commit is contained in:
parent
0a19b1e9cf
commit
6c4f596a9a
@ -150,6 +150,34 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
assertKeyCounter(1, 1);
|
assertKeyCounter(1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestPositionalTrackingAfterLongDistanceTravelled()
|
||||||
|
{
|
||||||
|
// When a single touch has already travelled enough distance on screen, it should remain as the positional
|
||||||
|
// tracking touch until released (unless a direct touch occurs).
|
||||||
|
|
||||||
|
beginTouch(TouchSource.Touch1);
|
||||||
|
|
||||||
|
assertKeyCounter(1, 0);
|
||||||
|
checkPressed(OsuAction.LeftButton);
|
||||||
|
checkPosition(TouchSource.Touch1);
|
||||||
|
|
||||||
|
// cover some distance
|
||||||
|
beginTouch(TouchSource.Touch1, new Vector2(0));
|
||||||
|
beginTouch(TouchSource.Touch1, new Vector2(9999));
|
||||||
|
beginTouch(TouchSource.Touch1, new Vector2(0));
|
||||||
|
beginTouch(TouchSource.Touch1, new Vector2(9999));
|
||||||
|
beginTouch(TouchSource.Touch1);
|
||||||
|
|
||||||
|
beginTouch(TouchSource.Touch2);
|
||||||
|
|
||||||
|
assertKeyCounter(1, 1);
|
||||||
|
checkPressed(OsuAction.LeftButton);
|
||||||
|
checkPressed(OsuAction.RightButton);
|
||||||
|
// in this case, touch 2 should not become the positional tracking touch.
|
||||||
|
checkPosition(TouchSource.Touch1);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestPositionalInputUpdatesOnlyFromMostRecentTouch()
|
public void TestPositionalInputUpdatesOnlyFromMostRecentTouch()
|
||||||
{
|
{
|
||||||
|
@ -97,8 +97,8 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ..or if the current position tracking touch was not a direct touch (this one is debatable and may be change in the future, but it's the simplest way to handle)
|
// ..or if the current position tracking touch was not a direct touch (and didn't travel across the screen too far).
|
||||||
if (!positionTrackingTouch.DirectTouch)
|
if (!positionTrackingTouch.DirectTouch && positionTrackingTouch.DistanceTravelled < 200)
|
||||||
{
|
{
|
||||||
positionTrackingTouch = newTouch;
|
positionTrackingTouch = newTouch;
|
||||||
return;
|
return;
|
||||||
@ -117,6 +117,12 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
|
|
||||||
private void handleTouchMovement(TouchEvent touchEvent)
|
private void handleTouchMovement(TouchEvent touchEvent)
|
||||||
{
|
{
|
||||||
|
if (touchEvent is TouchMoveEvent moveEvent)
|
||||||
|
{
|
||||||
|
var trackedTouch = trackedTouches.Single(t => t.Source == touchEvent.Touch.Source);
|
||||||
|
trackedTouch.DistanceTravelled += moveEvent.Delta.Length;
|
||||||
|
}
|
||||||
|
|
||||||
// Movement should only be tracked for the most recent touch.
|
// Movement should only be tracked for the most recent touch.
|
||||||
if (touchEvent.Touch.Source != positionTrackingTouch?.Source)
|
if (touchEvent.Touch.Source != positionTrackingTouch?.Source)
|
||||||
return;
|
return;
|
||||||
@ -148,8 +154,16 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
|
|
||||||
public OsuAction? Action;
|
public OsuAction? Action;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the touch was on a hit circle receptor.
|
||||||
|
/// </summary>
|
||||||
public readonly bool DirectTouch;
|
public readonly bool DirectTouch;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The total distance on screen travelled by this touch.
|
||||||
|
/// </summary>
|
||||||
|
public double DistanceTravelled;
|
||||||
|
|
||||||
public TrackedTouch(TouchSource source, OsuAction? action, bool directTouch)
|
public TrackedTouch(TouchSource source, OsuAction? action, bool directTouch)
|
||||||
{
|
{
|
||||||
Source = source;
|
Source = source;
|
||||||
|
Loading…
Reference in New Issue
Block a user