はじめに
「AudioVideoPlayback.Video」から取り出したテクスチャを使って今回は16パズルを作ってみたいと思います。細かいことを気にせず骨組みだけを作っていきますが、ちゃんと動きますし、工夫次第では、もっと面白いものができるかもしれません。
対象読者
環境
言語はC#を利用します。VB.NETでもまったく同じ事ができるので、C#のコードが読めれば問題ありません。
また、DirectX 9のSDKが入っていないとコンパイルできません。SDKはMicrosoftのページで手に入ります。
知識
とりあえずDirect3DとVideo
クラスからのテクスチャの取り出し方は知っておいて欲しいです。テクスチャの取り出し方については、「Managed DirectXでビデオをテクスチャとして利用する」を参照してください。今回はカメラや頂点バッファは利用しません。すべて「スプライト」を利用します。必要なスプライトの知識は随時説明していくので心配はいりません。
あと、一番重要なことが「16パズルを知っている」ことです。ちゃんと解ける能力があるとなお良いです。
必要な環境
DirectX 9が動くこと。その他に、.Net Framework1.1が必要です。
解説(前半)
16パズルのデータ構造
16パズルのデータ構造ですが、簡単に作ってあります。
- Rectangle配列(2次元配列):
map
- Point:
nowPosition
この2つでデータを保持しています。Pointの方は抜けている場所を保持しています。16パズルのときは、iとjがそれぞれ「0~3」の値をとります。
Rectangle配列は添え字が画面側の座標にそれぞれ対応し、構造体が持っている座標と大きさはテクスチャ側に対応しています。
配列の添え字の対応は上の図の通りです。移動が起こると、Rectangle配列の2カ所を交換してテクスチャの座標を入れ替えます。
今回はすごく簡単に作ったため、完成の判定は行っていません。完成したかどうかの判定については各自で実装してみてください。
mapの初期化
//宣言部 /// <summary> /// パズルのマップ /// </summary> private Rectangle [,]map =new Rectangle[puzzleSize,puzzleSize]; //初期化部 for(int i=0;i<puzzleSize;i++) { for(int j=0;j<puzzleSize;j++) { map[i,j] =new Rectangle( (int)( videoSize.Width * j / (float)puzzleSize ), (int)( videoSize.Height * i / (float)puzzleSize ), (int)( videoSize.Width / (float)puzzleSize ), (int)( videoSize.Height / (float)puzzleSize )); } }
videoSize
は再生されるビデオのサイズです。
puzzleSize
はパズルの一辺の大きさです。定数で「4」を指定してありますが、ここを変えれば他の大きさも楽しめます。現在4*4で16分割ですが、3*3=9分割などにすることもできます。
ここではビデオのテクスチャのどの範囲をどれくらいの大きさで切り出すかを設定しています。ここがみそです。ここがずれると表示がおかしくなります。
それと、Rectangleはint
単位の処理のため、場所によっては1ピクセルの隙間ができてしまいます。今回は簡単にするためにそのままにしてありますが、ここも改善点になるでしょう。
16パズルのキー操作
キーは普通にフォームの「KeyDown」イベントを利用しています。キーが押されると、map
とnowPosition
の値を頼りに空いている場所との交換を行います。
また、キー操作を乱数で作り出すことによってシャッフルも行っています。他のパズルゲームにも応用できる方法だと思います。