まず、前回から機能追加した関数と変更点の説明を行った後、新たな部分の解説を行います。
所々で深く説明するべきところは細かく説明しますので来週まで解説は掛かるかも知れません。
解説の順番としては次のような予定しています。
(1)mapMove.cpp/h ヘッダなどの一部変更。
(2)map.cpp/h イベントのための関数を追加。
(3)eventScn.cpp/h イベント(シナリオ)システム本体。
(4)data.cpp 町イベントを接続。
(5)scnTown.cpp/h 町イベント・シナリオだけのソースファイル。
(6)gameMain.cpp イベント処理の組み込み。
今回のものは、実はイベント(シナリオ)システムの全ては完成していません。
ほんの触りの初期スタートイベントが動いただけです。まぁ、それでもシステムの基本的な形は完成しているのですが。
できた部分の説明後に、町人の会話とか、マップチェンジなどを組み込んで、あとは必要に応じて随時で追加する予定です。
それと講座の内容というかRPG完成まで、まだまだ作るものがあるので現状のペースだと年内完結は無理そうですが、気長にお付き合い下さいませ。(^^;
ここからRPGらしい作りがいのある部分(少々難易度が上がる)事になるので、よろしくお願いします。
では、説明を始めましょう。
[mapMove.cpp/h]
[table=border:1px;background:#FFFFFF;padding:2px 12px 2px 12px;solid #cccccc;][tr=text-align:center;]
[td=border:をpx;solid #cccccc;]
●ヘッダのインクルードを変更
[/td]
[/tr][/table]
(1)mapMove.cpp/h ヘッダなどの一部変更。
mapMove.cppから次のヘッダ・インクルードをmapMove.hに移してください。 理由はヘッダの関連が分かり辛くなったのでヘッダに組み込みました。
[map.h]
(2)map.cpp/h イベントのための関数を追加。
マップヘッダです。
イベント関連を追加します。
[table=border:1px;background:#FFFFFF;padding:2px 12px 2px 12px;solid #cccccc;][tr=text-align:center;]
[td=border:1px;solid #cccccc;]
●構造体
[/td]
[/tr][/table]
イベント構造体ポインタを追加しました。
このヘッダにeventScn.hをリンクすると循環リンクに陥るので、struct tag_EventData *をつかって
struct tag_EventDataの構造定義なしでもリンクポインタとして成立するようにしてあります。
※ このヘッダだけをインクルードしてもコンパイルは正常に通ります。
// マップ定義構造体
typedef struct {
char *mapName; //マップ名
char *mapFile; //マップファイル名(fmf)
char *mapCgFile; //マップチップ画像ファイル名
char *(mapCharFile[MAPDEF_CHAR_MAX]); //マップ固有のキャラクタ・ファイル
int EncountAveSteps; //エンカウント平均歩数(0にするとバトルは発生しない。エンカウントする平均歩数を指定する)
int EncountEnemyType; //エンカウントする敵の種別
struct tag_EventData *EventDataTable; //イベント構造体ポインタ
} MapDefine_t;
[td=border:1px;solid #cccccc;]
●関数の宣言
[/td]
[/tr][/table]
新たな関数を追加しています。
前回までの
// イベント判定
// map_Event(int x,int y); //詳細未定。
は消してください。
// マップのイベント情報ポインタを得る。
extern struct tag_EventData *map_GetEventData();
// イベント座標の取得
extern int map_GetEventPosition(int evtno,int *px,int *py);
// 座標のイベント判定。イベントでなければ-1が戻る。
extern int map_CheckMapEvent(int px,int py);
(2)map.cpp/h イベントのための関数を追加。
プログラムです。
同じくイベント処理を追加します。
●map_GetEventData
「マップのイベント情報ポインタを得る。」ためだけの関数で、現在有効なマップの
イベント情報ポインタを呼び出し元の関数に返します。
つまり、これだけの事しかしていないのでstruct tag_EventDataの定義実体が
このソースから見えなくてもコンパイルはエラーになりません。
でもstruct tag_EventDataの型名で扱うことで違うポインタが紛れ込む可能性をかなり
排除することが出来ます。つまりバグの可能性を減らせるのです。
これが安易にvoid*を使うより良い点です。
ただ、ヘッダをインルードしていないので、struct tag_EventDataの構造体定義がない
のにコンパイルが通るのは慣れない人には気持ち悪いと思います。
//----------------------------------------------------------------------
// マップのイベント情報ポインタを得る。
//----------------------------------------------------------------------
struct tag_EventData *map_GetEventData()
{
// 現在有効なマップデータはあるか?
if( MapMngData.cur_mapDef != NULL ) {
// イベント構造体ポインタを持ち帰る。
return MapMngData.cur_mapDef->EventDataTable;
}
// 有効な情報はない。
return NULL;
}
指定されたイベント番号の座標をpx,pyポインタに代入します。
もし、該当するイベント番号がマップに設定されいなかったらFALSEを戻り値として返します。
該当番号が有った場合にはTRUEとpx,pyを返します。
該当イベントはマップのイベントレイヤーのパーツ番号で調べます。
//----------------------------------------------------------------------
// イベント座標の取得
//----------------------------------------------------------------------
int map_GetEventPosition(int evtno,int *px,int *py)
{
// マップチップのサイズ。この関数内で使うので別の変数に入れておく。
int chipW = MapMngData.fmfHeader.byChipWidth;
int chipH = MapMngData.fmfHeader.byChipHeight;
// 全イベントをサーチ。
for( DWORD x=0 ; xmapCharFile[cn] != NULL ) {
// マップ固有キャラをロードする。
MapMngData.MapCharObj[cn] = char_Load(MapMngData.cur_mapDef->mapCharFile[cn],MAP_CHAR_XNUM,MAP_CHAR_YNUM);
MapMngData.MapCharNums++;
} else {
// マップ固有キャラは存在しない。
MapMngData.MapCharObj[cn] = NULL;
}
}
// イベントレイヤーがない場合は発生しない。
if( MapMngData.MapData[MAP_LAYER_EVENT] == NULL ) {
return;
}
// キャラ発生ポイントを全サーチ。
for( DWORD x=0 ; x= EVENT_CHAR_BORN_NO ) {
int cn = pno - EVENT_CHAR_BORN_NO; //キャラ番号
int objno = cn % MapMngData.MapCharNums; //オブジェクト番号
// 座標系など初期化してキャラを発生させる。
MapMngData.MapChar[cn].bLive = TRUE; //存在フラグ
MapMngData.MapChar[cn].muki = CHAR_MUKI_DOWN; //向き
MapMngData.MapChar[cn].px = x*chipW; //座標ピクセルX
MapMngData.MapChar[cn].py = y*chipH; //座標ピクセルY
MapMngData.MapChar[cn].ChrObjNo = objno; //キャラオブジェクトの番号
MapMngData.MapChar[cn].AnimOfs = GetRand(64); //アニメタイミングを変えるためのオフセット
}
}
}
}
次回はいよいよイベント(シナリオ)システムの中核であるeventScn.cpp/hに入ります。