10.6 メッセージ履歴のカスタマイズ 〜基本編〜(その3)

前回で dispInit メソッドでやってる処理の STEP 1 がチェックできたから、今回は STEP 2 から見てくね。
は〜い。
STEP 2 はメッセージ履歴に表示されてるメッセージを全部消すっていう処理なんだけど、 何でこの処理をここでやるんだったか覚えてる?
え〜っとねぇ…確かメッセージ履歴画面を閉じても、 表示されてたメッセージは消えないから、ここでメッセージを消しとかないと、 2回目以降にメッセージ履歴画面を表示する時に、 前に表示されてたメッセージが表示されちゃうんだったよね?
ん、そうそう。
で、前に表示されてた履歴メッセージを消してるのが、 HistoryLayer クラス(元々の履歴レイヤのクラス)の dispInit メソッドの中の…

HistoryLayer クラスの dispInit メソッド(HistoryLayer.tjs より抜粋)>

function dispInit()
{
    // 全部再描画と初期設定
    makeButtons(); // ボタンを作成

    // メッセージ履歴アクション関係の設定
    lastLine = currentLine;
    endAction();
    lastAction = currentAction;

    // antialiased…メッセージ履歴に表示する文字にアンチエイリアスをかけるかどうか
    // (基本的に Config.tjs の defaultAntialiased の設定に従います)
    antialiased = window.chDefaultAntialiased;

    // メッセージをすべて消去
    clearBack();

(以下略)
※コメントを追加しています。

ここの部分ね。
この clearBack っていうメソッドで履歴メッセージを消してるんだ。
ちゃんと makeButtons メソッドが呼び出された後に呼び出されるようになってるでしょ。
makeButtons メソッドが呼び出されてから clearBack メソッドが呼び出されるまでの間にも何かやってるみたいだけど?
うん。そーなんだけど、makeButtons メソッドと clearBack メソッドの間でやってることは、 今回のカスタマイズには直接関係ないから、詳しい説明は省略させてもらうね。
そーなんだ。わかった。
で、この clearBack メソッドはカスタマイズ(オーバーライド)してないから、 HistoryLayer クラスの clearBack メソッドが呼び出されるんだ。
えっと、カスタマイズしてないメソッドは HistoryLayer クラスの方のメソッドが呼び出されるってことでいーのかな?
ん、そう思ってもらっていいよ。
じゃ clearBack メソッドのスクリプトを見てくね。
え、clearBack メソッドはカスタマイズしてないのに見てくの?
今は clearBack メソッドをカスタマイズしてないけど、 最終的にはちょっとだけカスタマイズする必要が出てくるからね。
どうやってメッセージを消してるのかってことくらいは今のうちに確認しといた方がいいかなって思って。
そっか。りょーかい。
これが clearBack メソッドのスクリプトだよ。

clearBack メソッド(HistoryLayer.tjs より抜粋)>

function clearBack(n)
{
    // 背景を塗りつぶす
    if(n === void)
    {
        face = dfAlpha;
        fillRect(0, 0, width, height, 0xc8000000);
    }
    else
    {
        face = dfAlpha;
        if(verticalView)
            fillRect(width - marginR - (n+1)*lineHeight, controlHeight, lineHeight,
                height - controlHeight, 0xc8000000);
        else
            fillRect(0, n*lineHeight + controlHeight + marginT, width, lineHeight, 0xc8000000);
    }
}

じゃとりあえず最初から見てこっか。
まずは最初の if のとこからね。
nvoid かどうかをチェックしてるね。
この n って clearBack メソッドの引数になってるみたいだけど、dispInit メソッドで clearBack メソッドを呼び出す時は引数ないよね?
n は画面上に表示されてる履歴メッセージの何行目を消すかを指定するための引数なんだ。
例えば n0 だったら、 メッセージ履歴画面の一番上の行(縦書きの時は一番右の行)に表示されてるメッセージを消すってことね。
あと、n は省略することもできて、省略した場合は全部の履歴メッセージが消されるんだ。
※メッセージ履歴画面上に表示されている一番上の行(縦書きの時は一番右の行)を0行目と数えます。
じゃあココclearBack メソッドを呼び出すと履歴メッセージが全部消えるってことだね。
そ。じゃまずは nvoid の時、つまり引数 n が省略されてる時の処理から見てくね。
あ、この n みたいにデフォルト値が設定されてない引数を省略すると void が代入されるからね。
そーなんだ。
だから“clearBack();”を実行すると、引数の nvoid になるの。
ってことは、引数を省略して clearBack メソッドを呼び出すと、if ブロックの中身が実行されるってことだね。
そうなるね。
じゃ if ブロックの中身から見てみよっか。
最初に“face = dfAlpha;”って書いてあるけど、これって何やってるの?
face ってのはレイヤクラス(Layer クラス)のプロパティで、レイヤへの描画形式を取得したり設定したりするためのプロパティだよ。
レイヤへの描画形式って?
レイヤにはメイン画像とマスク画像があるでしょ。
マスク画像でメイン画像の透明な部分とか不透明な部分を指定できるんだよね。
ん、画像のアンチエイリアスが必要な時とかはメイン画像とマスク画像を使うよね。
って言っても、PNG 形式とか TLG 形式の画像だとメイン画像とマスク画像を1つのファイルにまとめられるから、 普段はあんまり意識してないかもしれないけどね。
そーだね。メイン画像とマスク画像を別々に用意することってあんまりないかも。
で、この face プロパティに dfAlpha って値を代入すると、そのレイヤのメイン画像とマスク画像が両方扱えるようになるんだ。
dfAlpha は初めから定義されている(定義しなくても使える)値です。
え、メイン画像とマスク画像が使えるのって当たり前なんじゃないの?
確かにメイン画像とマスク画像が両方使えるのが普通だから当たり前に感じるんだけど、 face プロパティの設定を変えると、 メイン画像だけを扱えるようにしたり、マスク画像だけを扱えるようにしたり、 あと領域画像だけを扱えるようにしたりできるんだ。
ちなみに領域画像はクリッカブルマップで領域アクションを設定する時に使うやつのことね。
※詳しくは吉里吉里2リファレンスの「Layer クラス」−「face プロパティ」の項目をご覧ください。
へぇ、そんなことできるんだ?
まぁ普通はメイン画像だけを扱えるようにしたりとかする必要はないから、 face プロパティの設定を変えることは滅多にないと思うけどね。
そっか…でもここface プロパティを設定してるってことは、 何か意味があるってことなんだよね?
う〜ん、どうなんだろ…よくわかんない。
えっ?
face プロパティはデフォルトでメイン画像とマスク画像が両方使えるようになってるはずだから、 特にここで dfAlpha に設定しなくても問題ないと思うんだけど…
とりあえず、この後メイン画像とマスク画像の両方を操作する必要があるから、一応 dfAlpha に設定してるって感じじゃないかな?よくわかんないけど。
まぁ、ここはそんなに気にしなくても大丈夫だよ、たぶん。
face プロパティはデフォルトで dfAuto(レイヤ表示タイプ(type プロパティ)に従って自動的に描画形式を決定する)に設定されています。レイヤ表示タイプはデフォルトで ltAlpha(メイン画像とマスク画像を両方有効にする)に設定されているため、face プロパティはデフォルト(dfAuto)の状態でメイン画像とマスク画像を両方扱えます。
そ、そーなんだ…
じゃ次いくねー。
次は fillRect メソッドを呼び出してるとこだけど、 fillRect メソッドは今までに何回か使ってるから、 何やってるか大体わかるよね?
fillRect メソッドについては §3.2 参照。
んーと…第3引数の width と第4引数の height ってメッセージ履歴レイヤの幅と高さだよね?
そだよ。
じゃあ、左上の点が (0, 0) で、 大きさが width×height ピクセルの四角形の部分を 0xc8000000 って色で塗りつぶしてるってことかな?
ん、そういうことだね。
ちなみに 左上の点が (0, 0) で、 大きさが width×height ピクセルの四角形の部分ってのは、 つまりメッセージ履歴レイヤ全体ってことだね。
あ、そっか。確かにそーなるね。
ところで、0xc8000000 ってどんな色なの?
fillRect メソッドの第5引数に指定する色の値は AARRGGBB 形式になってるってのは覚えてる?
えっと…AA のとこに不透明度を指定して、 RR のとこに赤色度(って言うとちょっとヘンかもだけど、 要するにこの値が大きいほど赤っぽくなるってことだよ)を指定して、 GG のとこに緑色度を指定して、 BB のとこに青色度を指定するんじゃなかったっけ?
そうそう。
0xc8000000 だと RR, GG, BB の部分が全部ゼロだから、 赤色・緑色・青色の強さ(赤色度・緑色度・青色度)は全部ゼロってことになるね。
ちなみにこの値は光の三原色でいうところの赤色・緑色・青色の強さに対応してるから、 全部ゼロだと黒色になるよ。
じゃあ、不透明度の“c8”ってゆーのはどんな値なの?
c8200 って意味なんだけど、 AA, RR, GG, BB の値はそれぞれ16進数で指定するから、 ちょっとわかりにくいかもね。
ところで、16進数は知ってる?
う〜ん、聞いたことはあるけど、あんまりよく知らないかな。
今までにも何回か AARRGGBB 形式の色の指定は出てきたけど、 16進数の説明はしてなかったから、今回は簡単に説明しとくね。
まず普通の数字は 1, 2, 3, ... って数えていくと、 10 で2桁になるよね。
そだね。
だから普通の数字は10進数って呼ばれてるのね。
んで、16進数の方は 1, 2, 3, ... って数えていって、 16 で2桁になるから16進数なの。
でも数字って 0〜9 までだから16種類もないよね?
ん。だから 10 から先は数字の代わりにアルファベットを使って、 10 は a、11 は b、12 は c、13 は d、14 は e、15 は f って表すの。
16 になったら2桁になるから 10 になるわけね。
10〜15 を大文字で A〜F と表すこともあります。
16進数だと 1610 になるってこと?
そ。でも、単に“10”って書くと10進数の 10 なのか16進数の 1010進数でいうところの 16)なのか区別がつかないから、 16進数は先頭に“0x”って書くようになってるの。
そうすれば単に“10”なら10進数の 10 で、“0x10”なら16進数の 10 ってわかるからね。
なるほど、だから色を指定する時には“0x”なんとか、って書いてたんだね。
ところで、例えば 12 って“10×1+2”って表せるよね。
10×1+2=12 だから、そーなるね。
16進数の場合も同じように表せて、例えば c8 だと“c×10+8”って表せるんだ。
c×10 ってとこがなんかヘンな感じだね。
さっき言ったように、16進数の c1010進数で表すと、それぞれ 1216 になるから、 “c×10+8”は10進数で表すと“12×16+8”になるの。
12×16+8 ってことは…200
そ。だから c8200 なの。
つまり、第5引数の 0xc8000000 は、不透明度を 200 にして黒色で塗りつぶすってことになるワケ。
あ〜、なるほど、そーなるんだ。
ちなみに 20016進数に直す時は 16 で割ってみるとわかりやすいと思うよ。余りも計算する必要あるけどね。
200÷1612 余り 8 だよね。
1216進数で c816進数でも 8 だから、200c8 になるの。
へぇ、なるほどね。
さて、ちょっと話が逸れちゃったから、もっかいここの if ブロックの中身でやってることを確認しとくね。
…って言っても、基本的には fillRect メソッドを呼び出してるだけだけどね。
if ブロックの中身は、引数の nvoid のとき、つまり引数が省略されてるときに実行されて、 fillRect メソッドを呼び出すことで、 メッセージ履歴レイヤを不透明度 200 の黒色で塗りつぶしてる、ってことだよね。
ん、そういうこと。
じゃ次は else ブロックの中身を見てこっか。
まず、else ブロックの中身がどんな時に実行されるかはわかるよね?
nvoid じゃない時だから、 引数の n を省略しなかった時だよね?
そ。つまり、引数の n に何行目のメッセージを消すかを指定した時ってことだね。
最初の“face = alpha;”はさっきも出てきたからいいとして、 次の if のとこは何やってるかわかる?
えっと…verticalView って履歴メッセージを縦書き表示にしてるときに true になるんだったっけ?
そだよ。
verticalView については §10.5 参照。
ん〜…verticalViewtrue でも false でも fillRect メソッドを実行してるみたいだけど、引数が違ってるのかな。
横書きの時と縦書きの時じゃメッセージを表示する場所が違うからね。
つまり、メッセージを消す時に塗りつぶす場所も違うから、引数も違ってるの。
そっか。
ところで、else ブロックの中の fillRect メソッドの引数に色んな変数みたいなのがあるけど、これって今までに出てきたっけ?
大体出てきてるけど、一応一通り確認していくね。
まず、縦書き表示してる時に呼び出される fillRect メソッドの引数に出てくる widthheightmarginR はわかる?
widthheight はそれぞれメッセージ履歴レイヤの幅と高さで、marginR は履歴メッセージを表示する時の右側の余白かな?
そうそう。
あと、lineHeight はメッセージ1行分の幅で、 controlHeight は「前ページ」とかのボタンの高さだよ。
lineHeight”なのにメッセージ1行分の“幅”なの?
幅だったら“lineWidth”になるんじゃない?
まぁそーなんだけどね。
じゃちょっと横書き表示の時に呼び出される fillRect メソッドの引数も見てみて。
まず marginT はわかるよね?
履歴メッセージを表示する時の上側の余白だよね。
そう。
で、こっちの(横書き表示の時に呼び出される)fillRect メソッドにも lineHeight があるでしょ。
うん、あるね。
横書き表示の場合は、lineHeight はメッセージ1行分の幅じゃなくて高さになるんだ。
え、そーなの?
ん。つまり、lineHeight はメッセージが縦書き表示か横書き表示かによって意味が変わるってワケ。
変数の名前が lineHeight なのは、 横書き表示の時を基準にして名前が付けられたからじゃないかな。横書きの方が良く使われるしね。
へぇ、そーなんだ。
言葉で説明しただけじゃちょっとわかりにくいかもしれないから、 width, height, marginR, marginT, lineHeight, controlHeight をそれぞれ図で表してみるね。
まずこれが横書きの場合。

<横書き表示(verticalViewfalse)の時の各変数の意味>

で、こっちが縦書きの場合。

<縦書き表示(verticalViewtrue)の時の各変数の意味>

それじゃ最後に縦書き表示のときの fillRect メソッドの引数と、横書き表示のときの fillRect メソッドの引数を詳しく見てくね。
どっちもちょっとややこしそーだよね。
まーね。
じゃあまずはよく使う横書き表示のときの引数から見てくことにするね。
はーい。
あ、そうそう。
さっき clearBack メソッドの引数の n は、メッセージ履歴画面の上から(縦書き表示の時は右から)何行目のメッセージを消すかを指定する引数だって言ったよね。
うん、そー言ってたよね。
だからこの2つの fillRect メソッドの引数は、画面の上から(縦書き表示の時は右から)n 番目の行のメッセージを消すようになってるんだけど、“n 番目の行”だとわかりにくいと思うから、こっから先は“5 番目の行”を消す場合を見てくことにするね。
ちなみに何番目の行でも考え方はおんなじだから。
そっか。確かにその方がわかりやすそーだね。
横書き表示してる場合で、メッセージ履歴画面の上から5行目のメッセージを消すってことは、 下の図の赤色の四角形の中身を fillRect メソッドで塗りつぶして消せばいいってことになるよね。

<横書き表示時、上から5行目のメッセージを消去するために塗りつぶす領域>

そーだね。ここを塗りつぶせば5行目のメッセージが消せそうだね。
まず、fillRect メソッドの第1引数が 0 になるってのはすぐにわかるでしょ?
え〜っと…第1引数は塗りつぶす四角形の左端の座標だから…
あ、確かに画面の左端から塗りつぶしてるから、左端の座標は 0 だね。
じゃあ次は第2引数の“n*lineHeight + controlHeight + marginT”だね。
5行目のメッセージを消すときは n5 になるから、 “5*lineHeight + controlHeight + marginT”になるよね。
ん〜…これがよくわかんないよね。
式だとわかりにくいと思うから、図にしてみるね。

<横書き表示の時の fillRect メソッドの第2引数(塗りつぶす矩形領域の上端座標)の求め方>

塗りつぶす四角形の上端が controlHeightmarginT と、あと lineHeight 5つ分(5*lineHeight)を足した位置になってるでしょ?
そーだね。
だから、fillRect メソッドの第2引数は(ちょっと順番が入れ替わってるけど)“5*lineHeight + controlHeight + marginT”になるの。
なるほど。確かにそーなるね。
じゃ次は第3引数と第4引数、つまり塗りつぶす四角形の幅と高さね。
まず幅が width になるのはわかるよね?
えっと、画面の左端から右端までの部分を塗りつぶしてるから?
そ。つまり、塗りつぶす部分の幅はメッセージ履歴レイヤの幅(width)と同じになるってわけだね。
あと、高さが lineHeight なのもわかるでしょ?
1行メッセージを消すから、メッセージ1行分の高さになってるってコト?
ん、そういうこと。
第5引数の 0xc8000000 はさっきも出てきたから大丈夫だよね。
不透明度 200 の黒色で塗りつぶすってことだよね。
そう。じゃこれで横書き表示の時は OK だね。
次は縦書き表示の時の fillRect メソッドの引数を見てくね。
今度は第1引数からややこしくなってるね。
これも図にした方が良さそうだね。
と、その前に、消すのは5行目のメッセージだから、 第1引数は“width - marginR - 6*lineHeight”になるってのは OK?
うん、おっけーだよ。
n5 だから、(n+1) の部分が 6 になってるんだよね。
ん。それじゃ図を見てみるね。

<縦書き表示の時の fillRect メソッドの第1引数(塗りつぶす矩形領域の左端座標)の求め方>

まず、水色の矢印の長さが marginRlineHeight 6つ分(6*lineHeight)を足した長さになるってのはわかるよね?
うん。
塗りつぶす行の分も入ってるから、lineHeight 5つ分じゃなくって6つ分を足した長さになるんだよね。
そうそう。そこんとこ注意してね。
で、塗りつぶす四角形の左端の位置は、メッセージ履歴レイヤの幅(width)から水色の矢印の長さを引いた長さと同じだから、 “width - marginR - 6*lineHeight”になるよね。
それって fillRect メソッドの第1引数とおんなじだね。
だから第1引数はこうなるわけね。
あと、第2引数が controlHeight になるのも図からわかるよね。
うん。
第3引数(塗りつぶす部分の幅)と第4引数(塗りつぶす部分の高さ)がそれぞれ lineHeightheight - controlHeight になるのはわかる?
えっとね…まず塗りつぶす部分の幅はメッセージ1行分の幅だから lineHeight なんだよね。
さっき縦書き表示の時は lineHeight はメッセージ1行分の幅になるって言ってたもんね。
ん、そうそう。
あと、第4引数が height - controlHeight になるのは、 塗りつぶす部分の上端が controlHeight の位置になってて、塗りつぶす部分の高さが height より controlHeight の分だけ短くなるから、かな?
そういうこと。
第5引数は横書きの時と同じだから問題ないよね。
うん。
じゃあこれで clearBack メソッドは OK だね。
これでやっと STEP 2 が終わったね。
だね。それじゃ今回はこの辺にして、次回は STEP 3 のメッセージ表示処理を見ていくことにするね。
は〜い。
それじゃ、また次回ね!


前へ | TOP | 次へ