[map.cpp]
またまた、マップ管理プログラム編の続きとなります。
●map_HitJudge
地形データとマップ固有キャラクタ(町人)の当たり判定をします。
実際には内部関数で処理しているので、詳細はそちらで説明します。
//----------------------------------------------------------------------
// マップとの当たり判定。px,pyはキャラクタの左上座標。
//----------------------------------------------------------------------
int map_HitJudge(int px,int py)
{
//------------------------
// マップと当たり判定
//------------------------
// 当たり判定
if( map_HitCheck(px,py) ) {
// 歩けない。
return TRUE;
}
//------------------------
// 町人と当たり判定
//------------------------
if( map_HitMapCharCheck(px,py) ) {
// 歩けない。
return TRUE;
}
return FALSE;
}
マップ地形との当たり判定をします。
マップデータの当たり判定レイヤー(MAP_LAYER_HIT)の情報を使います。
int chipX = px / MapMngData.fmfHeader.byChipWidth;
int chipY = py / MapMngData.fmfHeader.byChipHeight;
でピクセル座標からマップチップの座標系に変換して、MapMngData.MapData[MAP_LAYER_HIT]
から該当座標のマップチップパーツ番号を得ます。
該当パーツが0番の場合は歩けません(何番が歩けないかは自分で決めるんですけどね)。
//----------------------------------------------------------------------
// マップとの当たりチェック
//----------------------------------------------------------------------
static int map_HitCheck(int px,int py)
{
// ピクセル位置からチップ位置に変換
int chipX = px / MapMngData.fmfHeader.byChipWidth;
int chipY = py / MapMngData.fmfHeader.byChipHeight;
// 当たり判定レイヤーがない場合は歩けることとする。
if( MapMngData.MapData[MAP_LAYER_HIT] == NULL ) {
// 歩ける。当たらない。
return FALSE;
}
// パーツ番号が0だと歩けない。
int pno = MapMngData.MapData[MAP_LAYER_HIT][(MapMngData.fmfHeader.dwWidth*chipY)+chipX];
if( pno == 0 ) {
// 歩けない。当たる。
return TRUE;
}
// 歩ける。当たらない。
return FALSE;
}
マップ固有のキャラクタと当たり判定します。
まぁ、単にbLiveが生存のキャラクタと座標が一致するか見ているだけです。
※ この当たり判定はキャラクタが必ずbyChipWidthとbyChipHeightで
割り切れるピクセル座標に立っている前提がありますので、
キャラクタがピクセル単位の移動を許す場合などは、範囲のあるちゃんとした
当たり判定が必要となります、
//----------------------------------------------------------------------
// マップ固有キャラとの当たり判定
//----------------------------------------------------------------------
static int map_HitMapCharCheck(int px,int py)
{
// 有効なキャラクタを表示する。
for( int bn=0 ; bnmapFile, "rb" );
MACRO_ASSERT(fp!=NULL);
// マップヘッダをロードする。
fread( &MapMngData.fmfHeader, sizeof(FMF_HEADER), 1, fp );
// メモリを確保する。
BYTE *mapdata = (BYTE *)malloc( MapMngData.fmfHeader.dwSize );
MapMngData.allMapData = mapdata;//保存
MACRO_ASSERT(mapdata!=NULL);
// 残りの部分を確保したメモリに読み込む
fread( mapdata, MapMngData.fmfHeader.dwSize, 1, fp );
// ファイルを閉じる。
fclose( fp );
// レイヤー毎にアドレスを振り分ける。
int layerSize = MapMngData.fmfHeader.dwSize / MapMngData.fmfHeader.byLayerCount;
for( int ly=0 ; lymapCgFile ) ;
MACRO_ASSERT(MapMngData.imageMapCG!=-1);
}
マップ名でマップ定義を検索します。
検索に成功したらマップ定義のポインタを返却します。
ちなみにマップ定義の終端は、mapNameがNULLになっている必要があります。
//----------------------------------------------------------------------
// マップ定義を検索する。
//----------------------------------------------------------------------
static MapDefine_t *map_searchMapDef(char *mapName)
{
// 終端までループ
int index = 0;
while( MapMngData.mapDefines[index].mapName != NULL ) {
// 同じマップ名?
if( 0==strcmp(MapMngData.mapDefines[index].mapName,mapName) ) {
// ポインタを返す。
return &MapMngData.mapDefines[index];
}
}
// 検索できませんでした。
return NULL;
}
マップデータを破棄します。
mallocしていたのはallMapDataだけですのでこれを破棄。
DeleteGraphでマップパーツの画像も破棄します。
//----------------------------------------------------------------------
// 前のマップデータの破棄
//----------------------------------------------------------------------
static void map_DeleteMapData()
{
// 今有効なマップデータがある?
if( MapMngData.cur_mapDef != NULL ) {
MapMngData.cur_mapDef = NULL; //今有効なマップはない。
// 前のデータがある?
if( MapMngData.allMapData != NULL ) {
// 破棄する。
free( MapMngData.allMapData );
MapMngData.allMapData = NULL;//破棄したのでNULLに。
}
// レーヤー毎の情報もクリア
for( int ly=0 ; lymapCharFile[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*CHAR_PIXEL_SIZEX; //座標ピクセルX
MapMngData.MapChar[cn].py = y*CHAR_PIXEL_SIZEY; //座標ピクセルY
MapMngData.MapChar[cn].ChrObjNo = objno; //キャラオブジェクトの番号
MapMngData.MapChar[cn].AnimOfs = GetRand(64); //アニメタイミングを変えるためのオフセット
}
}
}
}
マップ固有のキャラクタのオブジェクトを破棄する処理です。
同時に、表示するキャラの情報もクリアします。
//----------------------------------------------------------------------
// 前のキャラクタの破棄
//----------------------------------------------------------------------
static void map_DeleteCharData()
{
// 最大キャラ定義のMAXまで。
for( int cn=0 ; cn<MAPDEF_CHAR_MAX ; cn++ ) {
// 有効なマック固有キャラのオブジェクト?
if( MapMngData.MapCharObj[cn] != NULL ) {
// マップ固有キャラを破棄する。
char_Delete(MapMngData.MapCharObj[cn]);
MapMngData.MapCharObj[cn] = NULL;
}
}
MapMngData.MapCharNums = 0; //マップ固有のキャラのオブジェクトの有効数
// 表示キャラも無効にする。
for( int bn=0 ; bn<MAP_CHAR_BORN_MAX ; bn++ ) {
MapMngData.MapChar[bn].bLive = FALSE; //存在フラグ
}
}
長かったですね。お疲れさまでした。
と言っても、マップとキャラクタの処理はまだまだ続きますよ!
次はマップ定義データです。関連物ですので続けてお届けします。