MonoGame阅读触摸手势 [英] MonoGame reading touch gestures

查看:198
本文介绍了MonoGame阅读触摸手势的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是梦幻般的monogame框架目前正在写一个游戏。我无法反应,正确触摸输入。当用户在水平方向或垂直拖动欲每拖动一次执行一个动作。问题是手势是越来越多次发出每个拖动。这里是我的代码:

I am currently writing a game using the fantastic monogame framework. I am having trouble reacting to touch input correctly. When a user drags horizontally or vertically I want to perform an action once per drag. The problem is the gesture is getting issued multiple times for each drag. Here is my code:

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。我在做什么错

I have moved all of this code into one block for the purposes of this example. The RotateRightCommand or RotateLeftCommand that is returned is then executed by the calling code which rotates the object on the screen. This whole block of code is being run in the update loop in monogame. I think I am missing something in terms of resetting the touch input and that's why I'm getting 3 or 4 RotateCommands returned for one drag. What am I doing wrong?

推荐答案

编辑:您没有使用正确的手势这里。一拖手势产生的每个手指在屏幕上移动的时间。如果你从屏幕到另一个(很快)的一侧移动你的手指,你会得到很多的小的拖动动作。这是怎么XNA和MonoGame工作

You're not using gestures correctly here. A drag gesture is generated every time a finger moves across the screen. If you move your finger from one side of the screen to the other (Very quickly), you'll get a lot of small drag gestures. This is how XNA and MonoGame work.

这是你要找的逻辑:

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);   
}

如果您愿意的手势,你可以这样做:

If you'd rather do gestures, you can just do this:

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);
    }
}



无论哪种方式,会给你的行为,你正在寻找对于。你仍然需要把逻辑循环中,因为我在原来的职位说,因为你可以有多个手势排队,而你不想假设最后一个堆栈的拖累。 (感谢多点触控您可以拖动,水龙头,拖动完成,等等)。

Either way will give you the behavior you're looking for. You still need to put the logic inside of the loop as I said in the original post, because you can have multiple gestures queued up, and you don't want to assume that the last one in the stack is the drag. (Thanks to multitouch you can have drags, taps, drag complete, etc).

我不是100%肯定,如果这是你的问题...但你的逻辑是错在这里。该CodeFormatting老板在这里打我,但它应该是更喜欢这样的:

I'm not 100% sure if this is your problem... but your logic is wrong here. The CodeFormatting boss is beating me here, but it should be more like this:

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()被调用。因此,如果你的帧率打嗝,或者如果您无法读取手势一样快,您的操作系统可以读取它(这是很可能的),你可以用旧的信息工作。你可以在这里看到。对于这种应用,我建议采取每个手势,并将其组合成一个或两个,然后决定应该基于该做的事情。

By not putting the TouchPanel.ReadGesure() inside of a loop, you're only reading one gesure per frame. The available gestures are put into a queue, and only removed when ReadGesture() is called. Therefore if your framerate hiccups, or if you can't read a gesture as fast as you the OS can read it (Which is very possible), you'll be working with old information. You can see that here. For this application, I suggest taking each gesture, and combining it into one or two, then deciding what you should do based on that.

这篇关于MonoGame阅读触摸手势的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆