2

Angry Birds などのゲームでよく見られる 2 本指のスライド イン/アウト ジェスチャを使用してズーム機能を実装したいと考えています。今はスライダー ズームを使用していますが、単純なジェスチャほど気分が良くありません。だから私はモノゲームでのジェスチャーの実装を見ようとしましたが、説明された動作を達成するのに実際に何が役立つかわかりませんでした。

どんな助けでも大歓迎です、ありがとう!

4

1 に答える 1

6

簡単な答え:TouchPanelジェスチャ機能を使用してジェスチャを検出しPinch、結果のジェスチャを処理する必要があります。


長い答え...

GestureType.Pinchユーザー ジェスチャごとに複数のジェスチャ イベントが発生し、続いGestureType.PinchCompleteてユーザーが 1 つまたは両方の指を離したときに発生します。各Pinchイベントには、現在位置と各タッチ ポイントの位置変化の 2 組のベクトルがあります。ピンチの実際の変化を計算するには、各タッチ ポイントの以前の位置を逆算し、以前の状態と現在の状態でのタッチ ポイント間の距離を取得し、減算して合計の変化を取得する必要があります。これを元のピンチ タッチ ポイントの距離 (最初のピンチ イベントからのタッチ ポイントの元の位置) と比較して、合計距離の差を取得します。

最初に、ユーザーのピンチ ジェスチャの終了をキャプチャするかどうかに応じて、TouchPanel.EnabledGestures含めるプロパティを初期化してください。GestureType.PinchGestureType.PinchComplete

次に、これに似たもの (GameクラスのUpdateメソッドから呼び出される) を使用して、イベントを処理します。

bool _pinching = false;
float _pinchInitialDistance;

private void HandleTouchInput() 
{
    while (TouchPanel.IsGestureAvailable)
    {
        GestureSample gesture = TouchPanel.GetGesture();

        if (gesture.GestureType == GestureType.Pinch)
        {
            // current positions
            Vector2 a = gesture.Position;
            Vector2 b = gesture.Position2;
            float dist = Vector2.Distance(a, b);

            // prior positions
            Vector2 aOld = gesture.Position - gesture.Delta;
            Vector2 bOld = gesture.Position2 - gesture.Delta2;
            float distOld = Vector2.Distance(aOld, bOld);

            if (!_pinching)
            {
                // start of pinch, record original distance
                _pinching = true;
                _pinchInitialDistance = distOld;
            }

            // work out zoom amount based on pinch distance...
            float scale = (distOld - dist) * 0.05f;
            ZoomBy(scale);
        }
        else if (gesture.GestureType == GestureType.PinchComplete)
        {
            // end of pinch
            _pinching = false;
        }
    }
}

楽しい部分は、ズーム量を計算することです。2 つの基本的なオプションがあります。

  1. 上に示したように、倍率を使用して、現在のPinchイベントによって表される距離の生の変化に基づいてズームを変更します。これはかなり単純で、おそらく必要なことを実行します。この場合、_pinchingand_pinchInitialDistanceフィールドと関連するコードをおそらく削除できます。

  2. 元のタッチ ポイント間の距離を追跡し、現在の距離に基づいて初期距離のパーセンテージとしてズームを設定します ( float zoom = dist / _pinchInitialDistance; ZoomTo(zoom);) 。

どちらを選択するかは、現在ズームをどのように処理しているかによって異なります。

いずれの場合も、ズーム ポイントを画面の中心に固定するのではなく、タッチ ポイント間の中心点を記録してズームの中心として使用することもできます。または、本当に馬鹿げたことをしたい場合は、元のタッチ ポイント (aOldおよびbOld最初のPinchイベントから) を記録し、移動、回転、およびスケーリング操作を実行して、これらの 2 つのポイントが現在のタッチ ポイントに追従するようにします。

于 2013-09-19T09:05:25.043 に答える