拙著「あどばんすど 吉里吉里/TJS ノベルゲーム開発ガイド」のサポート情報をまとめてあります。
スクリーンショット
この本で紹介しているスクリプトの実行画面をいくつか掲載します。
左上:システムボタンから呼び出されたセーブ画面(グラフィカルボタンのみで実現/サムネイル画像右下の四角は上書き禁止用のチェックボックス)、右上:同コンフィグ画面(スライダーで無段階調整可能)、左下:メッセージ履歴画面(バックログ画面)、右下:ミニゲーム画面(タイピングゲーム)。
正誤表
書籍側
位置 | 誤 | 正 | 備考 |
p58 | (do~whileステートメントの図) | (下図を参照) | |
p330 | slider_createtマクロ | slider_createマクロ | |
‐ | ‐ | ‐ |
収録サンプルスクリプト側
プロジェクトフォルダ | ファイル | 修正内容 | ファイル | 備考 |
5章\5_2以下のプロジェクト全て | others\Override.tjs | MyKAGWindow.goToStart()を追加。コンフィグ画面中に[システム‐最初に戻る]メニューを選択した場合の不具合に対処 | bugfix_5_2_20120725.zip | システムボタン、システムボタン+タイトルメニューその他込み、落ち葉+システムボタン+タイトルメニューその他込みで共通。2012/07/25 不具合が残っていたので再度修正 |
‐ | ‐ | ‐ | ‐ | ‐ |
補足
大体どのサンプルでも、最後に宣言したメンバ変数(英大文字で始まっているモノ)か、~_config.tjsの内容を修正すれば、外観程度なら簡単に変更できるようにしてある(できないサンプルもあるけど)。
2.14.10 クラスの分析・設計
Umpireクラスのstart()メソッドの最後、
// 先攻→後攻→先攻…と切り替え turn = turn ? 0 : 1;
は、turnが真(0以外)ならturnに0を、偽(0)なら1を代入する…という意味。結果的に0, 1, 0, 1…の繰り返しになる。
2番目のサンプルで、
ar p0 = new HumanPlayer("あなた"); var p1 = new ComputerPlayer2("コンピュータ"); var u = new Umpire(p0, p1);
としているが、次のようにしても普通に動作する。
var p0 = new ComputerPlayer("コンピュータ1"); var p1 = new ComputerPlayer2("コンピュータ2"); var u = new Umpire(p0, p1);
4.4.16 Alt+Enterキーで画面モードを切り替えるには
Windows Vista以降でAlt+Enterキーを押下するとBEEP音が鳴ります。これを避けるには、小技の「Alt+Enterキーで画面モードを切り替えるには」に記載したスクリプトに変更してください。単一行エディットを表示している時もスクリーンモードを切り替えられます。
4.6.3 関数useArchiveIfExists()の定義、自動的に読み込むフォルダを登録
- 二重起動のチェックを行っているのは、セーブデータ(特にシステム変数)の整合性を保つため排他制御が必要だから
- 二重起動を許すと、以下の問題が起きてしまう:起動した順にA、Bとする
- Aを起動
- Bを起動
- Aでゲームをプレイし、終了(この時点でセーブデータ中のシステム変数はAの状態を記録している)
- Bで何もせず、ただ終了(この時点でセーブデータ中のシステム変数はBの状態になってしまい、Aの記録が失われる)
- 二重起動を許すと、以下の問題が起きてしまう:起動した順にA、Bとする
5 KAGプラグイン
- KAGプラグインのKAGシナリオファイルをコマンド行形式で記述しているのは、KAG3モード、KAG2互換モードの両方で動作するよう配慮しているため
- KAGシナリオファイルの先頭で、(typeof演算子で)KAGプラグインオブジェクトが定義されているかどうか確認しているのは、KAGプラグインを二重に読み込むのを避けるため
5.2.1 雪プラグインを改造する
116行目の
koma = (++koma) % 8;
はkomaに1加算したあと8で割った余りを求めている。komaの値は0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2…を繰り返すようになる。このように剰余算(%演算子)は「繰り返す値」を発生させるのに多用する。
5.3.4 マクロ
- あるクラスXのKAGプラグインオブジェクトを複数作成する場合で、かつ栞に個々のXオブジェクトのデータを記録する時、個々のXオブジェクトでセーブ/ロード用のキーが重複しないよう注意する必要がある
- 1つしか作成しない場合、このような問題はない(他のKAGプラグインと重複しない、ユニークなキーが必要なことに違いないが)
- ちなみにTelopPluginとBGMTelopPluginではコンストラクタ引数にキー名(___telopと___bgmtelop)を指定して、重複しないようにしてある
6.1.5 実装
95~96行目の
l = ((win.width - width)>>1) + win.left; t = ((win.height - height)>>1) + win.top;
はメインウィンドウ(KAGWindow)の中央に確認ダイアログボックスが表示されるよう座標を算出している。ここで使われている >>1 は右に符号付き1ビットシフトするという意味だが、これは2で割ることと同じ(逆に、左に符号付き1ビットシフトするのは2を掛けるのと同じ)。
例えば、10進数の50は2進数にすると0b110010となる。右に符号付き1ビットシフトすると0b11001となり10進数に直すと25になる(Windowsの電卓で確認されたい)。これは2進数が2のN乗で繰り上がるから。*1
現在では知らない人も多いと思うが、ビットシフトで2倍/2分の1にするという演算は、僅かに処理速度が速いという理由で多用されていたことがある(現在でも使われる局面はある)。
6.2.3 Override.tjs
Config.tjsのeverypage(ページ単位での閲覧を行うかどうか)がtrueの場合、5行するクロールするボタンは2つとも非表示にしている。
7.1.2 実装
- セーブ/ロードに対応させるならKAGプラグイン化するのが最も無難
- サンプルではメッセージレイヤを非表示にしているため、右クリックも利かないし履歴レイヤも表示されないが、ゲーム中、メッセージレイヤを表示する必要があるなら、rclickタグで右クリックを抑止しなくてはならない
謝辞
またしても#kirikiriircの皆さんには大変お世話になりました。感謝。