我现在用的是梦幻般的monogame框架目前正在写一个游戏。 我无法反应,正确触摸输入。 当用户水平或垂直拖拽我想每一次拖动执行操作。 问题是,手势越来越多次发出的每条拖。 这里是我的代码:
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);
}
我提出这些代码的一个块这个例子的目的。 返回的RotateRightCommand或RotateLeftCommand然后由该旋转屏幕上的对象调用代码执行。 这整个的代码块在monogame的更新循环中运行。 我想我失去了一些东西在重置触摸输入方面,这就是为什么我得到一个拖回到3个或4 RotateCommands。 我究竟做错了什么?
编辑:您没有使用正确的姿势这里。 甲拖动手势生成的每个手指在屏幕上移动的时间。 如果你从屏幕到另一个(很快)的一侧移动你的手指,你会得到很多的小的拖拽手势。 这是怎么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()在一个循环内,你只阅读每帧的一个gesure。 可用手势放入队列,只有移除时ReadGesture()被调用。 因此,如果你的帧率打嗝,或者如果您无法读取手势一样快,您的操作系统可以读取它(这是很可能的),你会用旧的信息工作。 你可以看到在这里 。 对于这种应用,我建议采取每个手势,并将其组合成一个或两个,然后决定应该基于该做些什么。
我想这取决于你认为是一个拖累。 MonoGame和XNA考虑从一个更新到下一一拖变化的触摸输入的检测。 所以,如果你认为你会收到一个手势,从你触摸你的手指在屏幕上的时间,直到你删除它,那将是XNA和MonoGame方面不正确。 被返回的手势是由T-1的三角洲其中T是现在和T-1是上一次调用更新。