Touch operation in game development on Windows Phone 7 Part 2 Multi-Touch

Page creation date :

Programming! - 2. Try multi-touch

About this sample

I would like to explain the program for realizing multi-touch input. Multi-touch input by touch panel in Windows Phone 7 is one of the important items as user input. This is because unlike Windows and Xbox 360, the main input interface is the touch panel. Windows Phone with a keyboard may also come out, of course not necessarily installed. When it comes to any Windows Phone, in order to make the game work, it is necessary to support the touch panel.

If you limit the touch panel to single touch only, the type of game that can inevitably be made will be limited when it comes to making games. Try remembering your portable game console (you can just leave it on hold). Most game consoles need to press a number of buttons at the same time with both hands with a game controller or a real machine.

Windows Phone 7 doesn't have a number of buttons like a game controller, and it doesn't necessarily have a keyboard. Therefore, virtual keys and buttons may be placed on the screen, and it is inconvenient because it is not possible to press at the same time only by single touch when pressing them.

Of course, not only the example of virtual buttons like the above, but also multi-touch is often common in multi-touch "pinch, stretch (operation to move or separate between two points)" or in a game where a single screen is operated by multiple people, multi-touch is required.

Well, i want to do the information acquisition of multi-touch using the class only for the touch panel in this sample though the preface became long. It's fun to create a sample that allows you to play with multi-touch all of a sudden, but I'd like to find out what information can be obtained by multi-touch first. Because there is a habit part, such as when it does not work well in later programming by knowing them ahead, I think that you can reduce the time to pursue the cause.

The goal of this sample program

I display the information when i do multi-touch and confirm it.

図 1 :タッチしたときにタッチ情報がテキストで表示される
Figure 1: Touch information is displayed in text when you touch it

Program - Declaring fields

The fields are declared "TouchPanelCapabilities Structure" and "TouchCollection structure".

/// <summary>
///  スプライトでテキストを描画するためのフォント
/// </summary>
SpriteFont font;

/// <summary>
///  タッチパネルの機能情報
/// </summary>
TouchPanelCapabilities capabilities;

/// <summary>
///  取得したタッチ情報の一覧
/// </summary>
TouchCollection touches;

The TouchPanelCapabilities structure is a structure that allows you to have the function of the touch panel itself as a parameter. Used to check whether the touch panel can be used during update.

The TouchCollection structure has a list of information in the currently touched state. If multiple touch scans are detected, you can retrieve multiple "TouchLocation structures". We'll talk more about it later.

Program - Loading fonts

Before you draw text on the screen, add a font definition to your content project and load it with the Game.LoadContent method. Since this is directly related to touch panel, i will spare a detailed explanation.

図 2 :コンテンツプロジェクトに「Font.spritefont」を追加しておく
Figure 2: Add Font.spritefont to content project

// フォントをコンテンツパイプラインから読み込む
font = Content.Load<SpriteFont>("Font");

Program - Get touch panel information

Gets the touch panel information in the Game.Update method.

// タッチパネルの機能情報を取得
capabilities = TouchPanel.GetCapabilities();

// タッチパネルが使用可能であるかチェック
if (capabilities.IsConnected)
  // 現在のタッチパネルの入力情報を取得
  touches = TouchPanel.GetState();

You can get the function information of the touch panel by calling the TouchPanel.GetCapabilities method. There are two information that can be obtained: whether a touch panel can be used or the maximum number of touch points that can be obtained by the touch panel. I think that it is not a problem if i obtain it in the Game.Initialize method because neither changes in the game, but it is described in the Update method considering the case that the device which can be removed of the touch panel in the future and the real machine other than the touch panel and Windows Phone which can be connected to USB appeared.

In addition, "Can you use the touch panel", windows phone 7 can always be used, so there is no need to check, but if you share code with Windows or Xbox 360, these hards are not required input interface, so you need to check.

Once you have verified that the touch panel is available in the TouchPanelCapabilities.IsConnected property, you can get the current touch state with the TouchPanel.GetState method.

I'm doing some operations after getting the touch information, but in this sample, i'm just going to show the information, so i'm not doing any more in the Game.Update method.

Program - Get the maximum number of touch points you can get

The maximum number of touch points that can be retrieved is roughly fixed, so you don't need to get them during the game, but you can get the maximum number of touch points you can get from the TouchPanelCapabilities.MaximumTouchCount property. For example, if the MaximumTouchCount property is "4", you cannot get the fifth location information by touching the touch panel with five fingers.

The number of acquisitions in the smartphone "HTC 7 Trophy" used in this sample was "4". (By the way, XNA Game Studio 4.0 always defines it to return 4.) Windows Phone 7 specification is more than 4 points, so you won't return less than 4)

// タッチ可能な最大数を表示
                       "MaximumTouchCount : " +
                       new Vector2(20, 50),

図 3 :TouchPanelCapabilities.MaximumTouchCount プロパティの取得数
Figure 3: Number of TouchPanelCapabilities.MaximumTouchCount property

Program - Get Touch Information

The retrieved TouchCollection structure contains multiple touch information. For example, if you're touching with two fingers, it usually contains two minutes of touch information.

The number of touch information can be obtained in the TouchCollection.Count property. The number obtained is displayed repeatedly touch information in the for statement. It is not a problem to loop in foreach originally, but i loop it with for because I use the index of the array (int index) in the following description.

// タッチ情報の数だけループする
for (int index = 0; index < touches.Count; index++)
  // 指定したインデックスのタッチ情報取得
  TouchLocation tl = touches[index];

  // タッチ情報を可視化
  string mes = "Index : " + index + Environment.NewLine +
               "Id : " + tl.Id + Environment.NewLine +
               "Position : " + tl.Position + Environment.NewLine +
               "State : " + tl.State;

  // 文字の描画
                         new Vector2(30 + (index % 4) * 10,
                                     80 + index * 140),

Now, each touch information gets these as a "TouchLocation" structure. If you are looping with for, you can get it in TouchCollection[index]. (Foreach can also get the "TouchLocation" structure directly.)

There are four information that can be obtained in the TouchLocation structure, and the sample displays each information.

Touch information is displayed as shown below when actually running. Three-finger touch information is displayed. By the way, touch with five fingers and only four will be displayed. (Maximum acquisition supated for 4)

図 4 :3 本の指でタッチしているところ
Figure 4:3 Touching with your fingers

Program - 1 thing to watch out for when retrieving touch information 1 (index and ID)

I mentioned that there are some things to be aware of when dealing with touch information, but the first is index and ID. An index is simply an array index.

I think that it is easier to understand if you have you try it on a real machine than to explain in writings. For example, you can use two "index fingers" and "middle fingers" to operate, and then touch them with your index finger first.

図 5 :人差し指でタッチ
Figure 5: Touch with index finger

The index is "0" as shown on the screen. Then touch with your middle finger.

図 6 :中指でタッチ
Figure 6: Touch with the middle finger

In this state, two pieces of information are displayed because you are touching with two fingers. The index touched by the middle finger is "1".

Let go of your index finger here. Then, the touch information is as follows.

図 7 :人差し指を放す
Figure 7: Release your index finger

As you may have noticed, the index of the information you are touching with the middle finger is "0". If you manage the character in the index when you move it, the previous operation will lead to the following behavior.

Move the character [A] with your index finger

Move the character [B] with the middle finger in that state

Release the index finger while moving the character with the middle finger

The character that was operating with the middle finger suddenly switches to [A].

Another phenomenon is that the drawing character of the first touch information flickers when you let one of those fingers go and touch them while touching them. This is because the second finger is cut into the index "0" the moment you touch or release it.

As mentioned above, the order of index and touch information when multi-touch does not match the order in which it was touched. Therefore, if you want to do something, you should not manage it with a TouchCollection index.

In what should be managed in "TouchLocation" structure has a "Id" property, id is rewritten to a new value every time you touch, the relationship between the touch point and id while you touch is guaranteed, so you will manage here.

Of course, it's not that you have to manage it with an ID, but sometimes you can manage your touch position well enough. For example, if you just touch the button on the screen, you can determine that you pressed the button by examining it at the touch position without the ID relationship. However, i think that it is necessary to determine by id still because the position always changes when it includes the drag processing, etc.

Program - 2 things to watch out for when retrieving touch information (number of touch information acquisition)

It is not included in the program of the article, but the sample draws "maximum number of touch information obtained at the same time" with the string "GetMaxTouchCount" at the bottom of the screen. This is to display the maximum number of touch information obtained by the "TouchPanel.GetState" method in the past, but in this test machine the "TouchPanelCapabilities.MaximumTouchCount" property is 4, so the maximum value of the number displayed here should usually be 4. Even if you put five fingers in the case, it will still be 4.

図 8 :5 本の指を置いたときの数値
Figure 8: Number when five fingers are placed

Now, let's experiment a little bit. Try to repeat the touch panel with multiple fingers at high speed. It depends on the test machine, but the number may exceed 4 before you know it.

図 9 :GetMaxTouchCount が 4 を超えている
Figure 9: GetMaxTouchCount exceeds 4

In fact, the touch information obtained by the "TouchPanel.GetState" method is not the touch information of the moment you call the "TouchPanel.GetState" method, the moment you touch from the last update timing, such as the moment you released it is cached. Therefore, even though there are up to four touchs that can be detected at the same time, the same finger can be treated as a separate touch if you touch again, so you may get more touch information than TouchPanelCapabilities.MaximumTouchCount.

So if TouchPanelCapabilities.MaximumTouchCount is 4, the number of array elements of touch-related data is fixed to 4, and some over-indexing errors may occur, depending on how you handle it.

By the way, the maximum value of the TouchCollection.Count property is described as "8" in xna game studio help, so if you want to fix the number of elements in the array, i think it's safe to set the number of elements to at least 8. (If you think about future version upgrades, you may want to put a guard clause so as not to over-index))

Summary of this sample

This time, I examined various parameters for the information obtained from multi-touch. We also confirmed that there are some caveats when obtaining touch panel information. Based on these knowledge, I would like to explain a sample using multi-touch.