337 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			337 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #pragma once
 | ||
| 
 | ||
| /*************************************************************
 | ||
| 
 | ||
|              《剑啸江湖》 游戏抽象地图加载类
 | ||
| 
 | ||
| 		地图数据读取后将不保存用于显示的图片编号等数据,而仅仅
 | ||
| 	保存用于进行逻辑处理的点阵数据——使用一个字节表示一个坐标。
 | ||
| 	当坐标数据的值为1的时候,表示该坐标可以移动,否则表示该
 | ||
| 	坐标不可移动。
 | ||
| 
 | ||
| 		地图坐标数据采用连续的字节数组存储,访问一个坐标值的方
 | ||
| 	法为:y * 地图宽度 + x
 | ||
| 
 | ||
| ************************************************************/
 | ||
| #pragma  once 
 | ||
| //#include "MapSearchNode.h"
 | ||
| #include "CommonDef.h"
 | ||
| #include "VirturalMap.h"
 | ||
| class CBufferAllocator;
 | ||
| namespace jxcomm
 | ||
| {
 | ||
| 	namespace gameMap
 | ||
| 	{
 | ||
| 		class CAbstractMap:
 | ||
| 			public VirturalMap //VirturalMap 只有一个父函数
 | ||
| 		{
 | ||
| 		public:
 | ||
| 			static const int s_nInvalidMapPos	= -2;
 | ||
| 			static const int s_nBlockPos		= -1;
 | ||
| 			static const int MAX_WAY_POINT_COUNT =1024*16; //一个地图最大的关键点的数目
 | ||
| 
 | ||
| 			
 | ||
| 	
 | ||
| 			//关键节点的信息,用于
 | ||
| 			/*
 | ||
| 			typedef struct tagKeyPoint
 | ||
| 			{
 | ||
| 				MAPPOINT nearPoints[8];  //旁边的8个方向上关键点的id和距离
 | ||
| 				MAPPOINT pos;         //本身的坐标
 | ||
| 			}KEYPOINT,*PKEYPOINT;
 | ||
| 			*/
 | ||
| 
 | ||
| 			//typedef struct tag
 | ||
| 			DWORD		m_dwWidth;		//地图宽度
 | ||
| 			DWORD		m_dwHeight;		//地图高度
 | ||
| 		protected:
 | ||
| 			void		*m_pGridData;
 | ||
| 			BYTE		*m_pMoveableIndex;//每坐标对应的可移动索引,用于外层优化
 | ||
| 			INT			m_nMoveableCount;//移动坐标数量		
 | ||
| 
 | ||
| 			CBufferAllocator*	m_pAllocator;		//内存块管理器
 | ||
| 
 | ||
| 			//PKEYPOINT        m_pWayPointMap;  //存储相邻关键点(waypoint)之间的
 | ||
| 			//INT				 m_nWayPointCount;    //关键点的数目
 | ||
| 
 | ||
| 			INT			m_nBBoxT;		// 全空飞包围盒top
 | ||
| 			INT			m_nBBoxL;		// 全空飞包围盒left
 | ||
| 			INT			m_nBBoxR;		// 全空飞包围盒right
 | ||
| 			INT			m_nBBoxB;		// 全空飞包围盒bottom
 | ||
| 
 | ||
| 			
 | ||
| 		public:
 | ||
| 			CAbstractMap();
 | ||
| 			virtual ~CAbstractMap();
 | ||
| 
 | ||
| 			//地图的一个点的值
 | ||
| 			//virtual int GetMapPosValue(int x,int y) ;
 | ||
| 			
 | ||
| 
 | ||
| 			/* 从流中加载地图数据 */
 | ||
| 			bool LoadFromStream(wylib::stream::CBaseStream& stream);
 | ||
| 			/* 从文件中加载地图数据 */
 | ||
| 			bool LoadFromFile(LPCTSTR sFileName);
 | ||
| 			
 | ||
| 			/* 生成一张全部可以移动的地图 */
 | ||
| 			void initDefault(DWORD dwWidth, DWORD dwHeight);
 | ||
| 			
 | ||
| 			/* 获取地图宽度 */
 | ||
| 			inline int getWidth(){ return m_dwWidth; }
 | ||
| 			/* 获取地图高度 */
 | ||
| 			inline int getHeight(){ return m_dwHeight; }
 | ||
| 			/* 获取可移动坐标数量 */
 | ||
| 			inline int getMoveableCount(){ return m_nMoveableCount; }
 | ||
| 			/* 获取地图中所有单元数目 */
 | ||
| 			inline int getUnitCount() const { return m_dwWidth * m_dwHeight; }
 | ||
| 			/* 获取地图中x, y坐标的可移动索引,返回-1表示此位置不可移动,返回s_nInvalidMapPos表示 */
 | ||
| 
 | ||
| 			/*
 | ||
| 			inline int getMoveableIndex(DWORD x, DWORD y)
 | ||
| 			{
 | ||
| 				if ( x >= m_dwWidth || y >= m_dwHeight )
 | ||
| 					return s_nInvalidMapPos;
 | ||
| 				return m_pMoveableIndex[y * m_dwWidth + x].nValue; 
 | ||
| 			}
 | ||
| 			*/
 | ||
| 			inline bool isValidPos(DWORD x, DWORD y)
 | ||
| 			{
 | ||
| 				if ( x >= m_dwWidth || y >= m_dwHeight )
 | ||
| 					return false;
 | ||
| 				return true;
 | ||
| 			}
 | ||
| 			inline INT_PTR getPosIndex(DWORD x, DWORD y)
 | ||
| 			{
 | ||
| 				if (!isValidPos(x, y ))
 | ||
| 					return s_nInvalidMapPos;
 | ||
| 
 | ||
| 				return y * m_dwWidth + x;
 | ||
| 			}
 | ||
| 
 | ||
| 			/* 判断地图中x, y坐标位置是否可以移动,返回true表示坐标可以移动 */
 | ||
| 			inline bool canMove(DWORD x, DWORD y)
 | ||
| 			{
 | ||
| 				if ( x >= m_dwWidth || y >= m_dwHeight )
 | ||
| 					return false;
 | ||
| 				return m_pMoveableIndex[y * m_dwWidth + x]  != 0; 
 | ||
| 			}
 | ||
| 
 | ||
| 			/*设置不可移动点*/
 | ||
| 			inline void setUnablePoint(DWORD x, DWORD y, BYTE btValue)
 | ||
| 			{
 | ||
| 				if ( x >= m_dwWidth || y >= m_dwHeight )
 | ||
| 					return;
 | ||
| 				m_pMoveableIndex[y * m_dwWidth + x] = btValue;
 | ||
| 			}
 | ||
| 			/*
 | ||
| 			inline INT getWayPointDistance(INT x,INT y)
 | ||
| 			{
 | ||
| 				if(x==y || m_pWayPointMap ==NULL)return -1;
 | ||
| 				if( x <=0 || x> m_nWayPointCount || y <=0 || y > m_nWayPointCount) return -1;
 | ||
| 				if( x > y )
 | ||
| 				{
 | ||
| 					return  m_pMoveableIndex[y * m_dwWidth + x].nValue;
 | ||
| 				}
 | ||
| 				return -1;
 | ||
| 			}
 | ||
| 			*/
 | ||
| 
 | ||
| 			/* 
 | ||
| 			* Comments: 判断一个点是否能够移动
 | ||
| 			* Param unsigned int x: 点的坐标x
 | ||
| 			* Param unsigned int y: 点的坐标y
 | ||
| 			* Param bool & isCrossPoint: 是否是交叉点
 | ||
| 			* Param int & nMoveabledDirMask:  能够移动的方向的掩码,按位操作的,比如方向2能够移动,那么第2位将为1
 | ||
| 			* @Return bool: 返回是否能够移动
 | ||
| 			*/
 | ||
| 			/*
 | ||
| 			inline bool canMove(unsigned int x,unsigned int y,bool & isCrossPoint,int& nMoveabledDirMask  )
 | ||
| 			{
 | ||
| 				if ( x >= m_dwWidth || y >= m_dwHeight )
 | ||
| 				{
 | ||
| 					return false;
 | ||
| 				}
 | ||
| 				MAPPOINT point= m_pMoveableIndex[y * m_dwWidth + x];
 | ||
| 				if(point.nValue == -1 )
 | ||
| 				{
 | ||
| 					return false ;
 | ||
| 				}
 | ||
| 				if(point.isKeyPoint) //高16位不为0表示是转湾点
 | ||
| 				{
 | ||
| 					isCrossPoint = true; 
 | ||
| 				}
 | ||
| 				else
 | ||
| 				{
 | ||
| 					isCrossPoint = false; 
 | ||
| 				}
 | ||
| 				nMoveabledDirMask = point.auxPointID;
 | ||
| 				//nMoveabledDirMask =( nValue & 0xFFFF); //低位表示能够移动方向的掩码
 | ||
| 				return true;
 | ||
| 			}
 | ||
| 			*/
 | ||
| 
 | ||
| 			// 
 | ||
| 			// 寻点规则:以当前位置为中心的24*24区域(可视区域)内找落脚点(可移动区域)。从中心点连线到6点位置,然后
 | ||
| 			// 分左右两边,左边顺时针,右边逆时针转动,汇聚到12点重合。
 | ||
| 			
 | ||
| 			inline void GetEntityAppearPos(int curPosX, int curPosY, int nRangeMin,  int nRangeMax, int& nDestX, int& nDestY)
 | ||
| 			{	
 | ||
| 				nDestX = nDestY = -1;
 | ||
| 				for (int r = nRangeMin; r <= nRangeMax; r++)
 | ||
| 				{
 | ||
| 					// 下
 | ||
| 					int nTempX = 0;
 | ||
| 					int nTempY = curPosY + r;
 | ||
| 					if (nTempY < (int)m_dwHeight)
 | ||
| 					{
 | ||
| 						for (int col = 0; col <= r; col++)
 | ||
| 						{
 | ||
| 							nTempX = curPosX + col;
 | ||
| 							if (canMove(nTempX, nTempY))
 | ||
| 							{
 | ||
| 								nDestX = nTempX;
 | ||
| 								nDestY = nTempY;
 | ||
| 								return;
 | ||
| 							}	
 | ||
| 
 | ||
| 							if (col != 0)
 | ||
| 							{
 | ||
| 								nTempX = curPosX - col;
 | ||
| 								if (nTempX >= 0 && canMove(nTempX, nTempY))
 | ||
| 								{
 | ||
| 									nDestX = nTempX;
 | ||
| 									nDestY = nTempY;
 | ||
| 									return;
 | ||
| 								}	
 | ||
| 							}
 | ||
| 						}
 | ||
| 					}					
 | ||
| 
 | ||
| 					// 左
 | ||
| 					nTempX = curPosX - r;
 | ||
| 					if (nTempX >= 0)
 | ||
| 					{
 | ||
| 						for (int row = r-1; row > -r; row--)
 | ||
| 						{
 | ||
| 							nTempY = curPosY + row;
 | ||
| 							if (nTempY >= 0 && canMove(nTempX, nTempY))
 | ||
| 							{
 | ||
| 								nDestX = nTempX;
 | ||
| 								nDestY = nTempY;
 | ||
| 								return;
 | ||
| 							}
 | ||
| 						}
 | ||
| 					}
 | ||
| 
 | ||
| 
 | ||
| 					// 右
 | ||
| 					nTempX = curPosX + r;
 | ||
| 					if (nTempX < (int)m_dwWidth)
 | ||
| 					{
 | ||
| 						for (int row = r-1; row > -r; row--)
 | ||
| 						{
 | ||
| 							nTempY = curPosY + row;
 | ||
| 							if (nTempY >= 0 && canMove(nTempX, nTempY))
 | ||
| 							{
 | ||
| 								nDestX = nTempX;
 | ||
| 								nDestY = nTempY;
 | ||
| 								return;
 | ||
| 							}
 | ||
| 						}
 | ||
| 					}
 | ||
| 
 | ||
| 					// 上
 | ||
| 					nTempY = curPosY - r;
 | ||
| 					if (nTempY >= 0)
 | ||
| 					{
 | ||
| 						for (int col = 0; col <= r; col++)
 | ||
| 						{
 | ||
| 							nTempX = curPosX + col;
 | ||
| 							if (canMove(nTempX, nTempY))
 | ||
| 							{
 | ||
| 								nDestX = nTempX;
 | ||
| 								nDestY = nTempY;
 | ||
| 								return;
 | ||
| 							}	
 | ||
| 
 | ||
| 							if (col != 0)
 | ||
| 							{
 | ||
| 								nTempX = curPosX - col;
 | ||
| 								if (nTempX >= 0 && canMove(nTempX, nTempY))
 | ||
| 								{
 | ||
| 									nDestX = nTempX;
 | ||
| 									nDestY = nTempY;
 | ||
| 									return;
 | ||
| 								}	
 | ||
| 							}
 | ||
| 						}
 | ||
| 					}
 | ||
| 				}
 | ||
| 
 | ||
| 				// 如果在可视区域找不到,就在垂直方向找一个点
 | ||
| 				int nTempX = curPosX;
 | ||
| 				for (int i = nRangeMin+1; i < (int)m_dwWidth; i++)
 | ||
| 				{
 | ||
| 					if (canMove(nTempX, curPosY+i))
 | ||
| 					{
 | ||
| 						nDestX = nTempX;
 | ||
| 						nDestY = curPosY+i;
 | ||
| 						return;
 | ||
| 					}
 | ||
| 				}
 | ||
| 
 | ||
| 				for (int i = -nRangeMin-1; i >= 0; i--)
 | ||
| 				{
 | ||
| 					if (canMove(nTempX, curPosY+i))
 | ||
| 					{
 | ||
| 						nDestX = nTempX;
 | ||
| 						nDestY = curPosY+i;
 | ||
| 						return;
 | ||
| 					}
 | ||
| 				}
 | ||
| 			}
 | ||
| 
 | ||
| 		private:
 | ||
| 			/* 
 | ||
| 			* Comments: 初始化1个点旁边的2个方向的点信息
 | ||
| 			* Param int nPosX1: 点1的x
 | ||
| 			* Param int nPosY1: 点1的y
 | ||
| 			* Param int nPosX2: 点2的x
 | ||
| 			* Param int nPosY2: 点2的y
 | ||
| 			* Param int nDir1: 点1相对基础点的方向
 | ||
| 			* Param int nDir2: 点2相对基础点的方向
 | ||
| 			* Param int nWidth: 长度
 | ||
| 			* Param int nHeight: 宽度
 | ||
| 			* Param int & nDirMask: 方向的mask
 | ||
| 			* @Return bool: 如果2个方向有一个能走就返回true,否则返回false
 | ||
| 			*/
 | ||
| 			/*
 | ||
| 			inline bool Init2DirInfo(int nPosX1,int nPosY1,int nPosX2,int nPosY2, int nDir1,int nDir2, int &nDirMask,int nWidth,int nHeight)
 | ||
| 			{
 | ||
| 				bool dir1Moveable =false,dir2Moveable=false; //2个对着的方向是否能够通过
 | ||
| 				
 | ||
| 				if(nPosX1 >=0 && nPosX1 < nWidth && nPosY1 >=0 &&  nPosY1 <  nHeight)
 | ||
| 				{
 | ||
| 					dir1Moveable = canMove(nPosX1,nPosY1) ;  //点1能否移动
 | ||
| 				}
 | ||
| 				
 | ||
| 				if(nPosX2 >=0 && nPosX2 < nWidth && nPosY2 >=0 &&  nPosY2 <  nHeight)
 | ||
| 				{
 | ||
| 					dir2Moveable = canMove(nPosX2,nPosY2) ;  //点2能否移动
 | ||
| 				}
 | ||
| 				if(dir1Moveable)
 | ||
| 				{
 | ||
| 					nDirMask |= (1 << nDir1);
 | ||
| 				}
 | ||
| 				if(dir2Moveable)
 | ||
| 				{
 | ||
| 					nDirMask |= (1 << nDir2);
 | ||
| 				}
 | ||
| 				return (dir1Moveable ||  dir2Moveable);
 | ||
| 			}
 | ||
| 			*/
 | ||
| 
 | ||
| 		};
 | ||
| 	};
 | ||
| };
 |