Kinectでキューブを再生します



IT業界の急速な発展に驚くこともあります。 比較的最近、TechDaysワークショップの1つで、 Evgeny MarchenkovがNatalプロジェクトに関する最初のビデオを公開したことを覚えています。 この名前を覚えている人は何人いますか? 実際、このプロジェクトはKinectとして知られています!



Kinect



このセンサーはXbox 360コンソール用に開発され、2012年2月以降はパーソナルコンピューターで使用できます。 少し前まで、センサーを評価してコードを書く機会がありました。



SDKのレビューに関するシリーズの以前の記事をすでに読んでいると思います。 Kinectを実際に試してみましょう! この記事では、小さなサイコロゲームを作成する方法について説明します。 そしてもちろん、キューブはあなたの手で動きます!



そのため、まずセンサーのSDKが必要です。これは公式サイトからダウンロードできます。 SDKには、多数の例とドキュメントがあります。 Coding4Fun クイックスタートシリーズもご覧ください。 また、codeplexの初心者向けKinectペイントでは、コードをダウンロード、コンパイル、学習できます。



私が絶対に邪魔されたくないのは、ゲームの物理学です。 しかし、彼女なしでも、なんとなく悲しい。 ソリューションは非常に簡単です-既製のライブラリを使用してください。 SilverlightおよびWindows Phone用の優れた物理ヘルパープロジェクトがあります。 残念ながら、現在のバージョン(4.0)はWPFをサポートしていません(このテーマに関する著者のコメントはこちら )が、以前のバージョンではサポートされていました。 したがって、WPFをサポートしたバージョンのソースコードを取得し、プロジェクトを.NET 4.0にアップグレードし、アセンブリをコンパイルできます。 記事の最後にある更新されたプロジェクトへのリンク。



Visual Studio 2010では、新しいWPFアプリケーション(C#)プロジェクトを作成します。 SDKの例には、Microsoft.Samples.Kinect.WpfViewersプロジェクトが含まれています。 その中には、カメラとセンサーマイク(ビューアー)を操作するための既製のコントロール、およびセンサーとの接続ロジックをカプセル化する要素(選択)があります。 このプロジェクトをソリューションに追加します。 起こったことは次のとおりです。



ソリューションエクスプローラー



[ツールボックス]ウィンドウでは、WpfViewersのコントロールを使用できます。



画像



次に、MainWindows.xamlでルートグリッドをCanvasに置き換え、その上にキューブを描画します。 KinectSensorChooserおよびKinectColorViewer要素をフォームに配置して、センサーに接続し、カメラからのビデオストリームを表示します。







バインディングに注意してください。 KinectColorViewerクラスのKinectプロパティをKinectSensorChooserクラスのKinectプロパティに関連付ける必要があります。 そのため、カラービューアーは、現在どのセンサーを使用しているかを把握できます。 必要なスレッドの初期化を追加するだけです。 これはKinectSensorChangedイベントハンドラー(KinectSensorChooserクラス)で実行できます。これにより、接続時にセンサーを初期化できます。 一般的に、これは次のように行われます。



sensor.ColorStream.Enable(); //   sensor.SkeletonFrameReady += SkeletonsReady; //   ,           sensor.SkeletonStream.Enable(); //   sensor.Start(); //  
      
      





有効なスレッドメソッドはオーバーロードされ、デフォルトの動作を変更するパラメーターを渡すことができます。 したがって、ColorStreamのオーバーロードされたEnableメソッドは、 ColorImageFormatの列挙のを使用して、画像形式(RGBまたはYUV)とその解像度を構成します。



技術的には、これでアプリケーションを起動し、Kinectの視野に入るもののビデオを見るのに十分です。



ゲームで物理を使用するには、まず、プロジェクトにアセンブリリンクを追加します:Physics HelperライブラリからFarseerPhysics、Spritehand.FarseerHelper、Spritehand.PhysicsBehaviorsを実行します。 ここで長方形を描きます-あなたが好きなように、それは床または地球になります。 PhysicsObjectBehavior物理オブジェクトの動作をそれに追加し、IsStaticプロパティをtrueに設定します。 Physics Helperの詳細については説明しませんが、ライブラリページでビデオチュートリアルを見ることができます。 キューブは、xamlマークアップまたはC#コードで指定できます。 主なことは、新しく作成されたキューブの物理的な動作の必要性を忘れないことです。



 private void CreateCube() { var cube = new Rectangle { Name = string.Format("PART_Cube_{0}", Guid.NewGuid().ToString("N")), Width = CubeSide, Height = CubeSide, Fill = new SolidColorBrush(Colors.Red), Stroke = new SolidColorBrush(Colors.Black), StrokeThickness = 3, RadiusX = CubeCornerRadius, RadiusY = CubeCornerRadius }; var behavior = new PhysicsObjectBehavior { IsStatic = false }; behavior.Attach(cube); PART_LayoutRoot.Children.Add(cube); }
      
      





次に進む前に、フィールドを横切る手の動きを表示するカーソルを作成します。 既製の写真を撮るか、 Path要素を使用してカーソルを美しく描画できます。 Pathで写真を撮ったり、美しく描いたりしませんでしたが、3番目の方法でPathをrewく描きました。

カーソル



隙間のある赤い穴は傷ではなく、単に中心へのポインタです。その目的については、もう少し詳しく説明します。



現在は、 SkeletonFrameReadyイベントを処理し、「奇跡の手」をフィールド全体に移動するだけです。 イベント処理の一般的なアプローチは次のとおりです。フレームを取得し、フレーム内で見つかったすべての人物(骨格)のデータを抽出し、これらの図形の中から最初に追跡されたものを選択します。 Kinectはフレーム内の6つの数字のデータを提供できますが、動きを追跡できるのは2つだけです( プレーヤーセグメンテーションデータを参照)。 単純なゲームの場合、最初に追跡されたプレーヤーを取得するだけで十分です。



 private Skeleton GetTrackedSkeleton(SkeletonFrameReadyEventArgs frameReadyEventArgs) { using (SkeletonFrame skeletonFrameData = frameReadyEventArgs.OpenSkeletonFrame()) { if (skeletonFrameData == null) { return null; } Skeleton[] allSkeletons = new Skeleton[skeletonFrameData.SkeletonArrayLength]; skeletonFrameData.CopySkeletonDataTo(allSkeletons); return allSkeletons.Where(s => s.TrackingState == SkeletonTrackingState.Tracked).FirstOrDefault(); } }
      
      





人物(スケルトン)に関する情報は、20ポイントのセットです。 ウィトルウィウス的人物のイメージは、彼らのデモンストレーションに最適です。



スケルトンポイント



したがって、スケルトンから、プレイヤーの体の興味のある部分の位置を取得し、必要に応じて競技場を更新できます。 次のジェスチャーシステムを使用できます。



左手の位置を確認するのは非常に簡単です。 左手と左肩のY座標を比較するだけで十分です。



 private bool IsAcionMode(JointCollection joints) { Joint lh = joints[JointType.HandLeft]; Joint ls = joints[JointType.ShoulderLeft]; return lh.Position.Y > ls.Position.Y; }
      
      





プレーヤーの右手がダイスの上にあるかどうかを判断するには、 VisualTreeHelperクラスのHitTest関数を使用できます。 「奇跡の手」の赤い丸を覚えていますか? このポイントの下で、キューブを探しています。



ジェスチャー処理機能:



 private void UpdateScenaItems(Skeleton skeleton) { Point currentPos = skeleton.Joints[JointType.HandRight] .ScaleTo((int)PART_LayoutRoot.ActualWidth, (int)PART_LayoutRoot.ActualHeight, 0.50f, 0.20f) .Position .ToPoint2D(); Rectangle cube = GetCubeUnderCursor(currentPos); var isAction = IsAcionMode(skeleton.Joints); if (!isAction || (isAction && cube == null)) { UpdateCursorPosition(currentPos); return; } MoveCubeUnderCursor(cube, currentPos); }
      
      





ScaleTo拡張メソッドを使用して、座標を競技場のスケールに合わせます。 このメソッドは、Coding4Fun Kinect Toolkitの一部です(NuGetからダウンロードできます)。 ToPoint2Dは、 SkeletonPointPointに変換するために使用される私の拡張メソッドです。 UpdateCursorPositionメソッドではカーソルのみを移動し、MoveCubeUnderCursorメソッドではキューブをドラッグすることは明らかです。



これでゲームを開始し、手を少し振ることができます!







以下に、ゲームのソースコードとアセンブリを示します。

PS時々、ブロックは一緒にくっついたり、床に引っかかったりします-おかしい。

PPS 次の記事では、アプリケーションに音声コマンドを理解する方法を教える方法について説明します。



ゲームビルド

ゲームのソースコード

PhysicsHelperライブラリアセンブリ

PhysicsHelperライブラリのソースコード



All Articles