WP7-XNA 多点触摸

XNA中对游戏的控制必然用到触摸事件(WindowsPhone的XNA涉及到的按钮只有一个那就是BACK按钮,其余的交互都必须通过触摸事件来完成)

XNA处理触摸事件的命名空间是 Microsoft.Xna.Framework.Input.Touch (官方示例文档 : http://msdn.microsoft.com/en-us/library/ff434208.aspx API:http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.input.touch.aspx

文档中提到处理触摸事件的示例代码如下:

   1: // Process touch events
   2: TouchCollection touchCollection = TouchPanel.GetState();
   3: foreach (TouchLocation tl in touchCollection)
   4: {
   5:     if ((tl.State == TouchLocationState.Pressed)
   6:             || (tl.State == TouchLocationState.Moved))
   7:     {
   8:  
   9:         // add sparkles based on the touch location
  10:         sparkles.Add(new Sparkle(tl.Position.X,
  11:                  tl.Position.Y, ttms));
  12:  
  13:     }
  14: }

新建一个项目,叫TouchTest吧~

将上述代码粘贴到Game1.cs的Update方法中,为了测试方便,加入Debug代码。

查看API介绍可知:

TouchLocation 用来保存某一个触摸点的状态信息。

TouchCollection  是保存了当前所有触控状态(TouchLocation)的集合。

然后可以再代码中查看这些类包括的属性,以下摘录个人觉得比较有用的属性列出:

TouchLocation :

State  触摸状态,包含4个状态

     > TouchLocationState.Pressed 表示屏幕被触摸时手指按下的一瞬间

     > TouchLocationState.Moved 表示手指按下后正在移动,经过测试可知,在手指按下的一瞬间State为Pressed ,在手指按下后抬起前这段时间内的状态均是Moved

     > TouchLocationState.Invalid 无效状态,测试没有出现这个状态,官方描述是This touch location position is invalid. Typically, you will encounter this state when a new touch location attempts to get the previous state of itself.

     > TouchLocationState.Released 表示手指抬起的一瞬间

ID 表示当前触摸事件的ID,一个完成的触控事件的过程应该是“Pressed  -> Moved  -> Released ”在这个过程中ID是一致的,用来在多点触摸时区分触摸的每个点。

Position 触摸位置,包含两个属性

     > X 当前触摸位置的X轴坐标

     > Y 当前触摸位置的Y轴坐标

     (横屏全屏情况下,屏幕的左上角坐标为(0,0)右下角坐标为(800,480))

TouchCollection:

Count 当前有几个点被触摸

比较常用的就是上面这些属性。

使用log记录这些属性。

调整后的测试代码如下:

   1: protected override void Update(GameTime gameTime)
   2: {
   3:     // Allows the game to exit
   4:     if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
   5:         this.Exit();
   6:  
   7:     // TODO: Add your update logic here
   8:     TouchCollection touchCollection = TouchPanel.GetState();
   9:     foreach (TouchLocation tl in touchCollection)
  10:     {
  11:         if (tl.State == TouchLocationState.Pressed)
  12:         {
  13:             Debug.WriteLine("ID " + tl.Id + " Count:" + touchCollection.Count + " Pressed (" + (float)tl.Position.X + "," + (float)tl.Position.Y + ")");
  14:         }
  15:         if (tl.State == TouchLocationState.Moved)
  16:         {
  17:             Debug.WriteLine("ID " + tl.Id + " Count:" + touchCollection.Count + " Moved (" + (float)tl.Position.X + "," + (float)tl.Position.Y + ")");
  18:         }
  19:         if (tl.State == TouchLocationState.Invalid)
  20:         {
  21:             Debug.WriteLine("ID " + tl.Id + " Count:" + touchCollection.Count + " Invalid (" + (float)tl.Position.X + "," + (float)tl.Position.Y + ")");
  22:         }
  23:         if (tl.State == TouchLocationState.Released)
  24:         {
  25:             Debug.WriteLine("ID " + tl.Id + " Count:" + touchCollection.Count + " Released (" + (float)tl.Position.X + "," + (float)tl.Position.Y + ")");
  26:         }
  27:     }
  28:  
  29:  
  30:     base.Update(gameTime);
  31: }

测试得到的日志如下:(测试时的动作是:“两个手指一起温柔的在屏幕上轻点一下”,官方提供的模拟器只能支持单点触摸,再真机上调试可以得到多个点得数据(我用的是Mozart最多可以得到4个点的数据,(但是偶尔很快地用五个指头一起点能得到5个点的数据。。)))

   1: 'taskhost.exe' (Managed): Loaded 'mscorlib.dll'
   2: 'taskhost.exe' (Managed): Loaded 'System.Windows.RuntimeHost.dll'
   3: 'taskhost.exe' (Managed): Loaded 'System.dll'
   4: 'taskhost.exe' (Managed): Loaded 'System.Windows.dll'
   5: 'taskhost.exe' (Managed): Loaded 'System.Net.dll'
   6: 'taskhost.exe' (Managed): Loaded 'System.Core.dll'
   7: 'taskhost.exe' (Managed): Loaded 'System.Xml.dll'
   8: 'taskhost.exe' (Managed): Loaded '\Applications\Install\6F53E388-71A5-4106-A3B2-609A945B2BAA\Install\TouchTest.dll', Symbols loaded.
   9: 'taskhost.exe' (Managed): Loaded 'Microsoft.Xna.Framework.Game.dll'
  10: 'taskhost.exe' (Managed): Loaded 'Microsoft.Xna.Framework.Graphics.dll'
  11: 'taskhost.exe' (Managed): Loaded 'Microsoft.Xna.Framework.dll'
  12: 'taskhost.exe' (Managed): Loaded 'Microsoft.Phone.Interop.dll'
  13: 'taskhost.exe' (Managed): Loaded 'Microsoft.Phone.dll'
  14: 'taskhost.exe' (Managed): Loaded 'Microsoft.Xna.Framework.Input.Touch.dll'
  15: A first chance exception of type 'System.ArgumentException' occurred in mscorlib.dll
  16: 'taskhost.exe' (Managed): Loaded 'Microsoft.Xna.Framework.GamerServices.dll'
  17: ID 24182784 Count:1 Pressed (515,159)
  18: ID 24182784 Count:2 Moved (521,158)
  19: ID 24182785 Count:2 Pressed (161,353)
  20: ID 24182784 Count:2 Moved (522,157)
  21: ID 24182785 Count:2 Moved (164,352)
  22: ID 24182784 Count:2 Moved (521,156)
  23: ID 24182785 Count:2 Moved (162,350)
  24: ID 24182784 Count:2 Released (521,156)
  25: ID 24182785 Count:2 Released (162,350)
  26: A first chance exception of type 'System.Threading.ThreadAbortException' occurred in Microsoft.Xna.Framework.dll
  27: The thread '<No Name>' (0x1b44096e) has exited with code 0 (0x0).
  28: The thread '<No Name>' (0x1aad047a) has exited with code 0 (0x0).
  29: The thread '<No Name>' (0x1add086a) has exited with code 0 (0x0).
  30: The program '[463930110] taskhost.exe: Managed' has exited with code 0 (0x0).

(taskhost.exe 那些是程序加载日志可以忽略,重点关注类似“ID 24182784 Count:1 Pressed (515,159)”这样的行)

Tips :

测试结果可知,我的动作是两个手指一起按得,但是在实际的到的数据来看 我手指触摸的时机,还是有点差别的,所以在开发中要注意这一点。涉及到用户体验啊~~

还有观察坐标可知,即使在我的感觉是轻点了一下,但是实际上我点击的时候手指还是会有轻微的移动的。这些都是开发的时候自定义手势的时候要考虑的问题~~

posted @ 2011-11-19 03:49  LightingCui  阅读(993)  评论(0编辑  收藏  举报