編集: ここではジェスチャーを正しく使用していません。指が画面上を移動するたびに、ドラッグ ジェスチャが生成されます。画面の一方の端からもう一方の端に指を (非常にすばやく) 移動すると、小さなドラッグ ジェスチャが多数表示されます。これが XNA と MonoGame の仕組みです。
これはあなたが探しているロジックです:
var touchCol = TouchPanel.GetState();
foreach (var touch in touchCol)
{
// You're looking for when they finish a drag, so only check
// released touches.
if (touch.State != TouchState.Released)
continue;
TouchLocation prevLoc;
// Sometimes TryGetPreviousLocation can fail. Bail out early if this happened
// or if the last state didn't move
if (!touch.TryGetPreviousLocation(out prevLoc) || prevLoc.State != TouchState.Moved)
continue;
// get your delta
var delta = touch.Position - prevLoc.Position ;
// Usually you don't want to do something if the user drags 1 pixel.
if (delta.LengthSquared() < YOUR_DRAG_TOLERANCE)
continue;
if (delta.X < 0 || delta.Y < 0)
return new RotateLeftCommand(_gameController);
if (delta.X > 0 || delta.Y > 0)
return new RotateRightCommand(_gameController);
}
ジェスチャーをしたい場合は、次のようにするだけです。
var gesture = default(GestureSample);
while (TouchPanel.IsGestureAvailable)
{
gesture = TouchPanel.ReadGesture();
if (gesture.GestureType == GestureType.DragComplete)
{
if (gesture.Delta.Y < 0 || gesture.Delta.X < 0)
return new RotateLeftCommand(_gameController);
if (gesture.Delta.Y > 0 || gesture.Delta.X > 0)
return new RotateRightCommand(_gameController);
}
}
どちらの方法でも、探している動作が得られます。元の投稿で述べたように、ループ内にロジックを配置する必要があります。これは、複数のジェスチャをキューに入れることができ、スタックの最後のジェスチャがドラッグであると想定したくないためです。(マルチタッチのおかげで、ドラッグ、タップ、ドラッグ完了などを行うことができます)。
これがあなたの問題かどうかは100%わかりません...しかし、あなたの論理はここで間違っています. CodeFormatting の上司はここで私を打ち負かしていますが、次のようにする必要があります。
var gesture = default(GestureSample);
while (TouchPanel.IsGestureAvailable)
{
gesture = TouchPanel.ReadGesture();
if (gesture.GestureType == GestureType.VerticalDrag)
{
if (gesture.Delta.Y < 0)
return new RotateLeftCommand(_gameController);
if (gesture.Delta.Y > 0)
return new RotateRightCommand(_gameController);
}
if (gesture.GestureType == GestureType.HorizontalDrag)
{
if (gesture.Delta.X < 0)
return new RotateLeftCommand(_gameController);
if (gesture.Delta.X > 0)
return new RotateRightCommand(_gameController);
}
}
TouchPanel.ReadGesure() をループ内に配置しないことで、フレームごとに 1 つのジェスチャのみを読み取ることになります。利用可能なジェスチャはキューに入れられ、ReadGesture() が呼び出されたときにのみ削除されます。したがって、フレームレートに問題が発生した場合、または OS が読み取れるほど速くジェスチャを読み取ることができない場合 (これは非常に可能性があります)、古い情報で作業していることになります。ここでそれを見ることができます。このアプリケーションでは、各ジェスチャを 1 つまたは 2 つにまとめ、それに基づいて何をすべきかを決定することをお勧めします。