Section 4.5 画像のコピー(その2)

それじゃ、前回の続きね。
前回は日付の表示をするプラグインのスクリプトを作ったんだよね。
ん。コンストラクタデストラクタ はチェック済みだから、 今回は drawChar メソッド からだね。
このメソッドって copyRect メソッドを使って、日付の画像をレイヤにコピーするメソッドなんだよね?
そうそう。
じゃ drawChar メソッド がどんなメソッドか説明してみて。
え〜っと、まずコピー先のレイヤを第1引数で指定するようになってるよね。
ん、そだね。
それから、コピー先の四角形の座標は drawChar メソッド の第3引数と第4引数で指定するようになってるんだよね?
ん。第3引数の left がコピー先の四角形の左端の座標で、 第4引数の top が上端の座標だね。
ちなみに第4引数は省略できて、省略すると 0 とみなされるよ。
あとは第2引数の char なんだけど…
これは copyRect メソッドの第4引数で使われてるから、 日付表示用画像のどの文字をコピーするかを指定する引数なんだよね?
そうそう。
で、copyRect メソッドの第4引数は chWidth * char になってるから…?
ん〜っと、左から char 番目の文字をコピーするってことかな?
うん、そういうこと。
じゃ、最後は drawDate メソッド だね。
第1引数の month と第2引数の day は、 何月何日ってのを指定するんだよね?
そ。で、第3引数は true だと表画面のレイヤに、 false だと裏画面のレイヤに日付を書き込むってことね。
drawDate メソッド の中で drawChar メソッド が5回も呼び出されてるね。
それぞれ「月の10の位」「月の1の位」「/(スラッシュ)」「日の10の位」「日の1の位」を書き込んでるんだけど、 まず第2引数がどうなってるかは解る?
んーと、month \ 10month の値を 10 で割って余りを切り捨てるんだから、これで月の10の位が判るのかな?
ん、そう。
あと、month % 10 の方は 10 で割った余りだから、月の1の位になるんだよね?
うん。
ちなみに、drawChar メソッドの第2引数に 09 の値を指定すると、 レイヤに 09 が書き込まれるんだ。
あ、そういえば 1 は imgLay の左端から1文字分右にあるし、2 は2文字分、3 は3文字分右にあるから、確かにそうなるよね。
こうしとくと、引数に指定する数字とレイヤに書き込まれる数字が同じになるからわかりやすいでしょ。
なるほど、確かにそうだね。
で、/(スラッシュ)は左から10番目にあるから、drawChar メソッドの第2引数に 10 を指定すればレイヤに書き込めるよね。
うん、そうだね。
あと、日の10の位と1の位は、月の時と同じように考えればいいんだよね?
ん、monthday に変わるだけ。
じゃ、あとは第4引数の left がどんなふうに指定されてるか解る?
え〜っと…1文字目はレイヤの左端に書けばいいから 0 で、 2文字目は1文字分右に書けばいいから chWidth で、 3文字目はさらに1文字分右に書けばいいから chWidth * 2 …っていう感じかな?
ん、そう。つまり、x 文字目はレイヤの左端から x-1 文字分だけ右に書けばいいから、 left には chWidth * (x - 1) を指定すればいいってことになるよね。
図にするとこんな感じ。

left の値>

leftの値

1文字書くごとに leftchWidth ずつ増えていくんだね。
じゃ、これで今回のプラグインの内容は理解できた?
うん!
…あっ、ちょっと待って!
ん?
プラグインオブジェクトを作ってるとこなんだけど、『global.date』ってどういう意味?
あぁ、それは date っていう変数をどこからでも使えるようにするためにそうしてるんだ。
それってどういうこと?
§1.12で変数の有効範囲について説明したよね。
えっと、確かブロックの中で宣言されてる変数は、そのブロックの中でしか使えない、っていうのだったよね?
ん。確かに、ブロックの中に入ってる変数はそのブロックの中でしか使えないんだけど、 ブロックの中に入ってない変数は、どこからでも使えるんだ。
あ〜、そう言われればそうだったような…
つまり…

// 変数 g は、これ以降どこからでも使えます
var g;

{
    // 変数 l はこのブロック内でしか使えません
    var l;
}

このスクリプトの場合だと、g っていう変数は、宣言した後はどこからでも使えるんだけど…
l っていう変数は、ブロックの中に入ってるから、このブロックの中でしか使えないんだよね。
ん、そういうこと。
で、変数 g の方は、宣言すると global オブジェクトっていうオブジェクトに登録されるんだ。
global オブジェクト?
§2.9 で使ったでしょ。
あー、そう言えば多重継承でスーパークラスのデストラクタを呼び出す時に使ったね。
global オブジェクトはクラスの定義に関する情報とか、 すべてのブロックの外で宣言されてる変数の情報を持ってるんだ。
だから…

var g = 1;  // 変数 g は global オブジェクトに登録されるので、以後 global.g でアクセスできます
System.inform(global.g);  // 上の行で宣言されている変数 g が参照されます

このスクリプトを実行すると「1」って表示されるんだ。
ちなみに…

{
    var l = 1;  // この変数 l はブロック内にあるので global オブジェクトに登録されません
    System.inform(global.l);  // なので、これはエラーになります
}

この変数 l はブロックの中にあるから global オブジェクトには登録されないんだ。
へぇ……あ、でも…

var g = 1;  // 変数 g は global オブジェクトに登録されるので、以後 global.g でアクセスできます
System.inform(g);  

これでも「1」って表示されるよね?
うん、もちろん。
じゃあ、わざわざ global.g なんて書く意味ないんじゃない?
ま、この場合はね。
でも、変数が存在するかどうかをチェックする時には、global キーワードが必要になるんだ。
例えばこんな感じ。

System.inform(typeof global.g);  // もし g という変数が存在しなければ "undefined" と表示されます
System.inform(typeof g);  // もし g という変数が存在しなければエラーになります

もし g っていう変数がブロックの外で宣言されてなかった場合は、 global キーワードをつけないとエラーになっちゃうんだ。
また今度説明するけど、こうやって変数が存在するかどうかチェックすることって結構あるから。
へぇ、そうなんだ。
あと、global キーワードは、変数を宣言する時にも使えるんだ。

global.g = 1;  // global.g に値を代入すると、どこからでも使える変数 g が作られます(var g; と書くのと同じ)
System.inform(global.g);
System.inform(g);  // global は省略しても OK

こんなふうに、global.g = 1; って書くと、 ブロックの外で var g = 1; って書くのと同じ意味になるんだ。
ふぅん…
つまり、プラグインオブジェクトを作ってるとこは、 どこからでも使える変数 date を宣言して、それに DatePlugin クラスのオブジェクトを代入して、 さらにそれを addPlugin メソッドの引数に指定する、っていう処理を1行で書いてるってワケ。
なるほど、そういうことだったんだ。
じゃ、あとは KAG スクリプト だけど、これは解るよね?
うん。最初に call タグでプラグインを読み込んで、 それから drawDate メソッドを呼び出して日付を表示してるんだよね?
ん、そういうこと。
これで今回のプラグインは OK かな?
うん、おっけーだよ!
なんか画像のコピーと言いつつ、後半は global オブジェクトの話になっちゃったけど…今回はこれくらいかな。
それじゃ、また次回ね!


前へ | TOP | 次へ