⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gamedstar.cpp

📁 是一个基于热血战国协议的网络游戏。现在脱机客户端先放出来给大家研究
💻 CPP
字号:

/*
 * name: GameDStar.cpp
 *
 * desc: 游戏路径,这个是D*寻路算法,和A*不一样的
 *
*/

#include "StdAfx.h"
#include "GameMir.h"

/*
=======================================================================
函数名       : CGameDStar
功能描述     : 
参数         : void
返回值       : NULL
=======================================================================
*/
CGameDStar::CGameDStar(CGameMap &map, CGameMir &game)
:m_Map(map) 
,m_DStarArray(NULL)
,m_DStarWidth(0)
,m_DStarHeight(0)
,m_Game(game)
{
	m_DStarTarget.x=0;
	m_DStarTarget.y=0;
}

/*
=======================================================================
函数名       : ~CGameDStar
功能描述     : 
参数         : void
返回值       : NULL
=======================================================================
*/
CGameDStar::~CGameDStar(void)
{
	Free();
}

/*
=======================================================================
函数名       : Free
功能描述     : 
参数         : void
返回值       : NULL
=======================================================================
*/
void CGameDStar::Free(void)
{
	m_DStarWidth=m_DStarHeight=0;
	DWORD*tmp=m_DStarArray;
	m_DStarArray=NULL;
	if(tmp != NULL) delete[]tmp;
}

/*
=======================================================================
函数名       : Init
功能描述     : 
参数         : void
返回值       : NULL
=======================================================================
*/
u64 CGameDStar::Init( DWORD x, DWORD y, long dis)
{
	u64 starttick=timestamp();
	//初始化D*数组时 不考虑地图上的活动物体 争取比较高的效率
	m_DStarTarget.x=x;
	m_DStarTarget.y=y;

	long count,i;
	if(!m_Map.TestMap(m_DStarTarget.x,m_DStarTarget.y))
	{
		CString str;
		str.Format("当前点不可行走\n(%d,%d)",m_DStarTarget.x,m_DStarTarget.y);
		AfxMessageBox(str);
		return 0; //如不可到达则取消计算
	}

	//释放数据
	Free();

	//地图大小为0退出
	m_Map.GetSize(m_DStarWidth,m_DStarHeight);
	if(m_DStarWidth <= 0 || m_DStarHeight <= 0)
	{
		AfxMessageBox("地图大小错误");
		return 0;
	}

	count = m_DStarWidth * m_DStarHeight;
	m_DStarArray = new DWORD[count];
	memset(m_DStarArray,-1,count*sizeof(DWORD));

	std::vector<POINT> OpenList;
	std::vector<POINT> OpenList2;
	std::vector<POINT>::iterator pos;

	POINT current;
	DWORD g;
	OpenList.push_back(m_DStarTarget);
	m_DStarArray[m_DStarTarget.x * m_DStarHeight + m_DStarTarget.y] = 0;
	while(!OpenList.empty())
	{
		for(pos = OpenList.begin();pos != OpenList.end();pos ++)
		{
			current=*pos;
			g = m_DStarArray[current.x * m_DStarHeight + current.y] + 1;
			for(i = 0; i < 8; i ++)
			{
				current=*pos;
				for(int j = 0; j < dis; j ++)
				{
					current.x += xofs_walk[i];
					current.y += yofs_walk[i];
					if(m_Map.TestMap(current.x,current.y))
					{
						if(m_DStarArray[current.x * m_DStarHeight + current.y] > g)
						{
							m_DStarArray[current.x * m_DStarHeight + current.y] = g;
							OpenList2.push_back(current);
						}
					}
					else
						break;
				}
			}
		}
		OpenList.clear();
		OpenList.swap(OpenList2);
	}
	return timestamp()-starttick;
}

/*
=======================================================================
函数名       : GetDist
功能描述     : 
参数         : void
返回值       : NULL
=======================================================================
*/
DWORD CGameDStar::GetDist(DWORD x, DWORD y)
{
	if(m_DStarArray==NULL) return MAXDWORD; //D*还没有初始化 返回失败
	if(x>=m_DStarWidth)
		return MAXDWORD;
	if(x<0)
		return MAXDWORD; 
	if(y>=m_DStarHeight)
		return MAXDWORD;
	if(y<0)
		return MAXDWORD;
	return m_DStarArray[x * m_DStarHeight + y];
}

/*
=======================================================================
函数名       : GetPath
功能描述     : 
参数         : void
返回值       : NULL
=======================================================================
*/
//取路径
//返回TRUE 成功
BOOL CGameDStar::GetPath(const POINT& Start, std::vector<POINT>& Path)
{
	//取路径的时候需要全面考虑地图环境 以及活动物体
	if(m_DStarArray==NULL) return FALSE; //D*还没有初始化 返回失败
	if(!m_Map.TestMap(Start.x,Start.y)) return FALSE; //起始点不可达 失败 //一般这个判断都为false 考虑稳定

	//清空路径
	Path.clear();

	POINT current,search;
	long i,dir;
	DWORD g_min;
	bool isRun,Action;

	current.x = Start.x;
	current.y = Start.y;
	Path.push_back(current);
	while(true)
	{
		Action = false;
		g_min = MAXDWORD;
		if( (current.x == m_DStarTarget.x) && (current.y == m_DStarTarget.y)) //查找到了终点 路径完成 返回TRUE
		{
			return TRUE;
		}
		for(i = 0;i < 8;i ++)
		{
			//走
			//GeneratePoint(current,i,false,search);
			search.x = current.x + xofs_walk[i];
			search.y = current.y + yofs_walk[i];
			if(m_Game.CanMove(search.x,search.y))//检测NPC
			{
				if( (m_DStarArray[search.x * m_DStarHeight + search.y] < g_min) && NotInPath(search,Path) )
				{//更近 并且 还未被添加到路径
					g_min = m_DStarArray[search.x * m_DStarHeight + search.y];
					dir = i;
					isRun = false;
					Action = true;
				}
				//跑
				//GeneratePoint(current,i,true,search);
				search.x = current.x + xofs_run[i];
				search.y = current.y + yofs_run[i];
				if(m_Game.CanMove(search.x,search.y))//检测NPC
				{
					if( (m_DStarArray[search.x * m_DStarHeight + search.y] < g_min) && NotInPath(search,Path) )
					{//更近 并且 还未被添加到路径
						g_min = m_DStarArray[search.x * m_DStarHeight + search.y];
						dir = i;
						isRun = true;
						Action = true;
					}
				}
			}
		}
		if(Action)
		{
			//GeneratePoint(current,dir,isRun,current);
			if(isRun)
			{
				current.x = current.x + xofs_run[dir];
				current.y = current.y + yofs_run[dir];
			}
			else
			{
				current.x = current.x + xofs_walk[dir];
				current.y = current.y + yofs_walk[dir];
			}
			Path.push_back(current);//将点加入路径
		}
		else
		{
			break;
		}
	}

	//如果查找路径失败 清空路径
	Path.clear();

	return FALSE;
}

/*
=======================================================================
函数名       : NotInPath
功能描述     : 
参数         : void
返回值       : NULL
=======================================================================
*/
//还没有被添加到路径中
inline bool CGameDStar::NotInPath(const POINT& Point, const std::vector<POINT>& Path)
{
	return (Path.end()==std::find(Path.begin(),Path.end(),Point));
}

/*
=======================================================================
函数名       : GetTarget
功能描述     : 
参数         : void
返回值       : NULL
=======================================================================
*/
void CGameDStar::GetTarget(POINT& t)
{
	t.x = m_DStarTarget.x;
	t.y = m_DStarTarget.y;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -