5.10 システムボタンプラグインのカスタマイズ

今回は、前回予告した通り SystemButtonPlugin クラスをカスタマイズして §5.1 のシステムボタンを作っていくね。
メッセージスキップとかオートモードとかのボタンがあるのって便利そうだけど、 6つもボタンを作るのって結構大変なんじゃない?
ううん、そんなことないよ。
追加したり変更したりするメソッドはこれだけだから。

追加するメソッドは追加するボタンの数だけあるみたいだけど、変更するメソッドってこれだけでいいの?
うん。SystemButtonPlugin クラスは簡単にボタンを増やせるように作ってあるから、 他のメソッドは全部そのまま使えるよ。
へぇ、そうなんだ。
じゃあまずは追加するメソッドから作っていくね。
は〜い!
最初はスキップボタンが押された時に呼び出される onSkipButtonClick メソッドからね。

onSkipButtonClick メソッド>

function onSkipButtonClick()
{
    kag.onSkipToNextStopMenuItemClick();  // スキップを開始します
}

えっ、これだけでいいの?
これだけで OK だよ。
onSkipToNextStopMenuItemClick って見たことないメソッドだけど、 これでメッセージがスキップできるの?
そうだよ。onSkipToNextStopMenuItemClick メソッドは メニューの「次の選択肢/未読まで進む」の項目を選択すると呼び出されるメソッドなんだ。
なるほどね。メソッドの名前に Menu とか Click とかが入ってるもんね。
じゃあ、スキップボタンを押すとメニューの「次の選択肢/未読まで進む」を選択したのと同じことになるんだよね?
ん、そういうこと。
じゃ次は onAutoModeButtonClick メソッドね。

onAutoModeButtonClick メソッド>

function onAutoModeButtonClick()
{
    kag.onAutoModeMenuItemClick();  // オートモードを開始します
}

これもシンプルだねぇ。
onAutoModeMenuItemClick っていうのも見たことないメソッドだけど、 メソッドの名前からすると「自動的に読み進む」を選択した時に呼び出されるメソッドってトコかな?
ん、そのとーり。
ちなみに onAutoModeMenuItemClick メソッドはオートモードの ON と OFF を切り替えるメソッドなんだけど、 基本的にボタンはオートモードが OFF の時しか押せないから、ここではオートモードを開始するのに使ってるんだ。
ふぅん、そうなんだ。
んじゃ次は onShowHistoryButtonClick メソッド。

onShowHistoryButtonClick メソッド

function onShowHistoryButtonClick()
{
    kag.onShowHistoryMenuItemClick();  // メッセージ履歴を表示します
}

えっと、onShowHistoryMenuItemClick メソッドってやっぱりメニューの「メッセージ履歴の表示」を選択した時に呼び出されるメソッド?
そうそう。
onShowHistoryMenuItemClick メソッドはメッセージ履歴の表示/非表示を切り替えるメソッドなんだけど、 ボタンが押せるのはメッセージ履歴が非表示の時だけだから、ここではメッセージ履歴の表示に使ってるってワケ。
なるほどね。
それじゃ最後は onHideMessageButtonClick メソッドだね。

onHideMessageButtonClick メソッド>

function onHideMessageButtonClick()
{
    kag.hideMessageLayerByUser();  // メッセージレイヤを非表示にします
}

これってメニューの「メッセージを消す」を選択した時に呼び出されるメソッドなんだよね?
…なんか今までのメソッドと違って、メソッドの名前に Menu とか入ってないけど。
ん〜、まぁ「メッセージを消す」を選択すると結果的には hideMessageLayerByUser メソッドが呼び出されることもあるんだけど、 このメソッドが直接呼び出されるわけじゃないんだ。
それってどういうこと?
メニューの「メッセージを消す」を選択すると、onRightClickMenuItemClick っていうメソッドが呼び出されるんだ。
で、このメソッドを呼び出すと、右クリックしたのと同じことになるの。
じゃあ結局「メッセージを消す」を選択するのと右クリックするのは同じってこと?
そ。デフォルトだと右クリックするとメッセージレイヤが非表示になるでしょ。
その時には onRightClickMenuItemClick メソッドの中で hideMessageLayerByUser メソッドが呼び出されるの。
それじゃあ右クリックサブルーチンとか作ると…
「メッセージを消す」を選択すると、右クリックサブルーチンの方が呼び出されるよ。
へぇ、そうなんだ。
だから rclick タグには name っていう属性があるわけだね。
あ、そっか。右クリックサブルーチンの内容に合わせてメニューに表示する内容を変えるんだね。
ん、そう。
で、ボタンをクリックした時は右クリックサブルーチンに関係なくメッセージウィンドウを非表示にしたいから、 onRightClickMenuItemClick メソッドじゃなくて hideMessageLayerByUser メソッドの方を呼び出してメッセージウィンドウを非表示にしてるってワケ。
なるほどね〜。
じゃこれで追加するメソッドはできたから、次は変更するメソッドを見ていくね。
はーい!
まずは createButtons メソッドから。
これはボタンを追加するだけだからそんなに難しくないと思うよ。
ってワケで、createButtons メソッドを書き換えてみて。
うん、わかった。
…あ、今回使うボタンの画像ってどれなの?
あ、そーだった。画像がないとボタンが作れないよね。
今回使うボタンの画像はこれ。

<セーブボタン用画像 button_save.png
セーブボタン用画像

<ロードボタン用画像 button_load.png
ロードボタン用画像

<メッセージスキップボタン用画像 button_skip.png
メッセージスキップボタン用画像

<オートモードボタン用画像 button_auto.png
オートモードボタン用画像

<メッセージ履歴表示ボタン用画像 button_history.png
メッセージ履歴表示ボタン用画像

<メッセージウィンドウ消去用ボタン画像 button_hide.png
メッセージウィンドウ消去用ボタン画像

ボタン用のレイヤには §5.6§5.7 で作った ExSystemButtonLayer クラスを使うから、 それぞれのボタンの画像は左から通常時・押されてる時・マウスカーソルが乗ってる時・使えない時に表示される画像になってるよ。
これで createButtons メソッドが作れるはずだよ。
えっと、元々の createButtons メソッドSystemButtonLayer だったのを ExSystemButtonLayer に変えればいいんだよね?
ん、そう。コンストラクタの引数はどっちも同じだからね。
わかった。それじゃやってみるね。

createButtons メソッド>

function createButtons(parent, array)
{
    var obj;

    // ボタン 0 (セーブ)
    array.add(obj = new ExSystemButtonLayer(kag, parent, onSaveButtonClick));
    obj.loadImages('button_save'); // セーブボタン用画像を読み込みます

    // ボタン 1 (ロード)
    array.add(obj = new ExSystemButtonLayer(kag, parent, onLoadButtonClick));
    obj.loadImages('button_load'); // ロードボタン用画像を読み込みます

    // ボタン 2 (メッセージスキップ)
    array.add(obj = new ExSystemButtonLayer(kag, parent, onSkipButtonClick));
    obj.loadImages('button_skip'); // メッセージスキップボタン用画像を読み込みます

    // ボタン 3 (オートモード)
    array.add(obj = new ExSystemButtonLayer(kag, parent, onAutoModeButtonClick));
    obj.loadImages('button_auto'); // オートモードボタン用画像を読み込みます

    // ボタン 4 (メッセージ履歴表示)
    array.add(obj = new ExSystemButtonLayer(kag, parent, onShowHistoryButtonClick));
    obj.loadImages('button_history'); // メッセージ履歴表示ボタン用画像を読み込みます

    // ボタン 5 (メッセージウィンドウ消去)
    array.add(obj = new ExSystemButtonLayer(kag, parent, onHideMessageButtonClick));
    obj.loadImages('button_hide'); // メッセージウィンドウ消去ボタン用画像を読み込みます
}

こんな感じでいいよね…?
ん、これで OK だよ。
ちなみにこうすれば効果音が再生できるよ。

createButtons メソッド(効果音再生版)>

function createButtons(parent, array)
{
    var obj;

    // ボタン 0 (セーブ)
    array.add(obj = new ExSystemButtonLayer(kag, parent, onSaveButtonClick));
    obj.loadImages('button_save'); // セーブボタン用画像を読み込みます
    obj.clickse = 'click.wav'// ボタンをクリックした時に "click.wav" を再生します
    obj.clicksebuf = 1;        // クリック時の効果音の再生に 1 番のバッファを使用します
    obj.enterse = 'enter.wav'// ボタンの上にマウスカーソルが乗った時に "enter.wav" を再生します
    obj.entersebuf = 2;        // マウスカーソルが乗った時の効果音の再生に 2 番のバッファを使用します
    obj.leavese = 'leave.wav'// ボタンの外にマウスカーソルが出ていった時に "leave.wav" を再生します
    obj.leavesebuf = 2;        // マウスカーソルが出ていった時の効果音の再生に 2 番のバッファを使用します

    // 以下略
}

clickse とか clicksebuf とかって button タグの clickse 属性とか clicksebuf 属性とかと同じように指定すればいいんだよね?
うん、その辺は button タグに合わせて作ってるからね。
じゃ、最後は realign メソッド。
このメソッドって何が変わるの?
元々 realign メソッド ってボタンを横に並べていくメソッドだったでしょ。
うん、そうだったよね。
でも、今回はこんなふうにボタンを縦に並べるから…

メッセージウィンドウ

そっか、それで realign メソッドを書き換えなくちゃいけないんだね。
ってワケで、realign メソッドを書き換えてみて。
え? えっと…前は横に並べてたから、x_pos っていう変数を使って x 座標を変えていってたけど、今回は縦に並べるから、 y 座標の方を変えていけばいいんだよね…?
ん、そう。
じゃあ、btn_xx_pos の代わりに btn_yy_pos っていう変数を使うことにすると、 btn_yy_pos はどう初期化すればいいと思う?
う〜ん… btn_x って前は 0 から始まってたよね…
これってボタンの表示オフセットだから、btn_y になっても 0 から始めていいんじゃないかな?
そうだね。
あと、x_posbtn_x + x に初期化されてたから、 y_posbtn_y + y でいいのかな?
そ。これは xy に置き換えるだけで OK。
じゃ setPos メソッドの引数は?
前は setPos(x_pos, y) だったから、 今回は setPos(x, y_pos) だよね?
ん、それで OK。
じゃあ、最後の btn_y の値を更新するとこなんだけど…
今度はボタンの高さを足せばいいから、btn_y += obj.height; だよね?
それがちょっと違うんだ。
え、なんで?
今回作るシステムボタンは、ボタンとボタンの間にこんなふうに隙間があるから…

<ボタン間の隙間>

ボタン間の隙間(各2ピクセル)

その隙間の分の2ピクセルも btn_y に足しとかなきゃいけないんだ。
じゃあ btn_y += obj.height + 2; でいいの?
うん。
じゃこれで realign メソッドが作れると思うから、 改めて realign メソッドを書き換えてみて。
おっけー。

realign メソッド>

function realign()
{
    // ボタンの再配置
    // このメソッドは、ボタンを x y 位置から縦一列に配置します
    var fore, back, count, btn_y;

    count = foreButtons.count;
    btn_y = 0;
    for(var i = 0; i < count; i++)
    {
        var ypos = btn_y + y;
        var obj;

        obj = backButtons[i];
        obj.setPos(x, ypos);
        obj.absolute = 2000000-3; // 重ね合わせ順序はメッセージ履歴よりも奥にします

        obj = foreButtons[i];
        obj.setPos(x, ypos);
        obj.absolute = 2000000-3;

        btn_y += obj.height + 2; // ボタンとボタンの間に2ピクセルの隙間があるので height + 2 を足します
    }
}

ん〜、こんなところかな。
ん、OK だよ。
それじゃこれで一通り作れたから、実行して実際にボタンを作ってみよっか。
うん!
今回はメッセージウィンドウにこの画像を使うから、この画像をプロジェクトフォルダに置いて、 あと Config.tjs を書き直しといてね。

<メッセージウィンドウ用画像:messagewindow.png

メッセージウィンドウ用画像

えっと、frameGraphic"messagewindow" にすればいいんだよね?
うん。あとマージンと初期位置もこう変えといてね。

<メッセージレイヤの設定(Config.tjs より抜粋)>

// ◆ メッセージ枠用の画像
// メッセージ枠用の画像のファイル名を指定します。
// "" を指定するとメッセージ枠の画像を使用しません。また、メッセージ枠用の
// 画像を指定した場合、position タグでメッセージレイヤのサイズを変更すると
// おかしな表示になると思います
;frameGraphic = "messagewindow";  // position タグの frame 属性に相当


// ◆ 左右上下マージン
// マージン (余白) を pixel 単位で指定します。メッセージ枠用の画像を指定し
// た場合は、メッセージ枠の表示範囲内に設定する必要があります。
// これらは、position タグの marginl, maringt, marginr, marginb 属性に対応
// します。
;marginL = 16; // 左余白
;marginT = 16; // 上余白
;marginR = 96; // 右余白
;marginB = 16; // 下余白


// ◆ 初期位置
// これらは、position タグのそれぞれ left top width height の属性に対応しま
// す。
;ml = 20;  // 左端位置
;mt = 314; // 上端位置
;mw = 600; // 幅
;mh = 146; // 高さ

それと、セーブとロードに使ってる saveBookMarkToFileWithAsk メソッドと loadBookMarkFromFileWithAsk メソッドはフリーセーブ用のメソッドだから、 フリーセーブモードにしといてね。

<フリーセーブモードの設定(Config.tjs より抜粋)>

// ◆ フリーセーブ
// 栞の保存形式を指定します。
// false を指定すると、メニューバーの「栞をたどる」「栞をはさむ」の
// サブメニュー項目からセーブデータを保存したり読み込んだりします。
// この場合は保存可能な栞の最大の個数は numBookMarks によって制限
// されます。
// true を指定するとフリーセーブモードになり、「栞をたどる」では
// 「開く」ダイアログボックス、「栞をはさむ」では「名前を付けて保存」ダイア
// ログボックスが開き、栞を個別のファイルとして保存するモードになります。
// この場合は 保存可能な栞の個数に制限はありません。また、
// エクスプローラなどによる栞の管理が容易になります。
;freeSaveDataMode = true;

それじゃ、必要なファイルはここに置いとくから、実行してみて。
おっけー。

<実行結果>

表示されたウィンドウ

お〜、ちゃんとボタンが出来てる!
うん、うまくいったね。
ボタンの数が多いから作るの大変かと思ったけど、 意外とカンタンにできちゃったね。
まぁ SystemButtonPlugin クラスがボタンを簡単に追加できるように考えて作られてるからね。
そっか、なるほどね〜。
それぞれのボタンを押した時の結果は省略させてもらうけど、 全部ちゃんと動作するはずだから、一通り試しといてね。
うん、りょーかい。
それじゃ、システムボタンも完成したことだし、これで第5章はおしまい。
次の章は何するの?
第6章はコンフィグ画面を作ってみようと思うんだ。
コンフィグ画面って、ウィンドウとフルスクリーンを切り替えたり、メッセージの表示速度を設定したりする画面のことだよね?
そうそう、それ。
右クリックサブルーチンを使って、右クリックするとコンフィグ画面が表示されるようにするの。
なんか今までよりさらに複雑になりそうな感じだね。
ん〜、まぁでもクリッカブルマップを使ってコンフィグ画面を作るから、結構作りやすいと思うよ。
ふぅん、そうなんだ。
ってワケで、次の章もがんばってついてきてね!
は〜い!


前へ | TOP | 次へ