我想使用愤怒的小鸟等游戏中常见的双指滑入/滑出手势来实现缩放功能。现在我正在使用 slider 缩放,感觉不如简单的手势好。所以我试图查看 MonoGame 中的手势实现,但还没有弄清楚实际上可以帮助我实现所描述的行为。
任何帮助将不胜感激,谢谢!
最佳答案
简短回答:您需要使用TouchPanel
手势功能来检测Pinch
手势,然后处理结果手势。
较长的答案...
您将针对每个用户手势获得多个 GestureType.Pinch
手势事件,然后在用户释放一个或两个手指时获得一个 GestureType.PinchComplete
。每个 Pinch
事件都有两对向量 - 当前位置和每个触摸点的位置变化。要计算捏合的实际变化,您需要反算每个触摸点的先前位置,获取先前和当前状态下触摸点之间的距离,然后减去以获得总变化。将此与原始捏合触摸点的距离(第一个捏合事件中触摸点的原始位置)进行比较,以获得总距离差。
首先,确保初始化 TouchPanel.EnabledGestures
属性以包含 GestureType.Pinch
和可选的 GestureType.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;
}
}
}
有趣的部分是计算缩放量。有两个基本选项:
如上所示,使用比例因子根据当前
Pinch
事件表示的原始距离变化来改变缩放。这相当简单,可能会完成您需要它做的事情。在这种情况下,您可能可以删除_pinching
和_pinchInitialDistance
字段和相关代码。跟踪原始触摸点之间的距离并根据当前距离设置缩放为初始距离的百分比 (
float zoom = dist/_pinchInitialDistance; ZoomTo(zoom);
)
您选择哪一个取决于您目前处理缩放的方式。
在任何一种情况下,您可能还想记录触摸点之间的中心点以用作缩放中心,而不是将缩放点固定在屏幕中心。或者,如果您想really 搞笑,记录原始接触点(aOld
和 bOld
来自第一个 Pinch
事件)并进行平移、旋转和缩放操作以使这两个点跟随当前触摸点。
关于c# - 使用 MonoGame 和双指手势实现缩放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18889441/