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);
|
||
}
|
||
*/
|
||
|
||
};
|
||
};
|
||
};
|