遊戲區域系統設計

遊戲中地圖中需要設置不同的區域,尤其對於大型網絡遊戲,到達不同的區域通常需要提示本區域名稱。

本節主要討論一種遊戲區域信息的管理方法:

實現步驟

 1.首先對區域進行邊界的描邊,獲取區域的頂點描邊信息


2. 對存儲有區域以及區域描邊信息的地圖,進行信息歸納,形成稀疏矩陣存儲, 其中X再加入區域ID信息

區域信息:

	struct SMapAreaInfo
	{
		typedef vector<POINT> Polygon;
		 size_t		nAreaID;		// area map ID
		 size_t		nFatherMapID;		 // father ID, a nearest area which contain it
		// tchar	szAreaName[32];		// Area name
		 tstring szAreaName;
		 RECT areaMapRect;                     //area Rect
		Polygon points;                        //edge points
	};
地圖信息: MapQueryInfo 即是 稀疏矩陣,每行表示Y這行的邊界點以及該邊界點的區域ID; 包含有本地圖中所有的區域,用List 存儲起來
	struct SMapStateInfo
	{
		struct QueryItem{ 
			short tile; 
			size_t areaid ;
		};
		typedef vector<QueryItem> MapLine;
		typedef vector<MapLine> MapQueryInfo;

		typedef std::vector<size_t> StateAreaList;
	    size_t nStateID;                                       //state ID, key to a map that should be showed independent
		StateAreaList  nStateAreaInfo;  
		MapQueryInfo QueryVertex;                         // query map information
	};
	typedef std::map<size_t,SMapAreaInfo>	TMAP_AREAINFO;          //map of SMapAreaInfo list 
	typedef map<size_t, SMapStateInfo>   TMAP_MAPSTATE;         //map of  SMapStateInfo list map

 3.判斷區域所屬哪個區域

 主要思想即: 查詢每張地圖的稀疏矩陣(即含有區域ID的邊界頂點信息),如果X大於最近的邊界,則在這個區域之中。

/**get Title's area ID
 * @ param  x,y:  is title 
 * @ param  nStateId: the title in map ID   
 * @ return : title's area ID
*/
size_t CTerrainMapArea::GetTerrainAreaID(size_t nStateID, int x, int y)const
{	
	//case 1 title or stateID is error return 0
	if(x<0 || y<0 || nStateID <=0)
		return 0;
	//case 2: title is not in map of nStateID return 0
        RECT rc;
	if(GetBoundingBox(nStateID,rc))
	{
		// for safety consideration, y = limitation should be deleted,  
		// as it may be a vertex point that not in linenum
		if(x<rc.left || x > rc.right || y<=rc.top || y >= rc.bottom)
			return 0;
	}
	TMAP_MAPSTATE::const_iterator it = m_mapTerrainMapState.find(nStateID);
	if (it == m_mapTerrainMapState.end())
		return 0;
	// put in case 2
	SMapStateInfo::MapLine const & line = it->second.QueryVertex[y];

	size_t index = 0;
	//case x <min( line[].titles) or x > max(line.titles) is out of consideration
	while(x > line[index].tile ){
		index++;
	}
	if(/*stackArearId.size() >0*/ index >0){
		//return stackArearId.top();
        return line[index - 1].areaid;
	}
	else{
		return 0;
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章