システムカスタマイズについてダラダラやるよーその6.5
システムカスタマイズについてダラダラやるよーその6 - 永字八法の続き。
ちょっと寄り道して、ソースを整理します。
NScripterでのスクリプトの書き方について私見
NScripterのスクリプトで、最低限エラーが出ずに終了するパターンは、以下のようなものです。
*define game *start end
また、これらは一行ずつ別々のファイルに書いても問題ありません。nscr.exeは起動時に00.txt〜99.txtまでを全て読み込んで一つのファイルにしてからパースするからです。
それと、ラベルは指定さえしっかりしていれば、順番を入れ替えても問題が少ないです。
ですので、以下の様なスクリプト構造を提案します。
*start シナリオをここに書く end *define game *other_routine return end
また、これを拡張のしやすいようにバラけた番号のファイルに書き込むのがいいでしょう。
結果、スクリプトは下記のようになりました。
現在のスクリプト
00.txt
;$V2000G1000S800,600L10000 *start saveoff ; 完全手動セーブ宣言! kidokumode 1 ; 既読スキップモードを使用可能にする。 gosub *if_in_advance ; 一度は実行しておく。 gosub *text_lb_skip_start ; 一度は実行しておく。 gosub *initialize_global ; グローバル変数の初期設定 ; 画面サイズを取得しておく、 getwindowsize %window_width,%window_height gosub *initialize_textwindow ; テキストウィンドウの初期設定 set_window ; テキストウィンドウ表示
10.txt
(阿頼耶/あらや)(識/しき)@ あ\ い\ う\ え\ お\
50.txt
end *define ; メニューバーを全消し deletemenu mov %0,100 ; numalias定義用一時変数 mov %1,900 ; スプライト番号定義用の一時変数 mov %2,1000 ; グローバル変数用 ; グローバル変数を使用 globalon numalias global_first,%2:inc %2 ; グローバル変数の初期設定をしたかしていないかのフラグ。 ; bexecの結果を受け取る専用変数を宣言 numalias bexec,%0:inc %0 ; システムカスタマイズの宣言 textgosub *text_lb ; 既読スキップ有りで。 kidokuskip ; isskipの結果を受け取る専用変数を宣言 numalias isskip,%0:inc %0 ; ifの代替命令群の定義 defsub if_str_goto defsub if_str_gosub defsub if_int_goto defsub if_int_gosub defsub notif_str_goto defsub notif_str_gosub defsub notif_int_goto defsub notif_int_gosub numalias if_a,%0:inc %0 numalias if_b,%0:inc %0 numalias if_label,%0:inc %0 ; 自動記録なし autosaveoff ; 画面サイズ回り numalias window_width,%0:inc %0 numalias window_height,%0:inc %0 ; setwindow回り numalias sp_textwindow,%1:dec %1 ; テキストウィンドウ用のスプライト番号 humanz sp_textwindow ; 立ち絵の位置を設定 windowback ; テキストウィンドウをスプライトの位置まで引っ込ませる。 numalias textwindow_width,%0:inc %0 numalias textwindow_height,%0:inc %0 numalias textwindow_x,%0:inc %0 numalias textwindow_y,%0:inc %0 numalias font_width,%0:inc %0 numalias font_height,%0:inc %0 numalias font_space,%0:inc %0 numalias line_space,%0:inc %0 numalias font_bold,%0:inc %0 numalias font_shadow,%0:inc %0 numalias font_ruby_width,%0:inc %0 numalias font_ruby_height,%0:inc %0 numalias textwindow_padding_top,%0:inc %0 numalias textwindow_padding_bottom,%0:inc %0 numalias textwindow_padding_left,%0:inc %0 numalias textwindow_padding_right,%0:inc %0 numalias textwindow_area_width,%0:inc %0 numalias textwindow_area_height,%0:inc %0 numalias textwindow_col,%0:inc %0 numalias textwindow_row,%0:inc %0 numalias textwindow_alpha,%2:inc %2 defsub set_window ; テキストの表示速度 numalias textspeed,%2:inc %2 ; 画面内の位置のNEWS指定 defsub news_position numalias news_ax,%0:inc %0 numalias news_ay,%0:inc %0 numalias news_x,%0:inc %0 numalias news_y,%0:inc %0 numalias parent_width,%0:inc %0 numalias parent_height,%0:inc %0 numalias child_width,%0:inc %0 numalias child_height,%0:inc %0
60.txt
game
70.txt
*text_lb ; 今がスキップモードなら、さっさと次に回す。 isskip %isskip if_int_goto %isskip,1,*text_lb_end ; 進む機能を持つキーが押されていないことをチェックする。 checkkey %bexec,"LCLICK" :skip (0-%bexec) * 1 checkkey %bexec,"WHEELDOWN":skip (0-%bexec) * 2 checkkey %bexec,"SPACE" :skip (0-%bexec) * 3 checkkey %bexec,"RETURN" :skip (0-%bexec) * 4 checkkey %bexec,"K" :skip (0-%bexec) * 5 ; CTRLは除く。CTRL押しっぱなしで進むのは、最近のエンジンではよくある仕様だから。 *text_lb_init_loop bclear *text_lb_loop bexec $bexec,%bexec ; Sにセーブを、Lにロードを割り当てる。 if_str_goto $bexec,"S",*save_routine if_str_goto $bexec,"L",*load_routine ; Kに既読スキップモードを割り当てる。 if_str_goto $bexec,"K",*text_lb_skip_start ; マウスの左クリックかホイールダウン、キーボードのスペースキーかエンターキーかコントロールキーで次へ。 if_str_goto $bexec,"LCLICK",*text_lb_end if_str_goto $bexec,"WHEELDOWN",*text_lb_end if_str_goto $bexec,"SPACE",*text_lb_end if_str_goto $bexec,"RETURN",*text_lb_end if_str_goto $bexec,"CTRL",*text_lb_end ; それ以外の入力であれば、ループする goto *text_lb_loop ; スキップモード開始用 *text_lb_skip_start systemcall skip ; クリック待ちの終了処理。 *text_lb_end texec return
75.txt
*initialize_global if %global_first=1 return ; グローバル変数の初期設定 ; テキストウィンドウの不透明度 mov %textwindow_alpha,255 ; テキストの表示速度(一文字表示にかけるミリ秒数)を格納する変数 mov %textspeed,40 ; フラグを立てる。 mov %global_first,1 return *initialize_textwindow ; テキストウィンドウの画像読み込み lsph sp_textwindow,":c;>600,200,#888888",0,0 ; テキストウィンドウのサイズを取得 getspsize sp_textwindow,%textwindow_width,%textwindow_height ; テキストウィンドウの配置場所の決定(左下にしている) news_position %textwindow_x,%textwindow_y,%window_width,%window_height,%textwindow_width,%textwindow_height,-1,1 ; フォントの設定 mov %font_width,22 mov %font_height,22 mov %font_space,2 mov %line_space,2 mov %font_bold,0 mov %font_shadow,1 mov %font_ruby_width,11 mov %font_ruby_height,11 ; パディングの設定 mov %textwindow_padding_top,8 mov %textwindow_padding_bottom,8 mov %textwindow_padding_left,12 mov %textwindow_padding_right,12 ; エフェクト中もテキストウィンドウが消えないようにする。 erasetextwindow 0 ; 念のため、右クリックを殺しておく。 rmode 0 return ; 実際にテキストウィンドウを設定する。 *set_window ; 実際の表示領域の広さを計算する。 mov %textwindow_area_width,%textwindow_width-%textwindow_padding_left-%textwindow_padding_right mov %textwindow_area_height,%textwindow_height-%textwindow_padding_top-%textwindow_padding_bottom ; 表示領域の広さから、行数や文字数を計算する。 mov %textwindow_col,%textwindow_area_width/(%font_width+%font_space) mov %textwindow_row,%textwindow_area_height/(%font_height+%line_space+%font_ruby_height) ; 数値を反映した値にする。 setwindow %textwindow_x+%textwindow_padding_top,%textwindow_y+%textwindow_padding_left,%textwindow_col,1+%textwindow_row,%font_width,%font_height,%font_space,%line_space,0,%font_bold,%font_shadow,#000000,%textwindow_x,%textwindow_y,%window_width,%window_height rubyon %font_ruby_width,%font_ruby_height textspeed %textspeed amsp sp_textwindow,%textwindow_x,%textwindow_y,%textwindow_alpha vsp sp_textwindow,1 return ; ある領域の中で、小さな領域を配置する時のための座標を計算する。 *news_position getparam i%news_x,i%news_y,%parent_width,%parent_height,%child_width,%child_height,%news_ax,%news_ay mov %%news_x,%parent_width-%child_width if %news_ax=-1 mov %%news_x,0 if %news_ax=0 div %%news_x,2 mov %%news_y,%parent_height-%child_height if %news_ay=-1 mov %%news_y,0 if %news_ay=0 div %%news_y,2 return ; セーブルーチン *save_routine savegame 0 mesbox "セーブしました。","save game" goto *text_lb ; ロードルーチン *load_routine loadgame 0 ; if 代替命令群本体ルーチン *if_str_goto getparam $if_a,$if_b,$if_label if $if_a=$if_b return $if_label return *if_str_gosub getparam $if_a,$if_b,$if_label if $if_a=$if_b goto $if_label return *if_int_goto getparam %if_a,%if_b,$if_label if %if_a=%if_b return $if_label return *if_int_gosub getparam %if_a,%if_b,$if_label if %if_a=%if_b goto $if_label return *notif_str_goto getparam $if_a,$if_b,$if_label notif $if_a=$if_b return $if_label return *notif_str_gosub getparam $if_a,$if_b,$if_label notif $if_a=$if_b goto $if_label return *notif_int_goto getparam %if_a,%if_b,$if_label notif %if_a=%if_b return $if_label return *notif_int_gosub getparam %if_a,%if_b,$if_label notif %if_a=%if_b goto $if_label return *if_in_advance ; 定義した命令を、一度は実行しておくためのルーチン。 ; 起動時に一回だけやっておけばよい。 if_str_goto ""," ",*dummy if_str_gosub ""," ",*dummy if_int_goto 0,1,*dummy if_int_gosub 0,1,*dummy notif_str_goto "","",*dummy notif_str_gosub "","",*dummy notif_int_goto 0,0,*dummy notif_int_gosub 0,0,*dummy if_str_gosub "","",*if_in_advance_dummy if_str_goto "","",*if_in_advance1 *if_in_advance1 if_int_gosub 0,0,*if_in_advance_dummy if_int_goto 0,0,*if_in_advance2 *if_in_advance2 notif_str_gosub ""," ",*if_in_advance_dummy notif_str_goto ""," ",*if_in_advance3 *if_in_advance3 notif_int_gosub 0,1,*if_in_advance_dummy notif_int_goto 0,1,*if_in_advance4 *if_in_advance4 return *if_in_advance_dummy ; 何もしないよ。 return
99.txt
return end
次回予告
今度こそ、発言者欄を……。