Interactions tactiles dans le développement de jeux pour Windows Phone 7 Partie 4 Pincement

Page mise à jour :
Date de création de la page :

Programmation! - 4.Pinch, étirement à l’échelle des sprites

À propos de cet exemple

Les smartphones modernes, tels que les visionneuses d’images, vous permettent d’agrandir et de réduire une image en utilisant deux doigts pour augmenter ou réduire la distance entre vos doigts. Vous pouvez faire de même avec Internet Explorer sur Windows Phone 7. Cette action est appelée « pincer, étirer » dans Windows Phone 7.

En plus de pincer et d’étirer, vous pouvez également utiliser des actions telles que « taper » pour toucher brièvement (appuyer) un point de l’écran et « glisser » pour tracer rapidement l’écran. Ces actions sont collectivement appelées gestes.

Dans ce programme, je voudrais agrandir et réduire le sprite affiché à l’écran par cette opération de pincement et d’étirement. Aussi, jusqu’à la dernière fois, j’obtenais directement les informations de l’écran tactile et les traitais, mais cette fois je souhaitais gérer les opérations tactiles en utilisant des méthodes dédiées aux gestes.

Objectifs de cet exemple de programme

Pincez et étirez les opérations pour agrandir et réduire le sprite.

図 1 :ストレッチでスプライトを拡大
Figure 1 : étirement pour agrandir le sprite

Programme - Déclaration de champs

Il n’y a pas de nouvelle classe dans la déclaration de champ, mais elle a « la coordonnée centrale de la texture », « le grossissement du sprite » et « la distance entre les deux dernières positions tactiles lors du pincement ».

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

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

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

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

Programme - Activation des gestes

Cette fois, nous allons effectuer un processus de geste uniquement, mais dans l’état par défaut, aucun des gestes ne peut être utilisé. Pour récupérer chaque information de mouvement, vous devez définir le mouvement à utiliser pour la propriété TouchPanel.EnabledGestures.

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

L’activation de tous les gestes affecte les performances, alors assurez-vous de définir uniquement les gestes que vous souhaitez utiliser. Ici, « GestureType.Inch » est défini pour obtenir des informations sur l’opération de pincement et « GestureType.PinchComplete » est défini pour indiquer que le processus de pincement est terminé. L’emplacement du paramètre est défini dans le constructeur du jeu.

Programme - Chargement des textures

Le chargement des textures est le même qu’auparavant, mais cette fois, nous calculons la « coordonnée centrale de la texture ». En effet, lors de la mise à l’échelle d’un sprite, il est mis à l’échelle avec la coordonnée centrale comme origine.

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

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

Programme - Obtenir des informations sur les gestes

Nous obtenons des informations gestuelles (pincez ici) dans la méthode Game.Update. Le traitement des gestes consiste à répéter autant de gestes que vous avez activés. La structure « TouchCollection » qui a été utilisée jusqu’à la dernière fois n’est pas utilisée.

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

Vérifiez l’état de la propriété TouchPanel.IsGestureAvailable dans la boucle while pour obtenir des informations sur les mouvements et vérifiez si les informations de mouvement suivantes sont présentes : Si vous disposez des informations de mouvement suivantes, utilisez la méthode « TouchPanel.ReadGesture » pour obtenir les informations de mouvement.

« GestureSample.GestureType » stocke des informations sur le type de mouvement inclus, donc branchez le processus avec une instruction switch basée sur celui-ci. Dans cet exemple, le constructeur affecte aux énumérations « GestureType.Pinch » et « GestureType.PinchComplete » la propriété « TouchPanel.EnabledGestures », afin qu’elles soient respectivement ramifiées.

Programme - Gestion des gestes de pincement

Il est plus rapide de regarder les commentaires dans le code pour ce que nous faisons, mais pour résumer ce que nous faisons, nous trouvons la différence entre la distance entre les deux points de contact précédents et la distance du point de contact entre les deux points cette fois, et utilisons cette différence pour augmenter ou diminuer la valeur de l’échelle.

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;

Les deux positions tactiles peuvent être obtenues avec « GestureSample.Position » et « GestureSample.Position2 », respectivement. Vous pouvez soustraire la différence entre les deux vecteurs obtenus et trouver la distance entre les deux points en appelant la méthode « Vector2.Length ».

Soit dit en passant, nous définissons ici la distance précédente comme 0 lorsque le pincement n’est pas effectué, de sorte que le processus est ramifié lorsque le pincement est lancé et dans la deuxième boucle et les suivantes. En effet, la première fois que vous pincez, il n’y a pas de distance précédente, il n’est donc pas nécessaire d’évoluer.

En outre, cette fois, nous n’utilisons que deux propriétés, « GestureSample.Position » et « GestureSample.Position2 », mais il existe également les propriétés « GestureSample.Delta » et « GestureSample.Delta2 », qui peuvent obtenir les informations de différence de la position tactile précédente. Il y a deux propriétés chacune, mais c’est pour le multi-touch, et pour les gestes qui n’utilisent qu’une seule touche, vous utiliserez des propriétés sans « 2 ».

Programme - Manipulation lorsque le geste de pincement est terminé

Lorsque le geste de pincement est terminé (relâchant l’un ou l’autre doigt de l’écran tactile), la distance entre les deux points précédents est rétablie à 0. À l’origine, il peut être préférable d’utiliser un drapeau séparé, mais comme il est physiquement impossible de toucher la même position avec deux doigts, la distance de 0 est définie comme ne pas pincer. (Si la résolution est faible, il peut être possible de toucher la même position...)

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

Programme - Sprites de dessin

Je n’entrerai pas trop dans les détails ici parce qu’il s’agit juste de dessiner le sprite, mais j’ai placé le sprite au centre de l’écran et dessiné la valeur d’échelle calculée en l’agrandissant et en la réduisant avec le centre du sprite comme origine.

// スプライトの描画準備
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();

Résumé de cet exemple

Cette fois, nous avons expliqué le processus dédié aux gestes. Dans l’exemple, nous ne créons qu’un processus de pincement, mais il y a aussi des « flicks » et des « holds ». Pour savoir quels mouvements sont disponibles, consultez l’aide de XNA Game Studio 4.0 pour les énumérations GestureType.

Vous pouvez implémenter la même chose à partir des informations tactiles obtenues à partir de la méthode TouchPanel.GetState sans utiliser de méthodes ou de structures spécifiques aux mouvements, mais dans ce cas, vous devrez calculer vous-même la vitesse de gestion des identifiants multi-touch, le temps tactile, les effleurements, etc. En utilisant des méthodes spécifiques aux gestes, ces implémentations peuvent être simplifiées, et il y a aussi l’avantage que tous les jeux et applications peuvent être utilisés de la même manière.

Lorsque vous créez vous-même un processus d’écran tactile, si vous pouvez substituer un processus similaire en tant que geste, nous vous recommandons de l’utiliser.

Programmation! - 5.Pincée pour faire pivoter les sprites

À propos de cet exemple

Le pincement fait généralement référence au « pincement » et à l'"étirement », mais le processus de pincement de XNA Game Studio 4.0 ne limite pas spécifiquement le processus à ces deux-là, vous pouvez donc également effectuer des opérations qui entourent un point de contact autour d’un autre point de contact.

Ici, je voudrais faire pivoter le sprite avec cette méthode d’opération. À propos, aucune nouvelle méthode ou classe n’est apparue cette fois, et elle est basée sur la mise à l’échelle précédente.

Dans la description de l’exemple de code dans cet article, les mêmes parties que l’exemple de mise à l’échelle précédent sont omises.

Objectifs de cet exemple de programme

En faisant pivoter les deux points de contact, le sprite tourne. L’opération de mise à l’échelle précédente fonctionne également.

図 2 :タッチポイントを回してスプライトを回転させています
Figure 2 : rotation du sprite en tournant le point de contact

Programme - Déclaration de champs

« Quantité de rotation des sprites » et « Dernier angle de rotation » sont ajoutés au programme de mise à l’échelle précédent. Tous les angles sont calculés en radians.

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

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

Programme - Processus de rotation

Le processus de rotation est effectué pendant les gestes de pincement de la même manière que lors de la mise à l’échelle.

Je n’entrerai pas trop dans les détails sur le calcul de la rotation parce que c’est une histoire mathématique, mais vous pouvez obtenir le radian d’angle avec la méthode « Math.Atan2 » en trouvant le vecteur de différence du point de contact 1 au point de contact 2. Trouvez la différence entre l’angle obtenu et l’angle précédemment acquis et ajoutez-la à l’angle de rotation du sprite.

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;
}

Programme - Sprites de dessin

Il n’y a pas de changements majeurs dans le dessin des sprites. Le cinquième argument de la méthode SpriteBacth.Draw est défini sur l’angle de rotation calculé.

// スプライトの描画準備
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();

Résumé de cet exemple

Cette fois, j’ai essayé de faire pivoter le sprite par pincement. Nous n’utilisons pas de nouvelles classes en particulier, mais j’espère que vous comprenez que nous pouvons réaliser un traitement appliqué basé sur les fonctions fournies.

Enfin

Nous avons parcouru des exemples et démontré la mise en œuvre des interactions tactiles à l’aide de Windows Phone 7 et XNA Game Studio 4.0. Le contenu comprenait l’acquisition et la manipulation tactiles tactiles uniques et multipoints des informations tactiles, ainsi que le traitement par manipulation gestuelle tactile à l’aide de méthodes spécifiques aux gestes.

Cette fois, je me suis concentré sur l’écran tactile, mais il y a encore quelques fonctions que je n’ai pas encore introduites. Windows Phone 7 inclut également de nouvelles fonctionnalités d’entrée dans XNA Game Studio 4.0, telles que l’entrée accéléromètre et l’entrée vocale. Il y a quelques fonctionnalités intéressantes que je n’ai pas pu présenter cette fois, alors s’il vous plaît profiter d’explorer les fonctions que vous voulez utiliser.