ダンジョンを接続しますので、これでこのRPG講座のマップは全部揃ったことになります。
まず、新規に作成した関数とかモジュールを説明します。
まず状態管理から、ヘッダです。
[stateMng.h]
●関数の宣言
関数を追加します。バグというか制御の都合のための関数ですね。
状態遷移の流れの中で、うまく初期化されない場合があってので機能追加しました。 続いてプログラム本体。
[stateMng.cpp]
●構造体
bResetを追加しています。
// 状態管理オブジェクトの構造体
struct tag_StateMngObject {
int nowState; //現在の状態
int beforeState; //前の状態(STM_UpdateStateで現在の状態が変化なら保存)
int nextState; //次の状態(STM_UpdateStateで現在の状態にコピー)
int stateNums; //状態数
int bBack; //状態を戻すフラグ
int bReset; //状態を強制設定するフラグ
int *pFlameCounts; //フレームカウント配列。状態数分。
};
bResetの初期化を追加。
//----------------------------------------------------------------------
// 状態管理の初期化。オブジェクトを返す。
//----------------------------------------------------------------------
STATEMNG_OBJECT STM_Init(int stateNums)
{
STATEMNG_OBJECT object = NULL;
// まず状態管理オブジェクトメモリを確保する。
object = (STATEMNG_OBJECT)malloc( sizeof(struct tag_StateMngObject)) ;
// 状態管理オブジェクトの値を初期化する。
object->nowState = -1; //現在の状態
object->beforeState = -2; //前の状態(STM_UpdateStateで現在の状態が変化なら保存)
object->nextState = -3; //次の状態(STM_UpdateStateで現在の状態にコピー)
object->stateNums = stateNums; //状態数
object->bBack = FALSE; //状態を戻すフラグ
object->bReset = FALSE; //状態を強制設定するフラグ
object->pFlameCounts = NULL; //フレームカウント配列。状態数分。
// フレームカウント配列を確保する。
if( stateNums > 0 ) {
object->pFlameCounts = (int*)malloc( sizeof(int) * stateNums );
}
// 状態管理オブジェクトを返す。
return object;
}
ここもbResetの追加。くどいぐらいあちこちに追加があります。
//----------------------------------------------------------------------
// 状態を遷移する。フレームカウントは0に初期化される。
//----------------------------------------------------------------------
void STM_ChangeState(STATEMNG_OBJECT object,int state)
{
// 状態を遷移する準備。STM_UpdateStateで更新される。
object->nextState = state;
object->bBack = FALSE; //状態を戻すフラグ
object->bReset = FALSE; //状態を強制設定するフラグ
}
今回の目玉。強制設定関数の追加です。
フラグをセットしているだけで実際の処理は別の場所(STM_UpdateState)ですけどね。
//----------------------------------------------------------------------
// 状態を強制設定する。フレームカウントは0に初期化される。
//----------------------------------------------------------------------
void STM_ResetState(STATEMNG_OBJECT object,int state)
{
// 状態を遷移する準備。STM_UpdateStateで更新される。
object->nextState = state;
object->bBack = FALSE; //状態を戻すフラグ
object->bReset = TRUE; //状態を強制設定するフラグ
}
ここもbResetの追加。
//----------------------------------------------------------------------
// 前の状態に戻す。フレームカウントはそのまま。
//----------------------------------------------------------------------
void STM_SetBackState(STATEMNG_OBJECT object,int state)
{
// 状態を遷移する準備。STM_UpdateStateで更新される。
object->nextState = state;
object->bBack = TRUE; //状態を戻すフラグ
object->bReset = FALSE; //状態を強制設定するフラグ
}
いよいよ、実際の動作を定義します。
今までは、状態が変化したときのみフレームカウンタを0クリアしていましたが、強制設定(bReset)モードだと無条件に状態を設置してフレームカウンタを0クリアします。まぁ、お店メニューで問題が出たので、その対策なんですけどね。
//----------------------------------------------------------------------
// 状態・フレームカウントを更新する。
//----------------------------------------------------------------------
void STM_UpdateState(STATEMNG_OBJECT object)
{
int bTrans = FALSE; //状態遷移が無効
// 状態の遷移?
if( object->nextState != object->nowState ) {
bTrans = TRUE; //状態遷移する。
}
// 強制遷移?
if( object->bReset ) {
bTrans = TRUE; //状態遷移する。
object->bReset = FALSE; //強制遷移を停止。
}
// 遷移有り?
if( bTrans ) {
// 今の状態を保存
object->beforeState = object->nowState;
// 新しい状態に遷移
object->nowState = object->nextState;
// 状態を戻した?
if( object->bBack ) {
// フレームカウントを1つ加算。
STM_SetFrameCount(object,STM_GetFrameCount(object)+1);
} else {
// フレームカウントを初期化。
STM_SetFrameCount(object,0);
}
} else {
// フレームカウントを1つ加算。
STM_SetFrameCount(object,STM_GetFrameCount(object)+1);
}
}
続いては、ウィンドウ管理に関数を追加します。
[winMng.h]
まずヘッダに追加です。
●関数の宣言
ウィンドウの情報を返す関数を追加します。
// ウィンドウの情報を得る。
extern int winmng_GetWinParam(int winno,int *ppx,int *ppy,int *psizex,int *psizey);
[winMng.cpp]
●winmng_GetWinParam
指定されたウィンドウ番号のウィンドウの情報を返す関数です。
全てポインタ参照の変数に代入する形でWindowの座標やサイズなどの値を返します。
//----------------------------------------------------------------------
// ウィンドウの情報を得る。
//----------------------------------------------------------------------
int winmng_GetWinParam(int winno,int *ppx,int *ppy,int *psizex,int *psizey)
{
MACRO_ASSERT( winno>=0 );
MACRO_ASSERT( winnomapCharFile[cn];//名前をローカル変数入れて扱いやすく
if( file != NULL ) {
// マップ固有キャラをロードする。
MapMngData.MapCharObj[cn] = char_Load(file,MAP_CHAR_XNUM,MAP_CHAR_YNUM);
MapMngData.MapCharObjNums++;
// 発生制御フラグを設定する。
MapMngData.MapCharBorn[cn].bBorn = TRUE; //発生可能フラグ
if( NULL!=strstr(file,".one.png") ) { //一回だけ発生の特殊キャラの名前。
MapMngData.MapCharBorn[cn].bOnlyOne = TRUE; //一回だけの発生。
} else {
MapMngData.MapCharBorn[cn].bOnlyOne = FALSE;//何回でも発生。
}
} else {
// マップ固有キャラは存在しない。
MapMngData.MapCharObj[cn] = NULL;
MapMngData.MapCharBorn[cn].bBorn = FALSE; //発生可能フラグ
MapMngData.MapCharBorn[cn].bOnlyOne = FALSE;//一回だけの発生。
}
}
// イベントレイヤーがない場合は発生しない。
if( MapMngData.MapData[MAP_LAYER_EVENT] == NULL ) {
return;
}
// キャラ発生ポイントを全サーチ。
for( DWORD x=0 ; x= EVENT_CHAR_BORN_NO) && (pno = MapMngData.MapCharObjNums ) objno = 0;
// 一巡したらまずい。つまり割り当てる番号が無かった。
MACRO_ASSERT( objno != *pBaseObjNo );
}
}
// オブジェクト番号を持ち帰る。
return objno;
}
指定されたキャラクタ・オブジェクト番号が発生可能か調べまてFALSE/TRUEを返します。
もし、発生可能でbOnlyOneなら以降は発生しない様にbBornをFALSEにします。
//----------------------------------------------------------------------
// (内部関数)キャラのオブジェクト番号が発生可能かチェックする。
//----------------------------------------------------------------------
static int map_CheckBornCharObjNo( int objno )
{
// オブジェクトが存在する?
if( objno < MapMngData.MapCharObjNums ) {
// そのオブジェクトは発生可能?
if( MapMngData.MapCharBorn[objno].bBorn ) {
// そのオブジェクトは一回きり?
if( MapMngData.MapCharBorn[objno].bOnlyOne ) {
// 発生完了で次回は発生しない。
MapMngData.MapCharBorn[objno].bBorn = FALSE;
}
// 発生できる
return TRUE;
}
}
// この番号では発生不能
return FALSE;
}
次も下回りというか機能追加やら整理、新規モジュールの追加です。