Windows Phone 7용 게임 개발의 터치 조작 2부 멀티터치

페이지 업데이트 :
페이지 생성 날짜 :

프로그래밍! - 2.멀티 터치 시도

이 샘플 정보

여기에서는 멀티 터치 입력을 실현하기위한 프로그램에 대해 설명하고자합니다. Windows Phone 7에서 터치 패널을 통한 멀티 터치 입력은 사용자 입력에 가장 중요한 항목 중 하나입니다. Windows 및 Xbox 360과 달리 기본 입력 인터페이스는 "터치 패널"이기 때문입니다. 키보드가 있는 Windows 휴대폰이 있을 수 있지만 물론 항상 키보드가 있는 것은 아닙니다. 따라서 게임이 모든 Windows Phone에서 작동하려면 터치가 가능해야 합니다.

터치 패널을 "싱글 터치"로만 제한하면 게임을 만들 때 만들 수있는 게임 유형이 제한 될 수밖에 없습니다. 휴대용 게임 콘솔을 생각해보십시오 (고정 상태로 둘 수 있음). 대부분의 게임 콘솔에서는 게임 컨트롤러(또는 실제 콘솔)를 양손으로 잡고 동시에 여러 버튼을 눌러야 합니다.

Windows Phone 7에는 게임 컨트롤러만큼 많은 단추가 없으며 키보드가 반드시 있어야 하는 것도 아닙니다. 따라서 가상 키와 버튼이 화면에 배치될 수 있으며, 이를 누를 때 한 번의 터치만으로 동시에 누를 수 없기 때문에 불편합니다.

물론 위의 가상 버튼 예 외에도 멀티 터치에서 흔히 볼 수있는 "핀치 앤 스트레치 (두 포인트 가까이 또는 더 멀리 이동)"와 같이 여러 사람이 한 화면을 조작하는 게임에는 멀티 터치가 필요합니다.

덧붙여서 소개는 길지만이 샘플에서는 터치 패널 전용 클래스를 사용하여 멀티 터치 정보를 얻고 싶습니다. 갑자기 멀티 터치로 재생할 수있는 샘플을 만드는 것도 재미 있습니다 만, 우선 멀티 터치로 어떤 정보를 얻을 수 있는지 알고 싶습니다. 몇 가지 습관이 있으므로 먼저 알면 나중에 프로그래밍에서 잘 작동하지 않는 경우와 같이 원인을 조사하는 데 소요되는 시간을 줄일 수 있습니다.

이 샘플 프로그램의 목표

멀티 터치를 수행할 때 정보를 표시하고 확인합니다.

図 1 :タッチしたときにタッチ情報がテキストで表示される
그림 1: 터치 정보는 터치 시 텍스트로 표시됨

프로그램 - 필드 선언

필드에는 TouchPanelCapabilities Structure 및 TouchCollection Structure라는 레이블이 지정되어야 합니다.

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

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

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

"TouchPanelCapabilities 구조"는 터치 패널 자체의 기능을 매개 변수로 가질 수 있는 구조입니다. 업데이트 중에 터치 패널을 사용할 수 있는지 확인하는 데 사용됩니다.

TouchCollection 구조체에는 현재 터치된 상태에 대한 정보 목록이 포함되어 있습니다. 여러 터치가 감지되면 여러 "터치 위치 구조"를 검색할 수 있습니다. 나중에 자세히 설명합니다.

프로그램 - 글꼴 로드

화면에 텍스트를 그리기 전에 콘텐츠 프로젝트에 글꼴 정의를 추가하고 Game.LoadContent 메서드를 사용하여 로드합니다. 이것은 터치 패널과 직접적인 관련이 없으므로 자세한 설명은 생략하겠습니다.

図 2 :コンテンツプロジェクトに「Font.spritefont」を追加しておく
그림 2: 콘텐츠 프로젝트에 "Font.spritefont" 추가

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

프로그램 - 터치 패널 정보 가져오기

게임 업데이트 메서드 내에서 터치 패널 정보를 가져옵니다.

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

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

"TouchPanel.GetCapabilities" 메서드를 호출하여 터치 패널의 함수 정보를 가져올 수 있습니다. 획득할 수 있는 정보에는 "터치 패널을 사용할 수 있습니까?"와 "터치 패널로 획득할 수 있는 최대 터치 포인트 수"의 두 가지 유형이 있습니다. 둘 다 게임 중에 변경되지 않기 때문에 Game.Initialize 메서드에 따라 가져 오면 문제가 없다고 생각하지만, 앞으로는 터치 패널을 제거 할 수있는 장치 (USB 또는 Windows Phone 이외의 실제 장치에 연결할 수있는 터치 패널)가 나타나며 업데이트 방법에 설명되어 있습니다.

또한 터치 패널은 Windows Phone 7에서 항상 사용할 수 있으므로 사용할 수 있는지 여부를 확인할 필요가 없지만 Windows 및 Xbox 360과 코드를 공유 할 때 이러한 하드웨어는 입력 인터페이스가 필요하지 않으며 확인해야합니다.

터치 패널을 "TouchPanelCapabilities.IsConnected" 속성에서 사용할 수 있는지 확인할 수 있는 경우 "TouchPanel.GetState" 메서드는 현재 터치 상태를 가져옵니다.

원래는 터치 정보를 획득한 후 일부 연산 처리가 수행되지만 이 샘플에서는 정보만 표시되므로 Game.Update 메서드에서는 추가 처리가 수행되지 않습니다.

프로그램 - 얻을 수 있는 최대 터치포인트 확보

검색할 수 있는 최대 터치 포인트 수는 대략적으로 고정되어 있으므로 게임 중에 검색할 필요가 없는 경우가 많지만 TouchPanelCapabilities.MaximumTouchCount 속성에서 검색할 수 있는 최대 터치 포인트 수를 가져올 수 있습니다. 예를 들어 MaximumTouchCount 속성이 "4"이면 터치 패널을 다섯 손가락으로 터치하여 다섯 번째 위치 정보를 가져올 수 없습니다.

이 샘플에 사용 된 스마트 폰 "HTC 7 트로피"의 획득 횟수는 "4"입니다. (그런데 XNA Game Studio 4.0은 항상 4를 반환하도록 정의되어 있습니다.) Windows Phone 7 사양에서는 4포인트 이상이라고 나와 있으므로 4보다 작은 값을 반환하지 않습니다.)

// タッチ可能な最大数を表示
spriteBatch.DrawString(font,  
                       "MaximumTouchCount : " +
                         capabilities.MaximumTouchCount,
                       new Vector2(20, 50),
                       Color.LightGreen);

図 3 :TouchPanelCapabilities.MaximumTouchCount プロパティの取得数
그림 3: TouchPanelCapabilities.MaximumTouchCount 속성 검색 횟수

프로그램 - 터치 정보 가져오기

검색된 TouchCollection 구조체에는 여러 터치 정보가 포함되어 있습니다. 예를 들어 두 손가락으로 터치하면 일반적으로 두 개의 터치가 포함됩니다.

터치 정보의 수는 TouchCollection.Count 속성에서 검색할 수 있습니다. 터치 정보는 얻은 횟수만큼 for 문에 반복적으로 표시됩니다. 원래는 foreach로 루프하는 데 문제가 없지만 나중에 설명에서 배열 인덱스 (int 인덱스)를 사용할 것이므로 for로 반복합니다.

// タッチ情報の数だけループする
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;

  // 文字の描画
  spriteBatch.DrawString(font,
                         mes,
                         new Vector2(30 + (index % 4) * 10,
                                     80 + index * 140),
                         Color.White);
}

이제 각 터치 정보를 "TouchLocation" 구조로 가져옵니다. for로 반복되는 경우 "TouchCollection[인덱스]"로 얻을 수 있습니다. (foreach에서 직접 "TouchLocation" 구조체를 가져올 수도 있습니다.)

"TouchLocation" 구조에서 다음 네 가지 유형의 정보를 얻을 수 있으며 각 정보가 샘플에 표시됩니다.

실제로 실행하면 아래와 같이 터치 정보가 표시됩니다. 세 손가락으로 터치하기 때문에 세 번의 터치를 볼 수 있습니다. 그런데 다섯 손가락으로 터치하면 최대 네 개까지만 볼 수 있습니다. (최대 취득 횟수가 4개이므로)

図 4 :3 本の指でタッチしているところ
그림 4: 세 손가락으로 터치

프로그램 - 터치 정보를 검색할 때 주의할 사항 1(인덱스 및 ID)

위에서 터치 정보를 다룰 때 유의해야 할 사항이 있다고 언급했지만 첫 번째는 "인덱스"와 "ID"입니다. 인덱스는 단순히 배열 인덱스를 나타냅니다.

서면으로 설명하는 것보다 실제 기계에서 시도하면 이해하기 쉽다고 생각합니다. 예를 들어 "집게 손가락"과 "가운데 손가락"의 두 손가락으로 조작하고 집게 손가락으로 먼저 터치한다고 가정 해 보겠습니다.

図 5 :人差し指でタッチ
그림 5: 검지 손가락으로 터치

화면에 표시된 것처럼 인덱스는 "0"입니다. 그런 다음 가운데 손가락으로 터치하십시오.

図 6 :中指でタッチ
그림 6: 가운데 손가락 터치

이 상태에서는 두 손가락으로 터치하므로 두 개의 정보가 표시됩니다. 가운데 손가락으로 만진 색인은 "1"입니다.

여기서 검지 손가락을 들어 봅시다. 그러면 터치 정보가 다음과 같이 표시됩니다.

図 7 :人差し指を放す
그림 7: 집게 손가락 떼기

지금까지 눈치 채 셨겠지만 가운데 손가락으로 터치하는 정보의 색인은 "0"입니다. 캐릭터를 이동할 때 인덱스로 관리하면 위의 작업으로 다음과 같은 동작이 발생합니다.

집게 손가락으로 문자 "A"를 이동

그 상태에서 가운데 손가락으로 문자 "B"를 움직입니다.

가운데 손가락으로 캐릭터를 움직이면서 집게 손가락을 뗍니다.

가운데 손가락으로 조종하는 문자가 갑자기 "A"로 전환됩니다.

또 다른 현상은 두 손가락 중 하나를 터치하면서 반복적으로 손을 떼거나 터치하면 첫 번째 터치 정보의 그리기 텍스트가 깜박일 수 있다는 것입니다. 이는 두 번째 손가락이 인덱스 "0"을 터치하거나 놓는 순간 중단하기 때문입니다.

상술한 바와 같이, 멀티 터치시 터치 정보의 인덱스 및 순서는 터치되는 순서와 일치하지 않는다. 따라서 작업을 수행 하려는 경우 TouchCollection 인덱스에서 관리 하지 마십시오.

관리해야 할 것은 "TouchLocation"구조에는 "Id"속성이 있고 Id는 터치 할 때마다 새로운 값으로 다시 작성되지만 터치하는 동안 터치 포인트와 ID의 관계가 보장되므로 관리하겠습니다.

물론 ID로 관리해야한다는 의미는 아니며 경우에 따라 터치 위치만으로 충분합니다. 예를 들어 화면의 버튼만 터치하면 ID와 상관없이 터치 위치를 확인하여 버튼을 눌렀는지 확인할 수 있습니다. 그러나 드래그 처리를 포함 할 때 위치는 항상 변경되므로 여전히 ID로 결정해야한다고 생각합니다.

프로그램 - 터치 정보를 획득할 때 유의해야 할 사항 2(획득한 터치 정보 수)

기사의 프로그램에는 포함되어 있지 않지만 샘플에서는 화면 하단에 문자열 "GetMaxTouchCount"와 "동시에 획득 한 최대 터치 정보 수"를 그립니다. 이전에는 "TouchPanel.GetState" 메서드에서 가져온 최대 터치 정보 수가 표시되었지만 이 테스트 컴퓨터에서는 "TouchPanelCapabilities.MaximumTouchCount" 속성이 4이므로 여기에 표시되는 최대값은 일반적으로 4여야 합니다. 5 개의 손가락을 올려 놓으면 여전히 4가됩니다.

図 8 :5 本の指を置いたときの数値
그림 8: 다섯 손가락 숫자

약간의 실험을 해봅시다. 여러 손가락으로 터치 패널을 고속으로 반복해 보십시오. 테스트 기계에 따라 다르지만 그 수는 당신이 그것을 알기 전에 4를 초과할 수 있습니다.

図 9 :GetMaxTouchCount が 4 を超えている
그림 9: GetMaxTouchCount가 4보다 큽니다.

실제로 "TouchPanel.GetState" 메서드에서 얻은 터치 정보는 "TouchPanel.GetState" 메서드를 호출하는 순간의 터치 정보가 아니라 터치하는 순간과 마지막 업데이트 타이밍에서 해제하는 순간이 캐시됩니다. 따라서 최대 4개의 터치를 동시에 검색할 수 있더라도 동일한 손가락을 다시 터치하는 것은 별도의 터치로 처리되므로 TouchPanelCapabilities.MaximumTouchCount보다 더 많은 터치 정보를 얻을 수 있습니다.

따라서 TouchPanelCapabilities.MaximumTouchCount가 4인 경우에도 터치 관련 데이터의 배열 요소 개수가 4로 고정되면 처리 방법에 따라 인덱스 초과분 오류가 발생할 수 있습니다.

그건 그렇고, XNA Game Studio의 도움말에서 TouchCollection.Count 속성의 최대 값은 "8"로 설명되므로 배열의 요소 수를 수정하려면 요소 수를 8 이상으로 설정해야합니다. (향후 버전 업그레이드에 대해 생각하는 경우 인덱스가 초과되지 않도록 guard 절을 포함할 수 있습니다.)

이 샘플의 요약

이번에는 멀티 터치에서 얻은 정보에 대한 다양한 매개 변수를 조사했습니다. 또한 터치 패널 정보를 취득 할 때 유의해야 할 몇 가지 사항이 있음을 확인했습니다. 이 지식을 바탕으로 실제로 멀티 터치를 사용하는 샘플을 설명하고자합니다.