Files
mir_server/sdk/commonLib/include/JXAbsGameMap.h
aixianling 5c9f1dae4a init
2025-01-09 17:45:40 +08:00

337 lines
8.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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