我在 Mango 中有一个 XNA + Silverlight 游戏:主要是 XNA,顶部有一些 Silverlight UI。我遇到的问题是,当您按下按钮或与 Silverlight 控件交互时,触摸信息仍会传递到 XNA 游戏循环。你怎么压制这个?
问问题
1095 次
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; }
}
}
(编辑)更新示例以使用更改的父元素Visibility
。
于 2011-07-29T01:25:03.323 回答
3
由于与 XNA 互操作的工作方式,您将始终获得由 XNA 和 Silverlight 处理的触摸输入 - 在某种程度上,XNA 获得优先级,因此 Silverlight 在此之上起作用。您可以做什么,如果您需要忽略特定的手势位置(例如 Silverlight 按钮所在的位置),您可以检查手势位置:
if (TouchPanel.IsGestureAvailable)
{
if (TouchPanel.ReadGesture().GestureType == GestureType.Tap)
{
if (TouchPanel.ReadGesture().Position == new Vector2(120, 120))
{
}
}
}
于 2011-07-28T18:11:45.897 回答