Kev*_*tch 6 c# iphone xamarin.ios monogame
我目前正在使用梦幻般的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);
}
Run Code Online (Sandbox Code Playgroud)
出于本示例的目的,我已将所有此代码移动到一个块中.然后返回的RotateRightCommand或RotateLeftCommand由调用代码执行,该调用代码在屏幕上旋转对象.整个代码块在monogame的更新循环中运行.我认为我在重置触摸输入方面缺少一些东西,这就是我为一次拖动返回3或4个RotateCommands的原因.我究竟做错了什么?
Ray*_*tts 15
编辑:你这里没有正确使用手势.每次手指在屏幕上移动时都会生成拖动手势.如果您将手指从屏幕的一侧移动到另一侧(非常快),您将获得许多小拖动手势.这就是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);
}
Run Code Online (Sandbox Code Playgroud)
如果你更愿意做手势,你可以这样做:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
无论哪种方式都会给你你正在寻找的行为.您仍然需要像我在原始帖子中所说的那样将逻辑放在循环内部,因为您可以排队多个手势,并且您不希望假设堆栈中的最后一个是拖动.(多边触控,你可以有拖动,点击,拖动完成等).
我不是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);
}
}
Run Code Online (Sandbox Code Playgroud)
通过不将TouchPanel.ReadGesure()放在循环中,您每帧只读取一个gesure.可用的手势被放入队列中,只有在调用ReadGesture()时才会被删除.因此,如果您的帧率打嗝,或者您无法像操作系统读取它那样快速地读取手势(这很可能),您将使用旧信息.你可以看到在这里.对于这个应用程序,我建议采取每个手势,并将其合并为一个或两个,然后根据它决定你应该做什么.
| 归档时间: |
|
| 查看次数: |
12821 次 |
| 最近记录: |