SQパズルに見る開発テクニックの面白さ
#win8dev_jp
田中さんがSQパズルのテンプレートを公開されました。
これはパズルゲームの題材として面白いのでぜひ見てください。
テンプレートの紹介と、簡単なカスタマイズ方法についても記載されていますが、見てほしいのは中で使われている開発テクニック。
ゲームに置ける挙動をどうやって実装しているのか、なかなか興味深いです。
■ 画面構成
このアプリは MainPage.xaml のみで作られているので、比較的理解しやすいです。
画面モードのステータスで、コードで切り替えている感じですね。起動画面とゲーム画面が全く違う場合は、異なる画面を作ったほうが簡単ですが、この場合は、タイトル画像からそのままパーツを切りだしてるので1画面でOKな感じです。
表示にはViewBox を使っているため、画面サイズに合わせてフレキシブルに合わせてくれます。無数の解像度で使われる Windows 8では重要なテクニックです。
■ 画像を切りだす方法
元画像からピースを作りだすところが、ジグソーパズルのキモになります。WPFならVisualBrush があるので簡単ですし、動画まで対応できますが残念ながら WinRT には VisualBrush がありません。
ですので、
- 画像を切りだし
- イメージオブジェクトにして
- 貼り付ける
という作業をします。これを実現しているのが
- Image.Clip
- RenderTargetingBitmap → ImageBrush
- Background への ImageBrush への貼り付け
です。図にするとこんな感じかな。これっていろんな場面で使えそうな気がいます(そうでもないか?)
■ Image.Clip をツールでやるには?
SQパズルテンプレート内で、Image.Clip はXAMLでこんな風に定義されています。
<Image x:Name="image1" Source="Assets/image.jpg" Stretch="UniformToFill" >
<Image.Clip>
<RectangleGeometry x:Name="rg1" />
</Image.Clip>
< /Image>
さて、これをツールでやるにはどうするのか? もちろん Blend で行えます。
- 元になる画像を配置し
- 切り出す領域をRectangle や Ellipse, Path などで作成し
- 両方を選択したら
- パス→クリッピングパスの作成 で切り出し
ます。
ここまではBlendのGUIでできるのですが、
- Geometry 領域のサイズの変更や
- Geometry に名前を付ける(後からコードで変更するため)
といった場合は、XAMLのソースを直接変更しないといけません。RectangleGeometry を選んでもプロパティで出てこないです。UIElementじゃないから仕方がないかw
■ 重なったピースを一番手前に出す
これが面白い。単純ではあるのですが。画面上に重なったピースを手前に出す方法。
親元のパネルから対象パーツを削除し、また追加する。
// 触っているピースを一旦削除し、グリッドの一番手前に追加する
grid1.Children.Remove(PieceImage[MovingPieceX, MovingPieceY]);
grid1.Children.Add(PieceImage[MovingPieceX, MovingPieceY]);
これを見たとき、「なるほどね!」って思いました。Grid 上の 重なりの順番はあとに追加されたものほど手前になります。その法則を利用したもの。
逆手にとれば、自分以外のものをすべて削除して追加すれば、自分が一番下になるということですね。
■ tagの利用
度のコントロールにも必ず Tag という Object プロパティが用意されています。これはユーザーが自由に何でも入れて利用できます。コントロールに独自のデータを保存したい場合、ユーザーコントロールなどを作成しないといけませんが、保存するものが1つなら Tag に入れておくとわざわざユーザーコントロールを作らなくてもいいので楽です。
勿論、取り出す時には保存したデータの方に合わせてキャストする必要はありますけどね。
SQ パズルでは、ピースが正しい場所にはまっているかどうかの状態を持たせるために使っています。
■ その他のアプリテンプレート
様々なテクニックが盛り込まれた、ストアアプリテンプレートがこちらに収められています。ぜひチェックしてみてください。