Touch interaction in game development in Windows Phone 7 Part 3 Drag

Page updated :

Programming! - 3. Try to move the card to the touch

About this sample

This time, I'd like to make a progran to place the four cards on the screen where you touch them and drag them. A multi-touch version of the program that first dragged the sprite in the Mouse class. Up until now, there were a lot of explanations, so I would like to explain this time around the program.

The goal of this sample program

Drag multiple cards at the same time as many multi-touch touches.

図 1 :マルチタッチによるドラッグ操作
Figure 1: Multi-touch drag

Program - Card Class

When it comes to multi-touch, you'll need to have multiple objects, so i'd like to create a "Card" class with the sprite you want to move as a card.

/// <summary>
/// ドラッグできるカード
/// </summary>
public class Card
{
  /// <summary>
  /// タッチ ID
  /// </summary>
  public int Id { get; set; }

  /// <summary>
  /// カードの位置
  /// </summary>
  public Vector2 Position { get; set; }

  /// <summary>
  /// カードの色
  /// </summary>
  public Color Color { get; set; }
}

One texture to avoid too much complexity is that the card class has three properties: touch ID, position, and color. There is no particular detailed item, but the Touch ID is used to check which touch point is tied.

Program - Declaring fields

There is nothing new except that it has an array of Card classes to have card information. This time it is the kind of application of the sample up to now. We've created four cards and set different colors to make the difference when you draw them.

/// <summary>
/// テクスチャー
/// </summary>
Texture2D texture;

/// <summary>
/// カードの一覧(4 枚分)
/// </summary>
Card[] cards = new Card[]
{
  new Card { Color = Color.White, },
  new Card { Color = Color.Yellow, },
  new Card { Color = Color.Fuchsia, },
  new Card { Color = Color.Aqua, },
};

Program - Get Touch Information

Inside the Game.Update method. There is nothing new about this area because it is boilerplate.

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

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

  //   :
  // ここに処理
  //   :
}

Program - Tie touch ID and card when you touch

In the sample program, the order is reversed in terms of processing costs, but it is easier to understand from here, so I will explain here first.

First, loop through the retrieved TouchCollection with foreach to get each information.

/// タッチ情報の処理を行う
foreach (TouchLocation tl in touches)
{
  // タッチ状態を調べる
  switch (tl.State)
  {
    case TouchLocationState.Pressed:
      // タッチされた瞬間は空いているカードを検索して紐づける
      Card card = cards.Where(c => c.Id == 0).FirstOrDefault();
      if (card != null)
      {
          card.Id = tl.Id;
          card.Position = tl.Position;
      }
      break;
  }
}

Check the TouchLocation.State property to indicate that "TouchLocationState.Pressed" is the moment you touch.

In this sample, the card ID is defined as "0" and is not used, so the card. Where (c => c.Id == 0). FirstOrDefault() searches for a card with an ID of 0 from the list of cards and retrieves it when it is found. Returns null if not found. Linq calls extension methods to simplify code, but if you're concerned about processing costs, you can search one by one in a for loop.

When you find a card, set the touch ID and touch position on the card.

Program - Processing cards in touch and processing when released

Keep the card dragged at all times while you touch it, and try to tie the touch point to the card when you release it.

// 各カードの情報を調べる
foreach (Card card in cards)
{
  if (card.Id != 0)
  {
    // 紐づくタッチ情報がまだ存在するか ID で検索
    TouchLocation tl;
    if (touches.FindById(card.Id, out tl) == true)
    {
      // まだタッチされている場合は位置情報取得
      card.Position = tl.Position;
    }
    else
    {
      // すでにタッチ情報がなかったら紐付を外す
      card.Id = 0;
    }
  }
}

Loop through the card list with foreach to process each card. If the ID is non-zero, the process is continued because it is tied to the touch point.

The TouchCollection structure provides a FindById method so that you can retrieve touch information if the specified ID exists. If the Card.Id property is not 0, you can assume that it is tied to a touch point somewhere, so the FindById method attempts to get touch information.

If the FindById method returns true, it is still in touch state, so get the touch position from the TouchLocation.Position property and set it to the card class. If the FindById method returns false, the touch is released, so set the Card.ID to 0 and leave no one touching.

Program - Drawing cards

There is nothing new because the parameters required for drawing should already be set in the Card class.

// スプライトの描画準備
spriteBatch.Begin();

// 各カードを描画
foreach (Card card in cards)
{
  spriteBatch.Draw(texture, card.Position, card.Color);
}

// スプライトの一括描画
spriteBatch.End();

Summary of this sample

This time, I tried to create an image program that actually moves objects in the game using multi-touch. You also found that when you dragged multiple cards at the same time using the touch id, you could see that the card movement was consistent when you let go or touch another finger.

This sample is only a sample and only a simple process is done. However, the basic part of the multi-touch operation by the touch panel by the actual game programming should be able to be covered, please apply it to the multi-touch processing that was in your game based on this.