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 :
测试结果可知,我的动作是两个手指一起按得,但是在实际的到的数据来看 我手指触摸的时机,还是有点差别的,所以在开发中要注意这一点。涉及到用户体验啊~~
还有观察坐标可知,即使在我的感觉是轻点了一下,但是实际上我点击的时候手指还是会有轻微的移动的。这些都是开发的时候自定义手势的时候要考虑的问题~~