8.6 パズルの設計

今回から PieceLayer クラスを使ってパズルを作っていくね。
は〜い!
まず、どんなふうに PieceLayer クラスのオブジェクトを使うかなんだけど…
うん?
こんなふうに、画像を何個かのピースに分割して、 それぞれのピースを正しい位置にドラッグしてパズルを完成させるから…

一つ一つのピースが PieceLayer クラスのオブジェクトになってるってこと?
そういうこと。
じゃあ PieceLayer クラスのオブジェクトって全部で9個作るんだ?
ううん、図をシンプルにするためにピースを9個にしてるだけで、 実際にはピースを何個作るかは自由に設定できるようにするつもりだよ。
あ、そーなんだ。
それに、ピースが9個しかなかったら簡単すぎるでしょ。
あそっか。そー言われれば確かに9ピースじゃ少なすぎるよね。
画像を縦方向と横方向に分割してピースを作るから、 画像を縦と横にそれぞれ何分割するかを指定できるようにするの。
例えば縦に5分割、横に5分割って指定すると25ピースのパズルになるって感じだね。
なるほどね。
で、このピースをドラッグしてパズルを完成させていくんだけど、 ちょっと処理の流れが複雑だから、フローチャートを使って書いてみることにするね。

<処理の流れ>

確かに結構ややこしそーだね…
とりあえず処理の流れに沿って見ていくことにするね。
うん。
まず、Puzzle クラスっていうクラスを作って、 その中でこのフローチャートに書いてる処理をやることにするね。
その Puzzle クラスってプラグインなの?
ん〜、プラグインにしてもいいんだけど、今回は特にプラグインの機能は使わないから普通のクラスにするつもり。
ふぅん、そーなんだ。
じゃ改めてフローチャートを見ていくね。
うん。
まず最初にやるのが、パズル用の画像を読み込んで、その画像を何個かに分割して、 ピースを作るっていう処理。
そのピースが PieceLayer クラスのオブジェクトになってるんだよね。
ん、そうだよ。
で、ピースが作れたら、次はそのピースを画面上にランダムに配置するの。
それって、こんな感じでピースをバラバラな位置に置くってことだよね?

<ピースの初期配置>

そうそう。
で、ここまでの処理は Puzzle クラスのコンストラクタでやるの。
じゃあ、コンストラクタの実行が終わったら、パズルの準備が出来てるって感じ?
そ。だから後はピースがドラッグされるのを待つわけね。
待つってどーやって?
パズルをやってる間は、シナリオの実行を s タグで止めてるから、 待ってる間は別に何もする必要ないよ。
あ、そーなんだ。
んで、どれかのピースがドラッグされ始めたら、そのピースを一番手前に表示するんだ。
ドラッグするピースを見やすくするために一番手前に表示するんだよね。
§8.3 参照。
そうそう。
一番手前に表示するってことは…えっと、index プロパティ…だったかな?
あの値を変えて、レイヤの重ね合わせ順序を変えるってことだよね?
そうそう。
ちなみに index プロパティじゃなくて absolute プロパティね。
indexKAG の属性の方だから間違えないように気をつけてね。
absolute プロパティについては §5.8 参照。
あ、そーだった。
ところで、ドラッグされ始めた時に最初に呼び出されるメソッドって何だったか覚えてる?
えっ? え〜っと…onMouseDown メソッド、だったっけ?
確かドラッガブルレイヤを作った時に onMouseDown メソッドdraggingtrue にして、 ドラッグが始まったって見なしてたよね?
ん、ドラッグを始める時には、まずレイヤの上でマウスのボタンを押すから、 最初に onMouseDown メソッドが呼び出されるよね。
だね。
ちなみに今回のパズルの場合は、ドラッガブルレイヤの onMouseDown メソッドの中でピースの重ね合わせ順序を変えるんじゃなくて、 Puzzle クラスに onDragStarted メソッドを作って、 その中で重ね合わせ順序を変えるんだ。
えっと、それってどーゆーこと?
パズルだから、当然ピースはいっぱいあるよね。
うん、まーそうだよね。
その中の1つのピースを一番手前に持ってくると、 元々そのピースより手前に表示されてたピースの absolute プロパティを減らさなくちゃいけないんだ。
こんなふうに。

<重ね合わせ順序の変更>

あ、なるほど。
一番手前に持ってくるより手前に表示されてたabsolute1 ずつ減らさなくちゃいけないんだね。
だから、onMouseDown メソッドの中でピースの重ね合わせ順序を変えようとすると問題があるんだ。
え、そーなの?
だって onMouseDown メソッドの中だと、 自分の absolute プロパティは設定できても、 他のピースの absolute プロパティの値は変えられないでしょ?
あ、そっか。
確かに他のオブジェクトのプロパティは変えられないよね。
Puzzle クラスは全部のピースを管理してるから、 Puzzle クラスのメソッドの中なら、 全部のピースの absolute プロパティの値を変えられるってワケ。
なるほどね。
あ、でも onMouseDown メソッドはピースの上でマウスのボタンが押されたら自動的に呼び出されるけど、 Puzzle クラスのメソッドの方は自動的には呼び出されないよね? それでもうまくいくの?
それなら大丈夫。
システムボタン(SystemButtonLayer クラス)は、 クリックされた時に onMouseUp メソッドの中で、 コンストラクタの第3引数に指定したメソッドが呼び出されるようになってたでしょ。
§5.6 参照。
そっか。それと同じようにして onMouseDown メソッドの中で Puzzle クラスのメソッドが呼び出されるようにすればいいんだね。
そういうこと。
じゃフローチャートの方に戻って、次の処理を見ていくね。
次はドラッグが終わった時の処理。
なんか YesNo に分かれてるね。
ドラッグが終わったらピースの位置をチェックして、 正しい位置に置かれてたら Yes の方に進んで、 正しい位置に置かれてなかったら No の方に進むの。
ちなみに No の方は「ピースがドラッグされるのを待つ」に戻るだけだから、 特に何もしなくて OK。
じゃあ Yes の方は?
そのピースが正しい位置に置かれたってことだから、ピースを固定するの。
動かせないようにするってこと?
そ。ところで、ドラッグが終わった時に呼び出されるメソッドは何だったか覚えてる?
えっと、onMouseUp メソッドだったよね?
ドラッガブルレイヤを作った時に draggingfalse にしてたから。
§8.2 参照。
ん、そうそう。
ちなみに onMouseUp メソッドが呼び出された時も、 Puzzle クラスのメソッドを呼び出すんだ。
え? ピースを固定するだけなんだったら、 onMouseUp メソッドの中でできるんじゃないの?
ピースを固定する時に重ね合わせ順序を一番奥にするから Puzzle クラスのメソッドを呼び出すの。
あ、そーなんだ。
でもなんで一番奥にするの?
固定されたピースはそれ以上ドラッグできないから、こんなふうに他のピースより手前にあると、 他のピースが動かしにくくなっちゃうんだ。

<固定されたピースより奥にドラッグできるピースがある場合>

確かにこれだと固定されてるより奥にあるがちょっとしか見えてないから、 の上でクリックするのが大変そーだね。
でしょ。
で、ピースを固定したら、 次は全部のピースが正しい位置に置かれてるかどうかチェックするんだ。
全部正しい位置に置かれてたら完成ってことだよね。
ん、そう。その場合は、process メソッドでパズルが完成した時に実行するシナリオファイルのラベルにジャンプするの。
まだ正しい位置に置かれてないピースが残ってたら、「ピースがドラッグされるのを待つ」に戻るわけね。
パズルの処理の流れはこんな感じだけど、大体わかった?
process メソッドについては §7.4 参照。
うん、大体はね。
それじゃ、今回はこの辺にしとこっか。
え、まだ全然スクリプト作ってないけど、いいの?
ん〜、まぁそうなんだけどね。今からスクリプトに入ると長くなっちゃうだろうし。
今回はパズルの設計の話ってことで。
そっか。わかった。
それじゃ、また次回ね!


前へ | TOP | 次へ