2011-07-28 14 views
5

Tôi đã có trò chơi XNA + Silverlight trong Mango: Chủ yếu là XNA với một số giao diện người dùng Silverlight ở trên cùng. Vấn đề tôi gặp phải là khi bạn nhấn một nút hoặc tương tác với một điều khiển Silverlight, thông tin cảm ứng vẫn được truyền đến vòng lặp trò chơi XNA. Làm thế nào để bạn ngăn chặn điều này?WP7: Loại bỏ đầu vào cảm ứng XNA khi được xử lý bởi Silverlight?

+0

Tại sao thẻ 'windows-phone-mango' tự động giải quyết thành 'windows-phone-7.1' nếu đó không phải là điều thực sự là? – RandomEngy

+0

Nó là một từ đồng nghĩa. 7.1 thực sự là phiên bản SDK cho hệ điều hành Mango (7.5). –

+0

Tên chính thức của hệ điều hành mới là 7,5. Vui lòng xem: http://windowsteamblog.com/windows_phone/b/windowsphone/archive/2011/07/26/windows-phone-mango-released-to-manufacturing.aspx –

Trả lời

4

Wrote lên một lớp học để làm việc theo dõi đối với tôi. Sau khi tải trang của bạn (trong trình xử lý được tải), hãy tạo điều này và cung cấp cho nó phần tử gốc (để nó có thể đính kèm vào sự kiện LayoutUpdated). Đăng ký bất kỳ điều khiển nào có thể che phủ bề mặt trò chơi trong khi chơi. Sau đó, chỉ cần gọi TouchesControl và vượt qua ở vị trí cảm ứng để tìm hiểu xem bạn có nên bỏ qua điểm đó hay không. Nó lưu trữ các vùng của các điều khiển và cập nhật chúng khi có bản cập nhật bố cục.

Nên làm việc để di chuyển các phần tử hình chữ nhật, thay đổi kích thước hoặc thu gọn/mở rộng.

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

(chỉnh sửa) Ví dụ cập nhật để làm việc với các thành phần chính thay đổi Visibility.

+0

Vẫn đang kiểm tra vị trí, nhưng kudo - bạn đã có ý tưởng! –

3

Do cách thức tương tác với XNA hoạt động, bạn sẽ luôn nhận được đầu vào cảm ứng được xử lý cả bởi XNA và Silverlight - ở một mức độ nào đó, XNA nhận ưu tiên, vì vậy Silverlight hoạt động trên đầu trang đó. Những gì bạn có thể làm, nếu bạn cần phải bỏ qua địa điểm cử chỉ cụ thể (ví dụ nơi nút Silverlight đang nằm), bạn có thể kiểm tra vị trí cử chỉ:

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

     } 
    } 
} 
+0

Không có cách nào để giải quyết vấn đề này nói chung? Tôi sẽ cần phải tự bảo trì những "vùng chết" này? Có lẽ tôi có thể viết một cái gì đó mà bạn đăng ký các điều khiển Silverlight để theo dõi và nó có thể cho bạn biết liệu điểm tiếp xúc có hợp lệ hay không (dựa trên nơi điều khiển và nếu nó có thể nhìn thấy hoặc bị thu gọn). Sau đó, vòng lặp XNA chạy kiểm tra này trước khi xử lý các liên lạc. – RandomEngy

+0

Chỉ cần có một khu vực cụ thể cho điều khiển SL và kiểm tra chống lại nó. Hoặc, nghĩ lại cách bạn sử dụng các điều khiển SL trong trò chơi để một cú chạm đơn giản sẽ không ảnh hưởng đến quá trình. –

+0

Tôi không muốn hạn chế trò chơi của mình bằng cách bỏ qua một số vùng "Silverlight". Tôi sẽ thử cách tiếp cận của tôi về việc đăng ký chúng và tự động bỏ qua các liên lạc trong các khu vực có các điều khiển. Điều cuối cùng tôi muốn là một lỗi mà tôi đã di chuyển điều khiển và quên cập nhật vùng chỉ có phép màu bạc. – RandomEngy

Các vấn đề liên quan