ちょー簡単RPG講座8-4 マップ管理の3。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

ちょー簡単RPG講座8-4 マップ管理の3。

投稿記事 by softya(ソフト屋) » 14年前


[map.cpp]

またまた、マップ管理プログラム編の続きとなります。
●map_HitJudge
地形データとマップ固有キャラクタ(町人)の当たり判定をします。
実際には内部関数で処理しているので、詳細はそちらで説明します。

CODE:

//----------------------------------------------------------------------
//	マップとの当たり判定。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_HitCheck
マップ地形との当たり判定をします。
マップデータの当たり判定レイヤー(MAP_LAYER_HIT)の情報を使います。
int chipX = px / MapMngData.fmfHeader.byChipWidth;
int chipY = py / MapMngData.fmfHeader.byChipHeight;
でピクセル座標からマップチップの座標系に変換して、MapMngData.MapData[MAP_LAYER_HIT]
から該当座標のマップチップパーツ番号を得ます。
該当パーツが0番の場合は歩けません(何番が歩けないかは自分で決めるんですけどね)。

CODE:

//----------------------------------------------------------------------
//	マップとの当たりチェック
//----------------------------------------------------------------------
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;
}
●map_HitMapCharCheck
マップ固有のキャラクタと当たり判定します。
まぁ、単にbLiveが生存のキャラクタと座標が一致するか見ているだけです。
※ この当たり判定はキャラクタが必ずbyChipWidthとbyChipHeightで
割り切れるピクセル座標に立っている前提がありますので、
キャラクタがピクセル単位の移動を許す場合などは、範囲のあるちゃんとした
当たり判定が必要となります、

CODE:

//----------------------------------------------------------------------
//	マップ固有キャラとの当たり判定
//----------------------------------------------------------------------
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);
}
●map_searchMapDef
マップ名でマップ定義を検索します。
検索に成功したらマップ定義のポインタを返却します。
ちなみにマップ定義の終端は、mapNameがNULLになっている必要があります。

CODE:

//----------------------------------------------------------------------
//	マップ定義を検索する。
//----------------------------------------------------------------------
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;
}
●map_DeleteMapData
マップデータを破棄します。
mallocしていたのはallMapDataだけですのでこれを破棄。
DeleteGraphでマップパーツの画像も破棄します。

CODE:

//----------------------------------------------------------------------
//	前のマップデータの破棄
//----------------------------------------------------------------------
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);	//アニメタイミングを変えるためのオフセット
			}
		}
	}
}
●map_DeleteCharData
マップ固有のキャラクタのオブジェクトを破棄する処理です。
同時に、表示するキャラの情報もクリアします。

CODE:

//----------------------------------------------------------------------
//	前のキャラクタの破棄
//----------------------------------------------------------------------
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;		//存在フラグ
	}
}
やった!ついにマップ管理編の終了です。
長かったですね。お疲れさまでした。
と言っても、マップとキャラクタの処理はまだまだ続きますよ!
次はマップ定義データです。関連物ですので続けてお届けします。

コメントはまだありません。