今回からパズルを作っていくわけだけど、 最初はパズルのピースに必要なドラッガブルレイヤから作ってみることにするね。 | |
はーい。 | |
…って言ってもドラッガブルレイヤって結構カンタンに作れるんだけどね。 | |
そーなの? ドラッグして動かせるようにするのって結構タイヘンそうな気がするんだけど? |
|
それが意外とそうでもないんだ。 まぁ作ってみればわかると思うよ。 |
|
ふぅん。 それじゃ作ってみよ。 |
|
うん。 まず、ドラッガブルレイヤのクラスを作るわけだけど、 どのクラスを継承して作ればいいかはわかるよね? |
|
ドラッガブルレイヤってゆーくらいだから、Layer クラスなんじゃないの? | |
ん、正解。 | |
まーさすがにこれはわかるよ。 | |
じゃ最初はいつものようにコンストラクタとデストラクタから作っていくね。 あと、ドラッガブルレイヤのクラスは DraggableLayer クラスって名前にするね。 |
|
りょーかい。 | |
これが DraggableLayer クラスのコンストラクタとデストラクタ。 |
<DraggableLayer クラスのコンストラクタとデストラクタ>
これって、スーパークラスのコンストラクタとデストラクタを呼び出してるだけ…だよね? | |
そ。ドラッガブルレイヤには別に特別な初期化処理とか終了処理は必要ないからね。 | |
そーなんだ。 | |
あと、オーバーライドするメソッドは onMouseDown、 onMouseUp、onMouseMove の3つだけで、 新しく作るメソッドはゼロ。 | |
えっ、それだけでできちゃうの? | |
ん、この3つのメソッドだけオーバーライドすれば OK。 じゃまずは onMouseDown メソッドから見ていくね。 |
えっと、これって何してるの? | |
ドラッグする時は、最初にマウスのボタンを押すでしょ。 | |
うん、そーだね。 | |
マウスのボタンが押されると onMouseDown メソッドが呼び出されるから、 ここでドラッグを始める時の準備をしてるんだ。 | |
ドラッグを始める時の準備? | |
まず、dragging っていう変数に true を代入してるでしょ。 | |
この変数って onMouseDown メソッドの中で宣言されてないから、メンバ変数なのかな? | |
そうそう。 dragging っていうメンバ変数は、 レイヤがドラッグされてる間だけ true になってて、 それ以外の時は false になってるんだ。 |
|
なるほど、名前の通りだね。 | |
onMouseDown メソッドが呼び出されたってことは、 これからレイヤがドラッグされるかもしれないってことだから、 ここで dragging を true にしてるワケ。 | |
でも、ドラッグされるかもしれないけど、もしかしたらクリックするだけでドラッグしないかもしれないじゃない? それなのに dragging を true にしちゃっていいの? |
|
あー、それなら大丈夫。 | |
え、そうなの? なんで? | |
それは onMouseUp メソッドを見ればわかると思うよ。 |
dragging を false にしてるだけ…? | |
onMouseUp メソッドはマウスのボタンが離された時に呼び出されるから、 dragging を false にして、ドラッグが終わったとみなしてるんだ。 | |
そっか。ドラッグしてるのってマウスのボタンを押してる間だけだもんね。 | |
ドラッグせずにマウスのボタンをクリックしただけなら、 onMouseDown メソッドが呼び出されて dragging が true になった後にすぐ onMouseUp メソッドが呼び出されて dragging が false に戻るから、結局何にも起こらないワケ。 | |
あ〜、なるほど。だからドラッグするかどうかわからなくても、 とりあえず onMouseDown メソッドで dragging を true にしても大丈夫なんだね。 | |
そういうこと。 じゃ onMouseDown メソッドの話に戻るね。 次は dragOriginX と dragOriginY にマウスカーソルの位置を代入してる部分を見ていくね。 |
|
これもメンバ変数っぽいよね? | |
ん、dragOriginX と dragOriginY もメンバ変数だよ。 それぞれドラッグし始めた時のマウスカーソルの x 座標と y 座標を保存しとくために使うの。 図にするとこんな感じ。 |
<onMouseDown メソッドが呼び出された時の状態>
onMouseDown メソッドの引数の x と y は、それぞれマウスカーソルとドラッガブルレイヤの左端、上端との距離になってるわけね。 | |
なるほどね。 でもこれって何のために使うの? |
|
ドラッグ中にどれだけマウスカーソルが移動したかを onMouseMove メソッドの中で計算するためだよ。 | |
えっと、どーいうこと? | |
じゃあ onMouseMove メソッドを見ながら説明するね。 onMouseDown メソッドの方は、 後はスーパークラスの onMouseDown メソッドを呼び出してるだけだから大丈夫だよね? |
|
うん、onMouseDown メソッドの方はおっけーだよ。 | |
ん、それじゃ onMouseMove メソッドを見ていくね。 |
う〜ん、なんかややこしそーだね。 | |
まぁ、とりあえず順番に見ていくことにするね。 | |
そだね。 | |
まず最初の if のとこだけど、これはわかるよね? | |
if(dragging) ってことは…ドラッグ中だったら dragging が true になってるから、 if ブロックの中身が実行されるってことだよね? | |
ん、そうそう。 それじゃ次は if ブロックの中身を見ていくね。 ブロックの中で最初にやってるのが、レイヤの移動先の座標の計算。 |
|
ここでさっきの dragOriginX と
dragOriginY が出てきてるね。 …どんな計算をしてるのかはよくわかんないけど。 |
|
確かにスクリプトだけだとわかりにくいと思うから、図にしてみるね。 まず、onMouseMove メソッドが呼び出された時に、 マウスカーソルの位置がこんなふうに右下に移動してたとするね。 |
<onMouseMove メソッドが呼び出された時の状態>
onMouseMove メソッドが呼び出された時の x と y も、マウスカーソルとレイヤの左端・上端との距離になってるんだ。 | |
えっと、マウスカーソルが右下に移動したってことは、onMouseMove メソッドの x は dragOriginX より大きくなってて、 y も dragOriginY より大きくなってるってことなんだよね? | |
ん、そうだよ。 ちなみにマウスカーソルは右方向に (x - dragOriginX) ピクセル、 下方向に (y - dragOriginY) ピクセル移動してるよ。 |
|
んー…dragOriginX とマウスカーソルが右方向に移動した距離を足すと x になるから、 移動距離は x から dragOriginX を引いた値になるってことなのかな? | |
そういうこと。 下方向も同じように考えて、dragOriginY + マウスカーソルが下方向に移動した距離 = y になるから、 下方向の移動距離は (y - dragOriginY) になるわけね。 |
|
だね。 | |
あとは、こんなふうにマウスカーソルの位置に合わせてレイヤを移動させれば、 レイヤがドラッグされてるように見えるってワケ。 |
うわ、なんかややこしい図だね… | |
ドラッグする前のドラッガブルレイヤの左端と上端が left と top になってるから、 ドラッグするためには、ドラッガブルレイヤの左端と上端をそれぞれ newLeft と newTop の位置にすればいいってことはわかる? | |
うん、それはなんとなくわかるよ。 | |
じゃあとはどうやって newLeft と newTop の値を計算するかだけど、いっぺんに考えるとややこしいから、 まず newLeft の方から考えていくね。 | |
はーい。 | |
left と x を足した長さが newLeft と dragOriginX を足した長さとおんなじになってるでしょ? | |
うん、確かに同じ長さになってるね。 | |
つまり、left + x = newLeft + dragOriginX ってことだから、 この式を変形すると… | |
newLeft = left + x - dragOriginX、だね。 | |
じゃ newLeft を計算してるスクリプトの方を見てみて。 | |
あっ、おんなじ式になってるね! | |
ん、あと newTop の方も同じようにすれば計算できるよ。 top と y を足した長さが newTop と dragOriginY を足した長さとおんなじだから… |
|
top + y = newTop + dragOriginY になって、 この式を変形すると newTop = top + y - dragOriginY だね。 | |
じゃ newTop を計算してるスクリプトの方はどうなってる? | |
こっちもおんなじになってるね。 | |
newLeft と newTop が計算できたら、 後は setPos メソッドを呼び出してレイヤを移動させれば OK。 | |
※ setPos メソッドについては §3.2 参照。 | |
なるほどねー。 あ、でも setPos メソッドを呼び出す前になんか if とか else if がいっぱいあるんだけど、これって何してるの? |
|
この if とか else if で、 ドラッガブルレイヤが親レイヤの外に出ちゃわないようにチェックしてるの。 | |
え、それってどーいうこと? | |
例えば、こんなふうにドラッガブルレイヤをずーっと左に動かすと、 親レイヤ、つまり表画面の背景レイヤの範囲外に出ちゃうんだ。 |
えっと、ドラッガブルレイヤが親レイヤの範囲外に出ちゃうと何か問題あるの? | |
ドラッガブルレイヤが親レイヤの範囲外に出ると、その部分が表示されなくなるってのは前に確認したよね。 | |
※§3.2 参照。 | |
うん、そーだったね。 | |
上の図の(B)の状態だと、ドラッガブルレイヤの一部が表示されてるから特に問題はないんだけど、 さらにドラッグして(C)の状態でドラッグするのをやめると、 ドラッガブルレイヤ全体が表示されなくなるから、二度とドラッグできなくなっちゃうんだ。 | |
あ、そっか。確かに(C)の状態だと画面上にドラッガブルレイヤが表示されてないから、 ドラッガブルレイヤがクリックできなくなっちゃうね。 | |
そうなっちゃうと困るから、 さっきのスクリプトでドラッガブルレイヤが完全に親レイヤの範囲外に出ないようにしてるの。 | |
なるほど。 でも具体的にはどーやってるの? |
|
チェックしてる条件は全部で4つあるんだけど、まずは最初の if(newLeft < -width + 4) newLeft = -width + 4; から見ていくね。 | |
うん。 | |
この if の条件がどういう意味かはわかる? | |
え〜っと、newLeft が
-width + 4 より小さい時に真になるんだよね… でも newLeft が -width + 4 より小さい時ってどんな時なんだろ…? |
|
これも図にしてみた方がわかりやすいかな。 これが newLeft が -width + 4 の状態だよ。 |
えっと、これってドラッガブルレイヤの右端が 4 ピクセル分だけ表示されてる状態、ってこと? | |
そういうこと。 じゃ、newLeft が -width + 4 より小さいとどうなると思う? |
|
う〜ん…例えば newLeft が -width + 3 だったら、
ドラッガブルレイヤの右端が 3 ピクセル分だけ表示されてる状態ってことだと思うから… newLeft が -width + 4 より小さいと、表示されてる部分が 4 ピクセルより小さくなる、ってことなのかな? |
|
そのとーり。 で、その時は newLeft を -width + 4 にしてるわけだから… |
|
ドラッガブルレイヤの右端の表示される部分が 4 ピクセルより小さくなる時は、 4 ピクセル表示されるようにするってこと? | |
つまり、表示される部分が 4 ピクセルより小さくならないようにしてるってこと。 こうすればどれだけ左にドラッグしても、必ずドラッガブルレイヤの右端は 4 ピクセル以上表示されるでしょ? |
|
なるほど、これなら左にずーっとドラッグしてっても、 ドラッガブルレイヤが完全に親レイヤの範囲外に出ちゃうことはなくなるんだね。 | |
次の条件も基本的に考え方はおんなじ。 まず、newLeft > parent.width - 4 が真になるのは、 右にドラッグしてった時に、ドラッガブルレイヤの左端の表示されてる部分が 4 ピクセル未満になった時だよ。 |
<newLeft が parent.width - 4 の時>
parent.width っていうのは親レイヤの幅ってこと? | |
あそっか。parent プロパティって今回初めて出てくるんだったっけ。 parent プロパティは親レイヤを表すプロパティなんだ。 だから、parent.width は親レイヤの幅だよ。 ちなみにこのドラッガブルレイヤの親レイヤは表画面の背景レイヤだから、 parent.width は kag.fore.base.width と同じ意味になるよ。 |
|
えと、じゃあ newLeft が parent.width - 4 より大きい時は newLeft を parent.width - 4 にしてるから、どれだけ右にドラッグしても、必ずドラッガブルレイヤの左端は 4 ピクセル以上表示される、ってこと? | |
ん、そういうこと。 あと考え方は同じだから説明は省略させてもらうけど、 残りの2つの条件は、 それぞれドラッガブルレイヤの下端と上端が 4 ピクセル以上表示されるようにするためにチェックしてるんだ。 |
|
newLeft を newTop に置き換えて、 あと width を height に置き換えて考えればいいんだね。 | |
そう。 この4つの条件をチェックすることで、どの方向にどれだけドラッグしても、 ドラッガブルレイヤが完全に親レイヤの範囲外に出ちゃうことはなくなるの。 |
|
なるほどね〜。 あ、ところで 4 ピクセルにしてるのってなんでなの? |
|
あぁ、これは別に 4 ピクセルじゃなくても OK だよ。 4 ピクセルくらい表示してればクリックしにくくならないかなと思って 4 ピクセルに設定してるだけ。 |
|
そーなんだ。 | |
さてと、これで onMouseMove メソッドは一通りチェックできたわけだけど、 onMouseMove メソッドで何やってるかは大体わかった? | |
んーと、まず dragging が true かどうかチェックして、 true だったらドラッグ中ってことだから、newLeft と newTop の値を計算して… | |
うんうん。 | |
それから、newLeft と newTop の値をチェックして、 親レイヤの範囲外に出てたら、ドラッガブルレイヤの端が 4 ピクセル以上表示されるように値を調整して、 setPos メソッドで位置を設定するんだよね。 | |
ん。で、最後にスーパークラスの onMouseMove メソッドを呼び出して完了、だね。 | |
最初にドラッガブルレイヤは作るのカンタンって言ってたわりにはややこしかったよねぇ。 | |
ん〜、まぁ考え方はちょっとややこしいかもね。 でもスクリプトは短いしそんなに複雑ってほどでもなかったでしょ? |
|
まーそれはそーだけどね。 | |
それじゃこれでドラッガブルレイヤのスクリプトができたから、ちょっと実行してみよっか。 | |
うん、そだね。 | |
first.ks はこんな感じにしとくね。 |
ほとんど TJS スクリプトだね… | |
まぁ、今回はドラッガブルレイヤを作ってみるだけだからね。 初めて使うメソッドとかは出てきてないと思うけど、スクリプトの内容はわかる? |
|
んと、128×128 ピクセルのドラッガブルレイヤを作って、緑色に塗りつぶして表示してるって感じだよね? | |
そうそう。 じゃスクリプトはここに置いとくから実行してみて。 |
|
わかった。 |
見た目はやっぱりフツーのレイヤだね。 | |
まぁね。じゃドラッグしてみて。 | |
うん。 |
お〜、ちゃんと動かせる〜! | |
ん、ちゃんとドラッグできてるね。 それじゃちょっとレイヤを画面外にドラッグしてみて。 |
|
おっけー。 |
ずっと左にドラッグしても、ちゃんとレイヤの端っこが表示されてるね。 | |
ん、これで OK だね。 じゃ今回はここまで。 次回からドラッガブルレイヤを使ってパズルのピースを作っていくことにするね。 |
|
は〜い! | |
それじゃ、また次回ね! |