次の方法で共有


Windowsストア アプリ 作り方解説 XNA編 第5回 ~ジェスチャーのシミュレート~

マイクロソフトの田中達彦です。
本連載では、Windows Phone 7用のXNAで開発したShoot EvoというゲームをWindowsストア アプリとして移植したときのポイントを紹介します。
本連載では、C#とXAMLを使用して同様のアプリを作っていきます。

[使用しているジェスチャー]
Shoot EvoのXNA版では、ジェスチャーとしてフリックとタップを使っています。
フリックは、画面をシュッと指でなぞる操作で、ボールを蹴るときに使っています。
タップは、画面を触る操作で、シュート後に画面を元に戻すときに使っています。

XNAでは、以下のようにフリックとタップを使用しています。

// タッチパネルの状況を検知する
while (TouchPanel.IsGestureAvailable)
{
    GestureSample gs = TouchPanel.ReadGesture();

// 画面がフリックされたかどうか
    if (gs.GestureType == GestureType.Flick)
    {
        // もしボールが動いていないときは、フリックに合わせてボールを動かす
        if (BallSpeed.X == 0 && BallSpeed.Y == 0)
        {
            BallSpeed.X = gs.Delta.X / 50;
            BallSpeed.Y = gs.Delta.Y / 50;

// シュートの情報を記録
            TotalShoot++;

CurrentShoot++;
            if (CurrentShoot > MaxShoot)
                CurrentShoot = 0;

ShootTime[CurrentShoot] = DateTime.Now;

break;
}
    }
    else if (gs.GestureType == GestureType.Tap && WaitCounter > 0)
    {
        WaitCounter = 0;
    }
}

フリックの時は、gs.Delta.Xとgs.Delta.YにX方向とY方向の移動量が入っています。
移動量とは、画面を触ってから離すまでの距離です。
それらの情報を使用してボールの方向とスピードを決め、BallSpeedフィールドに代入しています。

以下の部分で最後に50で割っているのは、ジェスチャーのスピードを適切なボールのスピードに変換するためです。
ここの数値を変更すると、ボールのスピードが変わります。

BallSpeed.X = gs.Delta.X / 50;

なおストア アプリ版では、ゲームバランスの調整のため、この50で割る部分の数値を変更しています。

[フリックのシミュレート]
Windowsストア アプリ版のShoot Eveでは、画面に触ったときに発生するPointerPressedイベントと、PointerReleasedイベントを使って、フリックをシミュレートしています。

イベントに対するイベントハンドラーは、Visual Studioを使用して以下の手順で作成します。
1. MainPage.xamlを表示します。
2. Pageタグの部分にキャレットを移動させます。
3. プロパティ ウィンドウで下図の赤い丸のイベントボタンをクリックします。
4. PointerPressedと書かれた部分を探し、その右側の部分をダブルクリックします。
    下図では右側の部分にPage_PointerPressed_1と書かれていますが、最初は空白です。
5. 手順1と2を繰り返し、PointerReleasedと書かれた部分を探し、その右側の部分をダブルクリックします。

これで、各イベントハンドラーがMainPage.xaml.csに作られました。
それぞれのイベントハンドラーとその上に、下記の黄色でマーカーしたコードを追加します。

Point PressedPoint = new Point();
Point MovePoint = new Point();
DateTime PressedTime = new DateTime();

private void Page_PointerPressed_1(object sender, PointerRoutedEventArgs e)
{
    PressedPoint = e.GetCurrentPoint(grid1).Position;
    PressedTime = DateTime.Now;
}

private void Page_PointerReleased_1(object sender, PointerRoutedEventArgs e)
{
    Point p = e.GetCurrentPoint(grid1).Position;

TimeSpan ts = DateTime.Now - PressedTime;

    MovePoint.X = (p.X - PressedPoint.X) / (ts.Milliseconds / 100.0);
    MovePoint.Y = (p.Y - PressedPoint.Y) / (ts.Milliseconds / 100.0);
}

これで、画面がフリックされたときにMovePointフィールドに移動量が入ります。
MovePointに入る移動量は、0.1秒の間に動いた距離です。
PointerPressed、PointerReleasedは、タッチだけでなくマウスでも発生するイベントです。
マウスでフリックのようなことをすると、ボールが飛んでいきます。

なお、ここではマルチタッチされたときを考慮していません。
単に、画面に触った、画面から手を離したという現象のみを見ています。

[タップのシミュレート]
画面のタップは、PointerReleasedイベントに置き換えています。
Shoot Eveでは、PointerReleasedのイベントハンドラーに以下の黄色のマーカーの部分のコードを足すことで、タップされたことを検知しています。
マウスでクリックしたときも、タップしたときと同じ動きをします。

private void Page_PointerReleased_1(object sender, PointerRoutedEventArgs e)
{
    Point p = e.GetCurrentPoint(grid1).Position;

TimeSpan ts = DateTime.Now - PressedTime;
           
    MovePoint.X = (p.X - PressedPoint.X) / (ts.Milliseconds / 100.0);
    MovePoint.Y = (p.Y - PressedPoint.Y) / (ts.Milliseconds / 100.0);

if (WaitCounter > 0)
        Restart = 1;
    else
        Restart = 0;
}

[前後の記事]
第4回 : キャラクターの描画
第6回 : 画面の構成
番外1 : Shoot Evo リリース1を公開
番外2 : Shoot Evoのソースコード / プロジェクト ファイルを公開

マイクロソフト
田中達彦