使用MonoGame和双指手势实现缩放

时间:2013-09-19 08:13:11

标签: c# android monogame

我想使用双手滑入/滑出手势来实现缩放功能,这种手势在“愤怒的小鸟”等游戏中很常见。现在我正在使用滑块缩放,它感觉不如简单的手势。所以我试着看一下MonoGame中的手势实现,但是还没弄明白实际上可以帮助我实现所描述的beahviour。

任何帮助将不胜感激,谢谢!

1 个答案:

答案 0 :(得分:4)

简短回答:您需要使用TouchPanel手势功能来检测Pinch手势,然后处理合成手势。


答案越久......

每个用户手势会获得多个GestureType.Pinch手势事件,当用户释放一个或两个手指时,会显示GestureType.PinchComplete。每个Pinch事件将具有两对向量 - 每个触摸点的当前位置和位置变化。要计算夹点的实际变化,您需要反向计算每个触摸点的先前位置,获取先前和当前状态下触摸点之间的距离,然后减去以获得总变化。将其与原始捏合触摸点的距离(触摸点与第一捏合事件的原始位置)进行比较,以获得总距离差异。

首先,请确保初始化TouchPanel.EnabledGestures属性以包含GestureType.PinchGestureType.PinchComplete,具体取决于您是否要捕获用户捏合手势的结束。

接下来,使用与此类似的内容(从Game类的Update方法调用)来处理事件

bool _pinching = false;
float _pinchInitialDistance;

private void HandleTouchInput() 
{
    while (TouchPanel.IsGestureAvailable)
    {
        GestureSample gesture = TouchPanel.GetGesture();

        if (gesture.GestureType == GestureType.Pinch)
        {
            // current positions
            Vector2 a = gesture.Position;
            Vector2 b = gesture.Position2;
            float dist = Vector2.Distance(a, b);

            // prior positions
            Vector2 aOld = gesture.Position - gesture.Delta;
            Vector2 bOld = gesture.Position2 - gesture.Delta2;
            float distOld = Vector2.Distance(aOld, bOld);

            if (!_pinching)
            {
                // start of pinch, record original distance
                _pinching = true;
                _pinchInitialDistance = distOld;
            }

            // work out zoom amount based on pinch distance...
            float scale = (distOld - dist) * 0.05f;
            ZoomBy(scale);
        }
        else if (gesture.GestureType == GestureType.PinchComplete)
        {
            // end of pinch
            _pinching = false;
        }
    }
}

有趣的部分是计算缩放量。有两个基本选项:

  1. 如上所示,使用缩放系数根据当前Pinch事件表示的距离原始更改来更改缩放。这很简单,可能就是您需要它做的事情。在这种情况下,您可以删除_pinching_pinchInitialDistance字段及相关代码。

  2. 跟踪原始触摸点之间的距离,并根据当前距离将缩放设置为初始距离的百分比(float zoom = dist / _pinchInitialDistance; ZoomTo(zoom);

  3. 您选择哪一个取决于您当前如何处理缩放。

    在任何一种情况下,您可能还希望记录触摸点之间的中心点以用作缩放的中心,而不是将缩放点固定到屏幕的中心。或者,如果您希望 真的 愚蠢,请记录第一个aOld的原始触摸点(bOldPinch事件)并进行平移,旋转和缩放操作,使这两点跟随当前的触点。