Section 4.4 画像のコピー(その1)

前回でプラグインでレイヤが使えるようになったから、 今回はレイヤに日付を表示してみるね。
は〜い!
今回は §3.6 とかでやったのとは違う方法で日付を表示するね。
え、それってどういうこと?
前に日付を表示した時は drawText メソッドを使ったよね。
うん、そだね。
今回は、こういう画像を使って日付を表示するの。

<日付の表示に使う画像>

日付の表示に使う画像

この画像を使って、どうやって日付を表示するの?
例えば、『1/23』(1月23日)って表示する場合は、この画像の『1』、『/』、『2』、『3』の部分を順番にレイヤにコピーすれば表示できるでしょ。
あ〜、なるほどね。
でも、それって画像の一部をレイヤにコピーするってことでしょ?
そんなの今までにやったことないよね?
ん、だから copyRect っていうメソッドを使って、画像の一部をレイヤにコピーするの。
copyRect メソッド?
説明はちょっと後回しにして、まずは実際にやってみるね。
う、うん。
日付を表示するプラグインのスクリプトはこんな感じ。

<日付を表示する KAG プラグインの例(DatePlugin クラス)>

[iscript]

class DatePlugin extends KAGPlugin
{
    var imgLay;   // 日付表示に使う画像用のレイヤ
    var foreLay;  // 表画面用のレイヤ
    var backLay;  // 裏画面用のレイヤ
    var chWidth;   // 各文字(数字、"/")の幅
    var chHeight;  // 各文字の高さ

    // コンストラクタ
    function DatePlugin()
    {
        super.KAGPlugin();  // スーパークラスのコンストラクタを呼び出します

        // 日付表示に使う画像用のレイヤを作ります
        imgLay = new Layer(kag, kag.fore.base);  // 表画面の背景レイヤを親レイヤにします
        imgLay.loadImages("date_char");  // 日付表示に使う画像を読み込みます

        chWidth = imgLay.imageWidth \ 11;  // 文字の幅を代入します
        chHeight = imgLay.imageHeight;     // 文字の高さを代入します

        // 表画面用のレイヤを作ります
        foreLay = new Layer(kag, kag.fore.base);  // 表画面の背景レイヤを親レイヤにします
        with(foreLay)
        {
            .setSize(chWidth * 5, chHeight);  // 日付が表示できるようにサイズを設定します
            .setPos(20, 20);  // 位置を (20, 20) に設定します
            .visible = true;  // 表示状態にします
        }

        // 裏画面用のレイヤを作ります
        backLay = new Layer(kag, kag.back.base);  // 裏画面の背景レイヤを親レイヤにします
        with(backLay)
        {
            .setSize(foreLay.width, foreLay.height);  // 表画面のレイヤと同じサイズにします
            .setPos(foreLay.left, foreLay.top);  // 表画面のレイヤと同じ位置にします
            .visible = true;  // 表示状態にします
        }
    }

    // デストラクタ
    function finalize()
    {
        invalidate imgLay;   // 日付表示に使う画像用のレイヤを無効化します
        invalidate foreLay;  // 表画面用のレイヤを無効化します
        invalidate backLay;  // 裏画面用のレイヤを無効化します

        super.finalize();  // スーパークラスのデストラクタを呼び出します
    }

    // レイヤに文字を書き込みます
    function drawChar(layer, char, left, top = 0)
    {
        // imgLay の char 番目の文字の画像を layer にコピーします
        layer.copyRect(left, top, imgLay, chWidth * char, 0, chWidth, chHeight);
    }

    // レイヤに日付を書き込みます
    function drawDate(month, day, fore = true)
    {
        // fore が true なら表、false なら裏画面のレイヤに書き込みます
        var layer = fore ? foreLay : backLay;

        // 以下レイヤに文字を書き込みます
        drawChar(layer, month \ 10, 0);          // 月の10の位
        drawChar(layer, month % 10, chWidth);    // 月の1の位
        drawChar(layer, 10, chWidth * 2);        // /(スラッシュ)
        drawChar(layer, day \ 10, chWidth * 3);  // 日の10の位
        drawChar(layer, day % 10, chWidth * 4);  // 日の1の位
    }
}

// プラグインオブジェクトを作って kag オブジェクトに登録します
kag.addPlugin(global.date = new DatePlugin());

[endscript]

[return]

う〜ん、結構長いねぇ…
ま、前半は前回のスクリプトとそんなに変わらないけどね。
あと、プロジェクトフォルダの中に date_char.png を置いて、first.ks にはこのスクリプトを書き込んでね。
ここからダウンロードしても OK だよ。

DatePlugin を使うための KAG スクリプト>

; プラグインを作るスクリプトを読み込みます
[call storage="DatePlugin.ks"]

; 06/30と表示します
[eval exp="date.drawDate(6, 30)"]

プラグインのスクリプトの方を DatePlugin.ks っていう名前で保存して、first.ks を実行してみて。
うん、おっけ〜。

<実行結果>

表示されたウィンドウ

あ、画面の左上の方に『06/30』って表示されてるね。
ん、それじゃプラグインのスクリプトを見ていこっか。
はーい。
いつものようにコンストラクタからね。
imgLay っていうレイヤに、日付表示に使う画像を読み込んでるみたいだけど…?
このレイヤにあらかじめ画像を読み込んどくと、画像の一部をコピーする度にいちいち画像を読み込まなくてもよくなるからね。
あ、これってそのためのレイヤなんだね。
そ。あと、このレイヤは画像をコピーするためだけに使うレイヤだから、画面上には表示しないんだ。
ほんとだ。visibletrue にしてないね。
で、次の chWidthchHeight には、それぞれ文字の幅と高さを代入してるんだ。
この2つの変数は、画像をコピーする時に文字の幅と高さをいちいち計算しなくてもいいようにするために作ってるの。
えっと、chHeight の方は imgLay の画像の高さだからわかるんだけど、 chWidth って何で imgLay の画像の幅を 11 で割った値にしてるの?
日付表示用の画像 は 0 から 9 までの数字と / の 11 種類の文字を横に並べて作ってるから、 1文字分の幅は画像全体の幅の 11 分の 1 になるでしょ。
あ、そっか。それで 11 で割って1文字分の幅を計算してるんだね。
ん。あと、表画面用のレイヤと裏画面用のレイヤの作り方は前回と似てるからわかるよね?
うん、だいたい解るんだけど…
レイヤの幅を chWidth * 5 にしてるのは何でなの?
あぁ、それは5文字分の幅があればレイヤに日付が表示できるからだよ。
それってどういうこと?
月は 12 まであるから2文字分必要だし、日は 31 までだから、これも2文字分必要だよね。
それと、月と日を区切るのに / を使ってるから、日付を表示するためには全部で5文字分の幅が必要になるってワケ。
あ〜、なるほどね。
コンストラクタについてはこれでいいかな。
デストラクタはわかるよね?
うん、デストラクタはレイヤを無効化して、スーパークラスのデストラクタを呼び出してるだけだよね。
ん。じゃ次は drawChar メソッドね。
このメソッドでレイヤに文字(って言っても実際は画像だけど)を書き込んでるんだ。
ここでいよいよ copyRect メソッドが出てくるんだね。
copyRect メソッドは、レイヤ内の四角形の領域をコピーするメソッドなんだ。
引数は全部で7つあって、戻り値はないよ。

copyRect メソッドの引数>
引数名引数の意味
第1引数dleftコピー先の四角形の左端の座標
第2引数dtopコピー先の四角形の上端の座標
第3引数srcコピー元のレイヤオブジェクト
第4引数sleftコピー元の四角形の左端の座標
第5引数stopコピー元の四角形の上端の座標
第6引数swidthコピーする四角形の幅
第7引数sheightコピーする四角形の高さ

えっと、これだけ見てもよくわかんないかな…
だね。
じゃあ、表画面用のレイヤ(foreLay)の左端に『1』を書き込む例を説明するね。
うん。

foreLay の左端に『1』を書き込む例>

foreLay の左端に『1』を書き込む例

まず、コピー先は foreLay で、第1引数と第2引数はコピー先の四角形の左上の位置になるから…
foreLay の左端にコピーするってことは、第1引数と第2引数はどっちも 0
ん、そういうこと。

<コピー先の四角形の左上の位置(第1・第2引数)>

コピー先の四角形の左上の位置

で、第3引数はコピー元のレイヤオブジェクトだから、imgLay を指定するの。
それから、第4引数と第5引数はコピー元の四角形の左上の位置になるんだけど、これはどう指定したらいいかわかる?
えっ?…え〜っと、第5引数はコピー元四角形の上端の座標だから 0 だよね?
そだね。
じゃ第4引数は?
第4引数はコピー元四角形の左端の座標だから、imgLay の中にある「1」の左端の座標と同じになるよね?
うん、そうなるよね。
えっと、「1」より左には「0」があるから、「1」の左端の座標はレイヤの左端から1文字分右になるよね。
ってことは… chWidth、かな?
ん、正解。
よかった。合ってた。

<コピー元の四角形の左上の位置(第4・第5引数)>

コピー元の四角形の左上の位置

で、最後の第6引数と第7引数はコピーする四角形の幅と高さだから…?
第6引数が chWidth で、第7引数が chHeight だよね?
そうそう。

<コピー元の四角形のサイズ(第6・第7引数)>

コピー元の四角形のサイズ

ってワケで、表画面用のレイヤの左端に『1』を書き込む時には…

<表画面用のレイヤの左端に『1』を書き込むスクリプト>

foreLay.copyRect(0, 0, imgLay, chWidth, 0, chWidth, chHeight);

って書けば OK。
copyRect メソッドの使い方は解った?
うん。だいたい解ったよ。
ん、それじゃ結構長くなっちゃったから今回はここまでにしとこっか。
drawChar メソッドdrawDate メソッド は次回説明するね。
うん、りょーかい。
それじゃ、また次回ね!


前へ | TOP | 次へ