WP7:当由Silverlight处理时抑制XNA触摸输入?

5

我在Mango中制作了一个XNA + Silverlight游戏:主要是XNA,上面有一些Silverlight UI。我的问题是,当你点击按钮或与Silverlight控件交互时,触摸信息仍然会传递到XNA游戏循环中。如何抑制这种情况?


为什么标签“windows-phone-mango”会自动解析为“windows-phone-7.1”,而实际上并不是这样的呢? - RandomEngy
这是一个同义词。7.1确实是Mango(7.5)操作系统的SDK版本。 - Den
新操作系统的官方名称是7.5。请参阅:http://windowsteamblog.com/windows_phone/b/windowsphone/archive/2011/07/26/windows-phone-mango-released-to-manufacturing.aspx - Todd Main
1
就是我上面提到的。SDK版本是7.1,操作系统版本是7.5。 - Den
2个回答

4
我为自己编写了一个类来进行跟踪。在页面加载后(在Loaded处理程序中),创建此类并将其分配给根元素(以便它可以附加到LayoutUpdated事件)。注册在游戏过程中可能覆盖游戏表面的任何控件。然后只需调用TouchesControl并传递触摸位置,以查找是否应忽略该点。它缓存控件的区域,并在布局更新时更新它们。
对于移动、改变大小或折叠/展开的矩形元素都应该有效。
public class ControlTouchTracker
{
    private List<FrameworkElement> controls = new List<FrameworkElement>();
    private Dictionary<FrameworkElement, ControlRegion> controlBounds = new Dictionary<FrameworkElement, ControlRegion>();

    public ControlTouchTracker(FrameworkElement rootElement)
    {
        rootElement.LayoutUpdated += this.OnLayoutUpdated;
    }

    public void RegisterControl(FrameworkElement control)
    {
        controls.Add(control);
    }

    public void RemoveControl(FrameworkElement control)
    {
        controls.Remove(control);
        controlBounds.Remove(control);
    }

    private void OnLayoutUpdated(object sender, EventArgs e)
    {
        foreach (Control control in this.controls)
        {
            this.RefreshControlBounds(control);
        }
    }

    private void RefreshControlBounds(FrameworkElement control)
    {
        if (this.ControlIsVisible(control))
        {
            try
            {
                GeneralTransform controlTransform = control.TransformToVisual(Application.Current.RootVisual);
                Point offset = controlTransform.Transform(new Point(0, 0));

                this.controlBounds[control] = new ControlRegion
                {
                    Left = (float)offset.X,
                    Right = (float)(offset.X + control.ActualWidth),
                    Top = (float)offset.Y,
                    Bottom = (float)(offset.Y + control.ActualHeight)
                };
            }
            catch (ArgumentException)
            {
            }
        }
        else
        {
            if (this.controlBounds.ContainsKey(control))
            {
                this.controlBounds.Remove(control);
            }
        }
    }

    private bool ControlIsVisible(FrameworkElement control)
    {
        // End case
        if (control == null)
        {
            return true;
        }

        if (control.Visibility == Visibility.Collapsed)
        {
            return false;
        }

        return this.ControlIsVisible(control.Parent as FrameworkElement);
    }

    public bool TouchesControl(Vector2 touchPosition)
    {
        foreach (ControlRegion region in this.controlBounds.Values)
        {
            if (touchPosition.X >= region.Left && touchPosition.X <= region.Right &&
                touchPosition.Y >= region.Top && touchPosition.Y <= region.Bottom)
            {
                return true;
            }
        }

        return false;
    }

    public class ControlRegion
    {
        public float Left { get; set; }
        public float Right { get; set; }
        public float Top { get; set; }
        public float Bottom { get; set; }
    }
}

(编辑)更新示例以适应父元素更改“可见性”问题。

仍在检查位置,但是赞 - 你有这个想法! - Den

3

由于与XNA的互操作方式,您将始终同时处理触摸输入和Silverlight - 在某种程度上,XNA会获得优先权,因此Silverlight在其之上运行。如果您需要忽略特定手势位置(例如Silverlight按钮所在的位置),则可以检查手势位置:

if (TouchPanel.IsGestureAvailable)
{
    if (TouchPanel.ReadGesture().GestureType == GestureType.Tap)
    {
        if (TouchPanel.ReadGesture().Position == new Vector2(120, 120))
        {

        }
    }
}

有没有一般性的解决方法?我需要手动维护这些“死区”吗?也许我可以编写一个程序,注册Silverlight控件进行跟踪,并告诉您触摸点是否有效(基于控件的位置以及它是否可见或折叠)。然后,在处理触摸之前,XNA循环运行此检查。 - RandomEngy
只需为SL控件设置特定区域并进行检查。或者,重新考虑在游戏过程中使用SL控件的方式,使得简单的触摸不会影响进程。 - Den
我不想通过隔离一些“Silverlight”区域来限制我的游戏。我将尝试我的方法,即注册它们并自动忽略控件所在区域的触摸。我最不希望出现的情况是出现一个错误,即我已经移动了控件,但忘记更新神奇的仅限于Silverlight的区域。 - RandomEngy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接