■ 新・ゲーム開発講座




■ へっぽこプログラミング入門♪


■第26夜:イベントフラグ

さて前回まででお絵描きの時間はひとまず終りました。これからしばらくは「よりゲームらしい内容」ということで、フラグ、分岐、ラベルジャンプ、選択肢といった少し構造的な部分の話を進めていきたいと思います。
そんな訳で、今回はイベントフラグのON/OFFです。とても単純な処理ですが、これがゲームらしい処理の基本になります。せっかくなのでスクリプトのDEBUG用にフラグの値をメッセージBOXで表示するコマンドも作っておきましょう。

■書式:#flag_on n
フラグ n をONする

■書式:#flag_off n
フラグ n をOFFする

■書式:#disp_flag n
メッセージBoxを開いてフラグ n の内容を示す


■処理の概要

特に難しい内容はありません。コマンドパラメータに応じて、イベントフラグ(配列で用意しておきます)の値をON/OFFしているだけです。

■Mode_stat

main.h の 構造体 Mode_stat にイベントフラグを追加します。とりあえず256個もあれば充分でしょう。フラグはON/OFFの2値しか取らない予定なので bool 型でも良さそうですが、VC++5以降では bool 型変数はサイズ的には結局 char なので、ここでは char で宣言しておきます。余談ですが古いVC++(4.2)では bool は int と同じサイズ=4バイトなので、コンパイラのバージョンによって4倍ものサイズ差が生じてしまいます(・・・やれやれ ^^)。


#define EVENT_FLAG_MAX 256

struct _Mode_stat {
int
int
int
int
int
int
char
flag_text; //テキスト表示:ON=進行 OFF=停止
flag_delay; //遅延処理:ON=遅延あり OFF=遅延なし
flag_cursor_blink; //カーソル点滅:ON=点滅 OFF=点滅なし
flag_halt; //終了:ON=終了 OFF=終了ではない
flag_page2; //改ページ type2:ON=改ページ処理中 OFF=処理中でない
flag_g_change; //画面切替効果:ON=切替中 OFF=処理はない
char event_flag[EVENT_FLAG_MAX]; //イベントフラグ
};



■フラグの初期値

フラグの初期値としては OFF を採用したい(イベントが起きてもいないのにフラグがONでは困る)ので、テキストエンジンの初期化のときに一緒にOFFに初期化してしまいましょう。デフォルトパラメータを決めている _Set_Default_params() に、以下のリストのような追加を行います。

シンボルの値は Basic_Tips.h にて ON=1、OFF=0 に定義してありますので初期値設定しなくても不都合はないのですが、将来的なバグの混入(スクリプターにとってかなり迷惑なタイプ ^^;)を防止するために、今回はきちんと初期化するようにしました。


void _Set_Default_params()
{

int i;

TEXT_WAIT = 60; //1文字表示のウェイト(ms)
Font_Size = 20; //Font size

TEXT_AREA.left = 20; //テキスト表示エリア(左)
TEXT_AREA.top = 20; //テキスト表示エリア(上)
TEXT_AREA.right = 640-20; //テキスト表示エリア(右)
TEXT_AREA.bottom= 480-20; //テキスト表示エリア(下)

TEXT_X=TEXT_AREA.left; //文字位置カウンタ初期化(表示エリア左肩から始まる)
TEXT_Y=TEXT_AREA.top;

TEXT_X_PITCH = Font_Size/2; //文字送りピッチ(X)
TEXT_Y_PITCH = Font_Size*130/100; //文字送りピッチ(Y)

//イベントフラグはゼロクリア
for ( i=0 ; i<EVENT_FLAG_MAX ; i++ ) {
Mode_stat.event_flag[i]=OFF;
}

}

■コマンド解釈部

TextEngine.cppvoid Command_call() に以下の部分を加えます。

void Command_call()
{

//省略

//コマンド名の評価 → 処理関数呼び出し
if( strcmp(com_name,"delay" )==0 ){ Com_delay(); flag=ON;} //遅延
if( strcmp(com_name,"wait" )==0 ){ Com_cursor_blink(); flag=ON;} //カーソルブリンク
if( strcmp(com_name,"w" )==0 ){ Com_cursor_blink(); flag=ON;} //カーソルブリンク
if( strcmp(com_name,"halt" )==0 ){ Com_halt(); flag=ON;} //終了
if( strcmp(com_name,"page" )==0 ){ Com_page(); flag=ON;} //改ページ
if( strcmp(com_name,"g_load" )==0 ){ Com_g_load(); flag=ON;} //BMPのLOAD
if( strcmp(com_name,"g_copy" )==0 ){ Com_g_copy(); flag=ON;} //BMPのCOPY
if( strcmp(com_name,"g_change")==0 ){ Com_g_change(); flag=ON;} //画面切替
if( strcmp(com_name,"flag_on" )==0 ){ Com_flag_on(); flag=ON;} //イベントフラグON
if( strcmp(com_name,"flag_off")==0 ){ Com_flag_off(); flag=ON;} //イベントフラグOFF
if( strcmp(com_name,"disp_flag")==0 ){ Com_disp_flag(); flag=ON;} //イベントフラグ表示

//省略

}


■コマンド実行部

やっていることは至極単純ですね(なんか最近単純ばっかりだなぁ ^^;)。フラグの番号をコマンドパラメータから解釈して、ON/OFF、あるいは表示しているだけです。フラグ番号がMAX値を越えていないか、という最低限のチェックしかしていませんが、まさか負の番号を指定するスクリプターは・・・いないことを祈りましょう(爆) 気になる方はもうすこしエラーチェックをがんばってみるのも良いでしょう。


//----------------------------------------------
// イベントフラグ ON
//----------------------------------------------

int Com_flag_on()
{

int no;

//フラグ番号の取得
TEXT++;
no = kaiseki_10();

if( no < EVENT_FLAG_MAX ){
Mode_stat.event_flag[no]=ON;
}else{
char str[256];
sprintf(str,"フラグ番号 %d は無効です",no);
msg( str, "Com_flag_on()" );
}

return 0;


}

//----------------------------------------------
// イベントフラグ OFF
//----------------------------------------------

int Com_flag_off()
{

int no;

//フラグ番号の取得
TEXT++;
no = kaiseki_10();

if( no < EVENT_FLAG_MAX ){
Mode_stat.event_flag[no]=OFF;
}else{
char str[256];
sprintf(str,"フラグ番号 %d は無効です",no);
msg( str, "Com_flag_off()" );
}

return 0;

}

//----------------------------------------------
// イベントフラグ表示(DEBUG用)
//----------------------------------------------

int Com_disp_flag()
{

int no;
char str[256];

//フラグ番号の取得
TEXT++;
no = kaiseki_10();

if( no < EVENT_FLAG_MAX ){

if( Mode_stat.event_flag[no]==ON ){
sprintf( str,"Flag %d = ON ",no );
}else if( Mode_stat.event_flag[no]==OFF ){
sprintf( str,"Flag %d = OFF",no );
}else{
sprintf( str,"Flag %d = UNKNOWN",no );
}

msg( str,"Com_disp_flag()" );

}else{
sprintf(str,"フラグ番号 %d は無効です",no);
msg( str, "Com_disp_flag()" );
}

return 0;

}


ソースはこちらになりますので、実行して動作を確認してみて下さい。次回は if 文での条件分岐を解説します。