手の動きに合わせて画面上のキャラクターを操作するLeap Motionプログラムを作る

2013年11月7日(木)
薬師寺 国安

今回のアプリは、画面をTYPESWIPE(指を伸ばした状態の手で直線を描く動作)すると、1匹の亀が手の動作に合わせて向きを変えて移動するアプリと、3匹の亀の中から任意の亀を選択して、選択した亀を移動させる2つのサンプルを紹介します。早速開発手順を見ていきましょう。

手の動きに合わせて、亀が向きを変えて移動する

まずWPFプロジェクトを作成しよう

今回のLeap MotionアプリもWPFで作成します。

これには、Visual Studio 2012(以下、VS 2012)のIDEを起動して、メニューバーから[ファイル]−[新規作成]−[プロジェクト]と選択して、それにより表示される[新しいプロジェクト]ダイアログで「Visual Basic」のテンプレートから「WPF アプリケーション」を選択します(Leap Motionは、.NET Framework 3.5と4.0に対応しています。しかし、.NET Framework 4.5でも動作します。今回のアプリは全て.NET Framework 4.5で作成しています。しかし、あくまでも対応しているのは、.NET Framework 3.5と4.0です。心配な方は、.NET Framework 4.0で作成すると安心でしょう)。[名前]欄には、ここでは「kameMoveLeapMotion」と指定します。
現在では、無料のVisual Studio Express 2013(以下VS2013)が下記のサイトよりダウンロードできますので、VS2013でも開発が可能です。
→ Visual Studio Express 2013ダウンロードページ

ソリューション・エクスプローラー内にImagesというフォルダを作成して、上向き、下向き、右向き、左向きの、4枚の亀のpng画像を配置しています。

ダウンロードされたサンプルファイルには、これらの画像ファイルは追加済みです。

WPFの基本的な作成手順は、「画面上の図形を5本の指で操作する基本的なLeap Motionプログラムを作る」と同じ手順となるので、説明を割愛します。具体的な手順は、第1回の「参照の追加」「プロジェクトのルートに「LeapCSharp.dll」と「Leapd.dll」を追加する」「プロパティを設定する」を参考にしてください。

今回のLeap Motionアプリについて

今回のアプリは、5本の指で、画面を空中で上下、左右に動かすと、1匹の亀が現れて、手の動きに合わせて向きを変えて移動するアプリです。亀の動きが速いので、上下左右にと手はゆっくりと動かしてください(図1参照)。

図1:TYPESWIPEで5本の指の動きに合わせて亀が向きを変えて移動する(クリックで拡大)

実際に動かした動画は次のようになります。

今回も「コールバック方式」を用いています。第1回のサンプルの「コールバック方式の採用」を参照してください。またコールバックメソッド等については、Build Insiderの「C#開発者から見たLeap Motion開発のファースト・インプレッション」を参照してください。

画面のレイアウト(MainWindow.xaml)

Image1と言う名前のImageコントロールを配置します。SourceにkameSourceをバインディング、Canvas.LeftにkameLeftをバインディング、Canvas.TopにkameTopをバインディング、Canvas.RightにkameRightをバインディング、Canvas.BottomにkameBottomをバインディングします。バインディングする名称は、後ほど作成する「kameUpDownRightLeftModel.vb 」クラス内で定義するプロパティ名です(リスト1参照)。

リスト1(MainWindow.xaml)

<Window x:Class="MainWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="MainWindow" Height="1080" Width="1920" WindowState="Maximized">
    <Canvas>
      <Image x:Name="Image1" Stretch="None" Source="{Binding kameSource}" Canvas.Left="{Binding kameLeft}" Canvas.Top="{Binding kameTop}" Canvas.Right="{Binding kameRight}" Canvas.Bottom="{Binding kameBottom}"/>
    </Canvas>
</Window>

画面上には何も表示はされないので、レイアウト図は省略します。

クラスの作成(SwipeDirection.vb)

では、次にクラスを作成していきます。ソリューション・エクスプローラー内のkameMoveLeapMotionプロジェクトを選択して、マウスの右クリックで表示されるメニューから[追加]−[クラス]と選択します。表示される画面から[クラス]を選択し、[名前]に[SwipeDirection.vb] と指定して[追加]ボタンをタップします。

SwipeDirection.vbのプログラム・コード

Enum列挙体は値を定義するための入れ物として使用する、特殊なクラスです。列挙体が便利なのはプログラム中に入力候補が自動的に表示される点です。

SwipeDirection.vb列挙体の中に、「Up」、「Down」、「Left」、「Right」という値を入れておきます(リスト2参照)。

リスト2(SwipeDirection.vb) 列挙体を記述したコード

Public Enum SwipeDirection
  Up
  Down
  Left
  Right
End Enum

クラスの作成(LeapListener.vb)

次に、第1回で、SwipeDirection.vbを作成した方法で、LeapListener.vbクラスを作成しますが、第1回のサンプルと同じコードが含まれているので、第1回のLeapListener.vbクラスを使用します。

ソリューション・エクスプローラー内で、kameMoveLeapMotionプロジェクトを選択し、マウスの右クリックで表示されるメニューから、[追加]-[既存の項目]と選択して、第1回で作成しておいたLeapListener.vbを取り込みます。

以下、第1回のサンプルのLeapListener.vbと異なる点のみ解説します。

(1)「Dim swipe As New SwipeGesture(gst)」の下に手をRight、Left、Up、Downした時の処理を追加します(リスト3参照)

上記の変更を行った後、リスト3のコードを作成します。

LeapListener.vbのプログラム・コード

リスト3(LeapListener.vb)

・・・・コード略・・・・
  Public Overrides Sub OnConnect(ctlr As Controller)
    ・・・第1回と同じなので割愛します・・・
  End Sub
  
  Public Overrides Sub OnFrame(ctlr As Controller)
      ・・・・コード略・・・・
    If (Not fingers.IsEmpty) Then
              Dim gestures As GestureList = currentFrame.Gestures
              For Each gst As Gesture In gestures
                ' GestureTypeがTYPESWIPEの時の処理
                If gst.Type = Gesture.GestureType.TYPESWIPE Then
                  Dim swipe As New SwipeGesture(gst)
                  If (Math.Abs(swipe.Direction.x) > Math.Abs(swipe.Direction.y)) Then
                    ' 手を右に振った時の処理
                      If (swipe.Direction.x > 0) Then
                          SwipeAction(fingers, SwipeDirection.Right)
                      Else
                   ' 手を左に振った時の処理
                                   SwipeAction(fingers, SwipeDirection.Left)
                      End If
                  Else
                    ' 手を上に振った時の処理
                      If (swipe.Direction.y > 0) Then
                          SwipeAction(fingers, SwipeDirection.Up)
                      Else
                    ' 手を下に振った時の処理
                      SwipeAction(fingers, SwipeDirection.Down)
                  End If
                End If
                Exit For
              End If
            Next
          End If   
  ・・・・コード略・・・・
  End Sub

' SwipeEventデリゲート経由で、LeapSwipeメソッドを呼び出す。
  第1回と同じコードのため割愛します。

' GestureTypeがTYPESWIPEであった場合は、スワイプの方向で条件分岐を
' 行うSwipeActionメソッドの処理。
Private Sub SwipeAction(ByVal fingers As FingerList, ByVal sd As SwipeDirection)
      fingersCount = fingers.Count
      If (fingersCount = 5) Then' 指5本で操作する
        Select Case sd
          Case SwipeDirection.Left
            ' RaiseEventで手を左に振った時のLeapSwipeイベントを発生させる。
              RaiseEvent LeapSwipe(SwipeDirection.Left)
              Exit Select
          Case SwipeDirection.Right
            ' RaiseEventで手を右に振った時のLeapSwipeイベントを発生させる。
                RaiseEvent LeapSwipe(SwipeDirection.Right)
              Exit Select
          Case SwipeDirection.Up
            ' RaiseEventで手を上に振った時のLeapSwipeイベントを発生させる。
              RaiseEvent LeapSwipe(SwipeDirection.Up)
              Exit Select
          Case SwipeDirection.Down
            ' RaiseEventで手を下に振った時のLeapSwipeイベントを発生させる。
              RaiseEvent LeapSwipe(SwipeDirection.Down)
              Exit Select
          End Select
        End If
    End Sub

クラスの作成(kameUpDownRightLeftModel.vb)

第1回のサンプルの、SwipeDirection.vbを作成した方法で、kameUpDownRightLeftModel.vbクラスを作成します。

第1回の「UpDownModel.vb」と同じコードが多いので異なる個所のみ解説します。

各プロパティを定義します。kameTopとkameLeft、kameRight、kameBottomプロパティを定義し、INotifyPropertyChangedインターフェースに各プロパティの名前を指定しておきます。また、BitmapImage型のkameSourceプロパティも定義し、INotifyPropertyChangedインターフェースにプロパティの名前を指定しておきます。

次はSwipeActionメソッドの処理です。

  • Enum列挙体で値を定義していた、SwipeDirectionの値で条件分岐を行います。
  • dispatcher.Invokeを使って、ワーカースレッドからUIスレッドに処理を任せます。
  • Upの場合はImagesフォルダ内の上向きの亀を表示させ、kameTopの値を5ずつ減少させます。
  • Downの場合はImagesフォルダ内の下向きの亀を表示させ、kameTopの値を5ずつ増加させます。
  • leftの場合はImagesフォルダ内の左向きの亀を表示させ、kameLeftの値を5ずつ減少させます。Rightの場合はImagesフォルダ内の右向きの亀を表示させ、kameRightの値を5ずつ増加させます。

以下第1回と同じ解説のため割愛します

  • 画面上のキャラクターを手の動きに合わせて操作するLeap Motionプログラム(1)

  • 手の動きに合わせて画面上のキャラクターを操作するLeap Motionプログラム(2)

薬師寺国安事務所

薬師寺国安事務所代表。Visual Basic プログラミングと、マイクロソフト系の技術をテーマとした、書籍や記事の執筆を行う。
1950年生まれ。事務系のサラリーマンだった40歳から趣味でプログラミングを始め、1996年より独学でActiveXに取り組む。1997年に薬師寺聖とコラボレーション・ユニット PROJECT KySS を結成。2003年よりフリーになり、PROJECT KySS の活動に本格的に参加、.NETやRIAに関する書籍や記事を多数執筆する傍ら、受託案件のプログラミングも手掛ける。Windows Phoneアプリ開発を経て、現在はWindows ストア アプリを多数公開中

Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。Microsoft MVP for Development Platforms - Windows Phone Development(Oct 2012-Sep 2013)。Microsoft MVP for Development Platforms - Client Development(Oct 2013-Sep 2014)。Microsoft MVP for Development Platforms-Windows Platform Development (Oct 2014-Sep 2015)。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています