Докосване взаимодействия в разработването на игри за Windows Phone 7 Част 4 щипка

Страницата се актуализира :
Дата на създаване на страница :

Програмен! - 4.Щипка, разтягане до мащаб спрайтове

За тази проба

Съвременните смартфони, като например визуализаторите на изображения, ви позволяват да увеличите и свиете изображението, като използвате два пръста, за да увеличите или свиете разстоянието между пръстите си. Можете да направите същото с Internet Explorer в Windows Phone 7. Това действие се нарича "щипка, разтягане" в Windows Phone 7.

В допълнение към прищипване и разтягане, можете също да използвате действия като "докоснете", за да докоснете за кратко (докоснете) една точка на екрана и "прелистете", за да проследите бързо екрана. Тези действия колективно се наричат жестове.

В тази програма бих искал да увелича и намаля спрайт, показан на екрана чрез тази операция за щипване и разтягане. Също така, до последния път, директно получих информацията от сензорния панел и я обработих, но този път бих искал да се справя с докосване с помощта на методи, посветени на жестове.

Цели на тази примерна програма

Захванете и разтегнете операциите за уголемяване и свиване на спрайт.

図 1 :ストレッチでスプライトを拡大
Фигура 1: Разтегнете, за да увеличите спрайт

Програма - Деклариране на полета

В декларацията на полето няма нов клас, но той има "централната координата на текстурата", "увеличението на спрайта" и "разстоянието между последните две позиции на допир при прищипване".

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

/// <summary>
/// テクスチャーの中心座標
/// </summary>
Vector2 textureCenterPos;

/// <summary>
/// スプライトのスケール
/// </summary>
float scale = 1;

/// <summary>
/// 前回の 2 点間の距離
/// </summary>
float previousLength = 0;

Програма - Активиране на жестове

Този път ще извършим процес само с жестове, но в състояние по подразбиране не може да се използва нито един от жестовете. За да извлечете информация за всеки жест, трябва да зададете жеста да се използва за свойството TouchPanel.EnabledGestures.

// タッチパネルでピンチのジェスチャーを有効にする
TouchPanel.EnabledGestures = GestureType.Pinch | GestureType.PinchComplete;

Активирането на всички жестове влияе на производителността, затова се уверете, че сте задали само жестовете, които искате да използвате. Тук "GestureType.Pinch" е настроен да получава информация за операцията на щипката, а "GestureType.PinchComplete" е настроен да показва, че процесът на щипване е завършен. Местоположението на настройката е зададено в конструктора на играта.

Програма - Зареждане на текстури

Зареждането на текстури е същото като преди, но този път изчисляваме "централната координата на текстурата". Това е така, защото при мащабиране на спрайт, той се мащабира с централната координата като произход.

// テクスチャーをコンテンツパイプラインから読み込む
texture = Content.Load<Texture2D>("Texture");

// テクスチャーの中心座標を求める
textureCenterPos = new Vector2(texture.Width / 2, texture.Height / 2);

Програма - Получаване на информация за жестове

Получаваме информация за жестове (щипка тук) в метода Game.Update. Обработката с жестове е под формата на повтаряне на толкова жестове, колкото сте активирали. Структурата "TouchCollection", която е била използвана до последния път, не се използва.

// 次のジェスチャー情報が取得できる場合は true を返し続けます
while (TouchPanel.IsGestureAvailable)
{
  // 次のジェスチャー情報を読み込みます
  GestureSample gs = TouchPanel.ReadGesture();
  
  switch (gs.GestureType)
  {
    case GestureType.Pinch:
      // ここにピンチ処理を記述します
      break;
    case GestureType.PinchComplete:
      // ここにピンチ完了処理を記述します
      break;
  }
}

Проверете състоянието на свойството TouchPanel.IsGestureAvailable в цикъла while за информация за жестове и проверете дали е налице следната информация за жестове: Ако имате следната информация за жестове, използвайте метода "TouchPanel.ReadGesture", за да получите информацията за жестовете.

"GestureSample.GestureType" съхранява информация за това кой тип жест е включен, така че разклонете процеса с изявление за превключване, базирано на него. В тази извадка конструкторът задава "GestureType.Pinch" и "GestureType.PinchComplete" към свойството "TouchPanel.EnabledGestures", така че те са разклонени съответно.

Програма - Обработка с жестове за щипка

По-бързо е да погледнем коментарите в кода за това, което правим, но за да обобщим това, което правим, откриваме разликата между разстоянието между предишните две точки на съприкосновение и разстоянието на допир между двете точки този път и използваме тази разлика, за да увеличим или намалим стойността на скалата.

case GestureType.Pinch:
  // 現在の2点間の距離を求めます
  float nowLength = (gs.Position - gs.Position2).Length();

  if (previousLength == 0)
  {
    // 前回の2点間の距離が 0 の場合は
    // 現在の2点間の距離を設定します
    // 初回はスケール計算を行いません
    previousLength = nowLength;
  }
  else
  {
    // 前回の2点間の距離との差分を計算します
    float diffLength = nowLength - previousLength;
    
    // ピンチ、ストレッチした距離に応じて
    // スケールを変化させています
    // 補正値は適当に設定します
    scale = MathHelper.Max(scale + diffLength / 150, 0);
    
    // 今回の距離を次の計算のために保持します
    previousLength = nowLength;
  }
  break;

Двете сензорни позиции могат да бъдат получени съответно с "GestureSample.Position" и "GestureSample.Position2". Можете да извадите разликата между двата получени вектора и да намерите разстоянието между двете точки, като извикате метода "Vector2.Length".

Между другото, тук определяме предишното разстояние като 0, когато не се извършва прищипване, така че процесът се разклонява при стартиране на прищипване и във втория и следващите цикли. Това е така, защото за първи път на прищипване, няма предишно разстояние, така че няма нужда да се мащабира.

Също така, този път използваме само две свойства, "GestureSample.Position" и "GestureSample.Position2", но има и "GestureSample.Delta" и "GestureSample.Delta2" свойства, които могат да получат информация за разликата от предишната позиция на докосване. Има две свойства всяка, но това е за мултитъч, а за жестове, които използват само едно докосване, ще използвате свойства без "2".

Програма - Обработка, когато жестът за щипване завърши

Когато жестът на щипка е завършен (освобождаване на всеки пръст от сензорния панел), разстоянието между предишните две точки се връща на 0. Първоначално може да е по-добре да използвате отделен флаг, но тъй като е физически невъзможно да се докосне една и съща позиция с два пръста, разстоянието от 0 се определя като не притискане. (Ако разделителната способност е ниска, може да е възможно да се докосне до една и съща позиция ...)

case GestureType.PinchComplete:
  // ピンチが終了した場合は保持している距離を 0 に戻して
  // 完了したことにします
  previousLength = 0;
  break;

Програма - Рисуване Спрайтс

Тук няма да навлизам в много подробности, защото става въпрос само за рисуване на спрайт, но поставих спрайт в центъра на екрана и начертах изчислената стойност на скалата, като я разширих и свих с центъра на спрайт като произход.

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

// スプライトを描画する
spriteBatch.Draw(texture,
                 new Vector2(graphics.PreferredBackBufferWidth / 2,
                             graphics.PreferredBackBufferHeight / 2),
                 null,
                 Color.White,
                 0.0f,
                 textureCenterPos,
                 scale,
                 SpriteEffects.None,
                 0.0f);

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

Резюме на тази извадка

Този път обяснихме процеса, посветен на жестовете. В пробата създаваме само процес на щипване, но има и "движения" и "задържания". За да разберете какви жестове са налични, разгледайте XNA Game Studio 4.0 Help for GestureType enums.

Можете да реализирате същото нещо от информацията за докосване, получена от метода TouchPanel.GetState, без да използвате специфични за жестовете методи или структури, но в този случай ще трябва сами да изчислите скоростта на управление на мултитъч ID, времето за докосване, движенията и т.н. Чрез използването на специфични за жестовете методи тези реализации могат да бъдат опростени, а има и предимството, че всички игри и приложения могат да се управляват по един и същи начин.

Когато сами създавате процес на сензорен панел, ако можете да замените подобен процес като жест, препоръчваме ви да го използвате.

Програмен! - 5.Щипка за завъртане на спрайтове

За тази проба

Притискането обикновено се отнася до "прищипване" и "разтягане", но процесът на щипване на XNA Game Studio 4.0 не ограничава конкретно процеса до тези две, така че можете също да извършвате операции, които обикалят една точка на съприкосновение около друга точка на съприкосновение.

Тук бих искал да завъртя спрайт с този метод на работа. Между другото, този път не се появиха нови методи или класове и се основава на предишното мащабиране.

В описанието на примерния код в тази статия се пропускат същите части като предишната извадка за мащабиране.

Цели на тази примерна програма

Чрез завъртане на двете допирни точки спрайтът се върти. Предишната операция по мащабиране също работи.

図 2 :タッチポイントを回してスプライトを回転させています
Фигура 2: Завъртане на спрайт чрез завъртане на точката на съприкосновение

Програма - Деклариране на полета

"Количеството на въртене на спрайт" и "Последен ъгъл на въртене" се добавят към предишната програма за мащабиране. Всички ъгли се изчисляват в радиани.

/// <summary>
/// スプライトの回転量(radian)
/// </summary>
float rotate;

/// <summary>
/// 前回の回転角度(radian)
/// </summary>
float previousAngle;

Програма - Ротационен процес

Процесът на въртене се извършва по време на жестове за щипване по същия начин, както при мащабиране.

Няма да навлизам в твърде много подробности за изчисляването на въртенето, защото това е математическа история, но можете да получите ъгъла радиан с метода "Math.Atan2", като намерите диференциалния вектор от точка на съприкосновение 1 до точка на съприкосновение 2. Намерете разликата между получения ъгъл и предварително придобития ъгъл и го добавете към ъгъла на въртене на спрайт.

switch (gs.GestureType)
{
  case GestureType.Pinch:
    //===== スケール計算 =====//
    // 前回と同じなので省略

    //===== 回転計算 =====//

    // 2点間のベクトルを求めます
    Vector2 pinchVector = gs.Position2 - gs.Position;

    // Atan2 で角度を求めます
    float nowAngle = (float)Math.Atan2(pinchVector.Y,
                                       pinchVector.X);

    if (previousAngle == 0)
    {
      // 前回の角度が 0 の場合は
      // 現在の角度を設定します
      // 初回は回転計算を行いません
      previousAngle = nowAngle;
    }
    else
    {
      // 前回の角度との差分をスプライトの回転角度に加算します
      rotate += nowAngle - previousAngle;

      // 今回の距離を次の計算のために保持します
      previousAngle = nowAngle;
    }
    break;
  case GestureType.PinchComplete:
    // ピンチが終了した場合は保持している距離、角度を 0 に戻して
    // 完了したことにします
    previousLength = 0;
    previousAngle = 0;
    break;
}

Програма - Рисуване Спрайтс

Няма големи промени в рисуването на спрайтове. Петият аргумент на метода SpriteBacth.Draw е настроен на изчисления ъгъл на въртене.

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

// スプライトを描画する
spriteBatch.Draw(texture,
                 new Vector2(graphics.PreferredBackBufferWidth / 2,
                             graphics.PreferredBackBufferHeight / 2),
                 null,
                 Color.White,
                 rotate,
                 textureCenterPos,
                 scale,
                 SpriteEffects.None,
                 0.0f);

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

Резюме на тази извадка

Този път се опитах да завъртя спрайт чрез операция за щипка. Ние не използваме никакви нови класове по-специално, но се надявам, че разбирате, че можем да реализираме приложена обработка въз основа на предоставените функции.

Най-сетне

Преминахме през проби и демонстрирахме внедряването на взаимодействия с докосване с помощта на Windows Phone 7 и XNA Game Studio 4.0. Съдържанието включваше придобиване на докосване с едно докосване и мултитъч докосване и манипулиране на сензорна информация и обработка чрез манипулиране на жестове с докосване с помощта на специфични за жестовете методи.

Този път се съсредоточих върху сензорния панел, но все още има някои функции, които все още не съм въвел. Windows Phone 7 включва и нови функции за въвеждане в XNA Game Studio 4.0, като например въвеждане на акселерометър и гласово въвеждане. Има някои интересни функции, които не можах да представя този път, така че моля, насладете се на проучването на функциите, които искате да използвате.