8.4 パズルのピースを作る(その2)

今回は PieceLayer クラスのテスト用に作った first.ks のスクリプトを見ていくことにするね。
結構ややこしそーなスクリプトだったよねぇ。
まぁね。
とりあえずいつものように最初から見ていこ。
うん。
最初の call タグのとこは大丈夫だよね?
DraggableLayer クラスと PieceLayer クラスの定義を読み込んでるんだよね。
そ。じゃ次は iscript ブロックの中身を見ていくね。
なんか最初に変数が宣言されてるね。
まず、pieceWidthpieceHeight にはそれぞれピースの幅と高さを代入してるの。
じゃあピースの幅と高さはどっちも 64 ピクセルにするってこと?
ん、そう。
でもなんでわざわざ変数に幅と高さの値を代入してるの?
pieceWidthpieceHeight の値はこの後何回も使うから、 こうやって変数に値を代入しといて、幅と高さを変えたくなった時に、この2つの変数の値だけを変えればいいようにしてるの。
ふぅん、そーなんだ。
で、goalLeftgoalTop には、 それぞれピースの正しい位置の x 座標と y 座標を代入してるんだ。
goalLeft の方は (kag.fore.base.width - pieceWidth) \ 2 だから、 表画面の背景レイヤの幅からピースの幅を引いた値の半分ってことだよね?
そ。あと goalTop の方は、 表画面の背景レイヤの高さからピースの高さを引いた値の半分だから、 つまり表画面の背景レイヤの真ん中の位置が正しい位置ってことね。

<ピースの正しい位置>

前にレイヤの真ん中に文字を表示した時と同じように計算してるんだね。
§3.5 参照。
ん、そう。
それじゃ、次は with ブロックの中身ね。
えっと、with(kag.fore.base) になってて、 with ブロックの中に .fillRect って書いてあるから、 これって表画面の背景レイヤのどこかを塗りつぶしてるってことだよね?
fillRect メソッドについては §3.2 参照。
そうだよ。
まぁホントは背景レイヤとかを fillRect メソッドで直接塗りつぶすのはあんまり良くないんだけどね。
え、背景レイヤに fillRect メソッドを使っちゃダメなの?
使っちゃダメってワケじゃないんだけど、 例えば fillRect メソッドで背景レイヤを塗りつぶした後にセーブして、 そのデータをロードしても、塗りつぶす前の状態になるんだ。
そうなの?
うん、fillRect メソッドとか drawText メソッドとかを使って、 背景・前景・メッセージレイヤを塗りつぶしたり文字を描いたりしても、 その情報はセーブデータには記録されないんだ。
あ、そーいえばメッセージレイヤに書いてある内容はセーブデータに保存されないから、 セーブ可能なラベルの後には cm タグとかを書きましょう、って KAG のリファレンスにも書いてあったね。
※KAG System リファレンスの「チュートリアル」−「セーブ・ロードに対応させよう(KAGの「栞」)」の項目参照。
そうそう。だから普通は背景レイヤを直接塗りつぶしたりしない方がいいんだけど、 今回はちょっとしたテストだしセーブもしないから、 fillRect メソッドを背景レイヤに使うことにしたんだ。
そーいう場合は使っても大丈夫なんだね。
まぁね。
じゃ改めて with ブロックの中身を見ていくね。
最初は .fillRect(0, 0, .width, .height, 0xFFFFFF); だから、 背景レイヤ全体を塗りつぶしてるみたいだけど、第5引数の塗りつぶす色って、確か 0xAARRGGBB ってゆー形式で指定するんじゃなかったっけ?
ん、§3.2 とかで fillRect メソッドを使った時はそうしたよね。
でしょ?
でも今回は 0xFFFFFF ってなってて、 BB の部分がないんだけど?
0xFFFFFF って書くと 0x00FFFFFF っていう意味になるから、 BB の部分は FF になるの。
あ、そーなんだ。
じゃあ AA の部分が 00 だから、 透明色で塗りつぶしてるってこと?
んーん、そうじゃないよ。
実は背景レイヤはちょっと特別なレイヤだから、 AA の部分は指定しなくていいんだ。
…っていうか、指定できないようになってるの。
へぇ、そーなんだ。
それじゃ 0xFFFFFF にするとどーなるの?
背景レイヤは透明にならないから、背景レイヤの場合は AA の部分はいつでも FF になるって思っといて。
えっと、じゃあ背景レイヤの場合は 0xFFFFFF って書いても 0xFFFFFFFF と見なされるから、結局白色で塗りつぶすってこと?
ん、そういうこと。
で、その次の4つの fillRect メソッドで、 ピースの正しい位置を四角で囲んでるんだ。
なんか引数がややこしーね…
んー、じゃあまず最初の .fillRect(goalLeft, goalTop, pieceWidth, 1, 0x000000); を実行するとどうなるかわかる?
んと、(goalLeft, goalTop) の点が左上になるように、 幅が pieceWidth ピクセルで高さが 1 ピクセルの部分を… 0x000000 だから黒色で塗りつぶすってことだよね?
そうそう。
図にするとこんな感じね。

<最初の fillRect メソッドの実行結果(黒い線の部分が描かれます)>

なんかこれって塗りつぶしてるってゆーより線を書いてるって感じだよね。
Layer クラスには線を引くためのメソッドが無いから、 レイヤに線を書きたい場合は fillRect メソッドを使って、 幅とか高さが 1 ピクセルの領域を塗りつぶすようにするの。
幅を 1 ピクセルにすると縦の線になって、高さを 1 ピクセルにすると横の線になるってこと?
ん、そうだよ。
だから、残り3つの fillRect メソッドを実行するとこうなるわけ。

<4つの fillRect メソッドの実行結果(黒い四角の部分が描かれます)>

えーと、2番目の fillRect メソッドは .fillRect(goalLeft, goalTop, 1, pieceHeight, 0x000000); だから、 (goalLeft, goalTop) が左上で、 幅が 1 ピクセルで高さが pieceHeight ピクセルになるよね。
今度は幅が 1 ピクセルだから、縦の線を書いてるってことだよね。
ん、2番目の fillRect を呼び出すと (goalLeft, goalTop) の点から、 下方向に長さが pieceHeight ピクセルの線を書くことになるから、 つまりAの線が書き込まれるわけね。
じゃあ、3番目の fillRect メソッドを呼び出すとBの線が書き込まれて、 4番目の fillRect メソッドを呼び出すとCの線が書き込まれるってこと?
そういうこと。
3番目の線は (goalLeft + pieceWidth, goalTop) の位置じゃなくて (goalLeft + pieceWidth - 1, goalTop) の位置から書き始めるから注意してね。
あ、そういえば何で - 1 がつくの?
線は点の集まりで出来てるから、 例えば (0, 0) の位置から横に長さ 10 ピクセルの線を引くと、 こんな感じで10個の点で線が表されるの。

(0, 0) の位置から横に引かれた長さ 10 ピクセルの線( ■ が1つの点を表します)>

この線の右端の座標は (9, 0) になってるから、 この線の右端から下方向に線を引こうと思ったら、(10, 0) じゃなくて (9, 0) の位置から書き始めることになるわけ。

<最初に引いた線の右端から下方向にもう1本線を引く場合>

なるほど、だから (10 - 1, 0)(9, 0) になるんだね。
4番目の線もおんなじ理由で (goalLeft, goalTop + pieceHeight - 1) の位置から書き始めてるの。
だね。
これで背景レイヤの方は OK だから、次はパズルのピース用のオブジェクトを作るとこね。
PieceLayer クラスのコンストラクタの引数はどうなってたか覚えてる?
えっと、第1引数と第2引数は普通のレイヤとおんなじで、所属するウィンドウと親レイヤだから、 kagkag.fore.base になってるんだよね。
うんうん。
第3引数と第4引数はピースの正しい位置の x 座標と y 座標だから、 それぞれ goalLeftgoalTop になってるね。
正しい位置は背景レイヤの真ん中に設定したよね。
あと、第5引数の onDragStarted がドラッグを始めた時に呼び出されるメソッドで、 第6引数の onDragFinished がドラッグが終わった時に呼び出されるメソッドだったよね。
ん、この2つのメソッドはまた後で見ていくことにするね。
で、あとは global.pieceLayer っていう変数にピース用レイヤオブジェクトへの参照を代入して、 kagadd メソッドで KAG ウィンドウにオブジェクトを管理してもらうって感じだね。
kag.add ってどんなメソッドなんだったっけ?
add メソッドは Window クラスのメソッドで、 ウィンドウが無効化される時に、引数に指定したオブジェクトが自動的に無効化されるようにするためのメソッドだよ。
だから、kag.add の引数に global.pieceLayer を指定すると、 KAG のウィンドウが無効化される時、つまりウィンドウを閉じた時に、ピース用レイヤが自動的に無効化されるようにしてるの。
Window クラスの add メソッドについては §3.2 参照。
あ、そういえばそんな感じのメソッドだったね。
確か、add メソッドで管理してもらってるオブジェクトは invalidate で無効化しなくていいんだったよね?
invalidate 演算子については §2.2 参照。
そうそう。
それじゃ、今回はこの辺にしとこっか。
まだスクリプトが残ってるけど、もう終わりにするの?
んー、まだ結構先が長いからね。
今回全部見てこうと思うとかなり長くなっちゃいそうだから、一旦ここで区切っとこうと思うんだ。
ふぅん、そーなんだ。
まー確かにまだ結構スクリプトが残ってるもんね。
ってワケだから、続きは次回にするね。
それじゃ、また次回!


前へ | TOP | 次へ