即使是再有經驗的XNA程式員,在開始Windows Phone 7上的遊戲開發時也不得不學習下多點觸控這個新的實現方法。雖然目前有些Windows Phone 7手機附帶了鍵盤,但是為了對所有WP7手機相容,我們的遊戲最好能全部採用多點觸控這種輸入方法。
目前在Windows Phone 7平台上的熱銷遊戲包括“刺客信條”、“極品飛車”、“巴比倫兄弟”都是採用觸控和加速度感應器的操作方式。這對於Windows平台的程式員來說可謂是一個全新的模式。
刺客信條使用多點觸控實現英雄的移動、攻擊和武器切換
Windows Phone 7採用最少支援4個觸點的電容屏,它不再是以前模擬手筆和識別手寫筆那麼簡單,如何處理多點觸控成為開發人員的新挑戰。在XNA編程中,多點觸控輸入會在XNA的Update()方法中被偵測,Update()方法的一個主要目的就是處理多點觸控的輸入,並將輸入導致的更改用Draw()方法繪製在螢幕上。
XNA中的底層多點觸控輸入處理
在XNA中,多點觸控裝置被抽象為一個觸控面板(Touch Panel),你可以使用TouchPanel這個靜態類中的方法來獲得觸點的資訊。儘管多點觸控還存在滑動等手勢的識別,但是我們還是從最底層的觸控輸入的處理開始學起。
我們可以用TouchPanel.GetCapabilities()這個方法來擷取觸控螢幕的一些特性,這個方法返回的TouchPanelCapabilities對象包含兩個屬性。分別如下:
IsConnected:查看是否和觸控螢幕裝置進行串連。因為WP7手機總是存在觸控螢幕的,所以該屬性總是返回true。
MaximumTouchCount:該屬性返回WP7手機電容屏支援的最大觸點個數,對於Windows Phone 7來說這個屬性最小值為4,也就是同時支援最少4個觸點。
一般說來,我們只需要使用TouchPanel中的兩個靜態方法。為了擷取底層的觸控輸入資訊,你可以在Update()方法中使用如下的方法:
TouchCollection touchLocations = TouchPanel.GetState();
TouchPanel.GetState()方法返回的是一個觸點集合,該集合包含0個或者多個TouchLocation對象。TouchLocation對象包含三個重要屬性:
State:該屬性是TouchLocation的枚舉成員,包含Pressed、Moved和Released三種狀態。分別對應觸點當前是否按下、移動和釋放。
Position:該屬性是一個Vector2是向量座標,用於確認當前觸點相對於左上方的座標位置。
Id:該屬性是一個Int的整型數字,用於標示每個由按下到釋放狀態的手指。
如果觸控螢幕上沒有任何的手指按下,那麼TouchCollection為空白。一旦有某個手指和觸控螢幕接觸,TouchCollection將包含一個State屬性為Pressed的TouchLocation對象。
在下一次TouchPanel.GetState()方法調用中,即使你的手指沒有移動,TouchLocation的State屬性也將更改為Moved。一旦你的手指離開觸控螢幕,TouchLocation的State屬性毋庸置疑,狀態為Released了。在接下來的TouchPanel.GetState()方法調用中,TouchCollection又將為空白。
這裡也有個特例,就是當你在1/30秒的時間內,完成手指在觸控螢幕上由按下到釋放的過程,那麼TouchLocation的State屬性將會由Pressed直接變更為Released,跳過了Moved這個過程。估計沒幾個人手指可以在觸控螢幕上如此神速,1/30秒呢?嘿嘿,要不你試試。
一般來說,我們可能會使用多個手指在WP7電容屏上實現各種操作,每個手指都可以獨立地實現按下、移動和釋放的過程。
如何對多個手指進行標示以便實現相應狀態的跟蹤,這裡就需要使用前面提及的TouchLocation.Id屬性了。每個觸控屏上的手指都將用一個特定的Id進行標示,以便確認是那個手指的Pressed、Moved和Released狀態。
TouchLocation還存在一個非常有用的TryGetPreviousLocation()方法,調用代碼:
TouchLocation previousTouchLocation;
bool success = touchLocation.TryGetPreviousLocation(out previousTouchLocation);
我們可以在touchLocation.State等於Moved時調用該方法,這樣你可以擷取先前的觸點位置,並計算手指移動的距離。如果touchLocation.State等於Pressed,TryGetPreviousLocation()方法將返回false,而previousTouchLocation.State的值將為TouchLocationState.Invalid。
到目前為止,我們大致瞭解了WP7上多點觸控的實現和編程方法,在Platformer遊戲中,英雄的移動和跳躍分別是由加速度感應器和觸控螢幕控制的。點擊手機螢幕,英雄將會跳躍,而左右傾斜手機,加速度感應器就會判定英雄是向左還是向右移動。
下面就是Platformer遊戲中多點觸控的封裝方法,具體的使用軒轅將在後續文章的遊戲情境繪製中重點介紹。代碼依然是一如既往的短小精悍:
1 /// <summary>
2 /// 對TouchCollection的擴充
3 /// </summary>
4 public static class TouchCollectionExtensions
5 {
6 /// <summary>
7 /// 確定觸控螢幕是否存在觸點
8 /// </summary>
9 /// <param name="touchState">當前TouchCollection集合</param>
10 /// <returns>如果存在觸點狀態為Pressed或Moved,返回true,反之為false</returns>
11 public static bool AnyTouch(this TouchCollection touchState)
12 {
13 foreach (TouchLocation location in touchState)
14 {
15 if (location.State == TouchLocationState.Pressed || location.State == TouchLocationState.Moved)
16 {
17 return true;
18 }
19 }
20 return false;
21 }
22 }