cocos2dx 45度Staggered格式A*寻路 曼哈顿算法(待优化)

前端之家收集整理的这篇文章主要介绍了cocos2dx 45度Staggered格式A*寻路 曼哈顿算法(待优化)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

cocos2dx 45度Staggered格式A*寻路 曼哈顿算法(待优化)


转自:http://blog.csdn.net/hpking/article/details/9775289


#ifndef__ASTARPATHFINDER_H__
  1. #define__ASTARPATHFINDER_H__
  2.  
  3. #include"cocos2d.h"
  4.  
  5. USING_NS_CC;
  6.  
  7. /**
  8. *横向移动一格的路径评分
  9. */
  10. staticconstintCOST_HORIZONTAL=20;
  11.  
  12. /**
  13. *竖向移动一格的路径评分
  14. */
  15. staticconstintCOST_VERTICAL=5;
  16.  
  17. /**
  18. *斜向移动一格的路径评分
  19. */
  20. staticconstintCOST_DIAGONAL=12;
  21.  
  22. classPathInfo;
  23.  
  24. /**
  25. *A星寻路类
  26. *@authorhpking
  27. *
  28. */
  29. classAStarPathFinder
  30. {
  31. 	//未探索的节点列表
  32. cocos2d::CCArray*_openSteps;
  33. 	//已探索的,不需要再寻路的节点列表
  34. CCArray*_closedSteps;
  35.  
  36. 	//地图相关数据
  37. 	PathInfo*_pathInfo;
  38.  
  39. public:
  40. 	AStarPathFinder(PathInfo*info);
  41. 	virtual~AStarPathFinder();
  42.  
  43. /**
  44. *public寻路
  45. *
  46. *@paramCCPointstartPointtile开始坐标点
  47. *@paramCCPointendPointtile结束坐标点
  48. *@returnCCArray*读取方法:CCPointFromString(string->getCString())
  49. */
  50. CCArray*find(CCPointstartTilePt,CCPointendTilePt);
  51.  
  52. private:
  53. 	//最短路径步数
  54. 	classShortestPathStep:publicCCObject
  55. 	{
  56. 	public:
  57. 		boolinitWithPosition(CCPointpos)
  58. 		{
  59. 			boolbRet=false;
  60.  
  61. 			do
  62. 			{
  63. 				position=pos;
  64. 				gscore=0;
  65. 				hscore=0;
  66. 				parent=NULL;
  67. 				inOpen=false;
  68. 				inClose=false;
  69.  
  70. 				bRet=true;
  71. 			}
  72. 			while(0);
  73.  
  74. 			returnbRet;
  75. 		}
  76.  
  77. 		intfscore()
  78. 		{
  79. 			returnthis->getGscore()+this->getHscore();
  80. 		}
  81.  
  82. 		inlinebooloperator==(constShortestPathStep*other)
  83. 		{
  84. 			returnisEqual(other);
  85. 		}
  86.  
  87. 		boolisEqual(constShortestPathStep*other)
  88. 		{
  89. 			returnthis->getPosition().equals(other->getPosition());
  90. 		}
  91.  
  92. 		staticShortestPathStep*inst(CCPointpos)
  93. 		{
  94. 			AStarPathFinder::ShortestPathStep*sps=newShortestPathStep;
  95.  
  96. 			if(sps&&sps->initWithPosition(pos))
  97. 			{
  98. 				sps->autorelease();
  99. 				returnsps;
  100. 			}
  101.  
  102. 			CC_SAFE_DELETE(sps);
  103. 			returnNULL;
  104. 		}
  105.  
  106. 		CC_SYNTHESIZE(CCPoint,position,Position);
  107. 		CC_SYNTHESIZE(int,gscore,Gscore);
  108. 		hscore,Hscore);
  109. 		ShortestPathStep*,parent,Parent);
  110. 		CC_SYNTHESIZE(bool,inOpen,InOpen);
  111. 		inClose,InClose);
  112.  
  113. 	private:
  114. 		CCString*description()
  115. 		{
  116. 			returnCCString::createWithFormat("pos=[%f,%f],g=%d,h=%d,f=%d",this->getPosition().x,0)">getPosition().y,0)">getGscore(),0)">getHscore(),0)">fscore());
  117. 		}
  118. 	};
  119.  
  120. private:
  121. voiddestroyLists();
  122.  
  123. createPath(ShortestPathStep*step);//intxStart,intyStart
  124. 	voidfindAndSort(ShortestPathStep*step);
  125.  
  126. 	voidinsertAndSort(ShortestPathStep*step);
  127.  
  128. /**
  129. *private判断是否超出边界或路点是否可走
  130. *
  131. *@paramCCPointtpt
  132. *@returnbool
  133. */
  134. boolisWalkable(CCPointtpt);
  135.  
  136. /**
  137. *private计算G值
  138. *
  139. *@paramNode*curNode
  140. *@paramNode*node
  141. *@returnint
  142. */
  143. intgetGValue(ShortestPathStep*curStep,133)">ShortestPathStep*step);
  144.  
  145. /**
  146. *private计算H值
  147. *
  148. *@paramNode*curNode
  149. *@paramNode*endNode
  150. *@paramNode*node
  151. *@returnint
  152. */
  153. intgetHValue(ShortestPathStep*endStep,133)">ShortestPathStep*step);
  154.  
  155. getAroundsNode(CCPointtPt);
  156.  
  157. 	boolisInClosed(CCPointtPt);
  158.  
  159. voidsetOpenSteps(CCArray*var);
  160. voidsetClosedSteps(setShortestPath(CCArray*var);
  161. };
  162.  
  163. #endif

  1.  
  1. #include"AStarPathFinder.h"
  2. #include"map/PathInfo.h"
  3.  
  4. PathInfo*info)
  5. {
  6. _pathInfo=info;
  7. _openSteps=NULL;
  8. _closedSteps=NULL;
  9. }
  10.  
  11. AStarPathFinder::~AStarPathFinder()
  12. {
  13. destroyLists();
  14. }
  15.  
  16. //获取毫秒时间
  17. longmsNow()
  18. {
  19. 	structcc_timevalnow;
  20. 	CCTime::gettimeofdayCocos2d(&now,NULL);
  21. 	return(now.tv_sec*1000+now.tv_usec/1000);
  22. }
  23.  
  24. CCArray*AStarPathFinder::CCPointendTilePt)
  25. {
  26. boolisFinded=false;//能否找到路径,true-已找到
  27.  
  28. //到达终点
  29. if(startTilePt.equals(endTilePt))
  30. {
  31. CCLog("You'realreadythere!:P");
  32. returnNULL;
  33. }
  34.  
  35. //终点不可走,直接退出(可优化为最近的可走地点停止)
  36. if(!isWalkable(endTilePt))
  37. {
  38. "blocked!:P");
  39. returnNULL;
  40. }
  41.  
  42. //设置打开和封闭步数
  43. CCArray::create());
  44. create());
  45.  
  46. //CCLog("From:(%f,%f)To(%f,%f)",startTilePt.x,startTilePt.y,endTilePt.x,endTilePt.y);
  47.  
  48. //结束坐标
  49. ShortestPathStep*endStep=ShortestPathStep::inst(endTilePt);
  50.  
  51. //插入开始点
  52. inst(startTilePt));
  53.  
  54. ShortestPathStep*curStep;
  55. longtime1=msNow();
  56.  
  57. do
  58. {
  59. //取出并删除开放列表第一个元素
  60. curStep=(ShortestPathStep*)_openSteps->objectAtIndex(0);
  61. curStep->setInClose(true);
  62. curStep->setInOpen(false);
  63. _closedSteps->addObject(curStep);
  64. _openSteps->removeObjectAtIndex(0);
  65.  
  66. //当前节点==目标节点
  67. if(curStep->equals(endTilePt))
  68. {
  69. isFinded=true;//能达到终点,找到路径
  70. break;
  71. }
  72.  
  73. //取相邻八个方向的节点,去除不可通过和已在关闭列表中的节点
  74. CCArray*aroundNodes=getAroundsNode(curStep->getPosition());
  75. //CCLog("8dirc%d",aroundNodes->count());
  76. CCObject*obj;
  77. CCARRAY_FOREACH(aroundNodes,obj)
  78. {
  79. //计算G,H值
  80. CCString*string=(CCString*)obj;
  81. ShortestPathStep*nextStep=newShortestPathStep;
  82. nextStep->initWithPosition(CCPointFromString(string->getCString()));
  83.  
  84. intg=getGValue(curStep,nextStep);
  85. inth=getHValue(curStep,endStep,nextStep);
  86.  
  87. if(nextStep->getInOpen())//如果节点已在播放列表中
  88. {
  89. //如果该节点新的G值比原来的G值小,修改F,G值,设置该节点的父节点为当前节点
  90. if(g<nextStep->getGscore())
  91. {
  92. nextStep->setGscore(g);
  93. nextStep->setHscore(h);
  94. nextStep->setParent(curStep);
  95. findAndSort(nextStep);
  96. nextStep->release();
  97. }
  98. }
  99. else//如果节点不在开放列表中
  100. {
  101. //插入开放列表中,并按照估价值排序
  102. nextStep->setParent(curStep);
  103.  
  104. insertAndSort(nextStep);
  105. nextStep->release();
  106. }
  107.  
  108. //CCLog("opennum:%d",_openSteps->count());
  109. }
  110. }
  111. while(_openSteps->count()>0);
  112.  
  113. "a*time:%d",0)">msNow()-time1);
  114.  
  115. /*if(_openSteps)
  116. CCLog("finded:%d,openlen%d,closelen%d",isFinded?1:0,_openSteps->count(),_closedSteps->count());*/
  117.  
  118. //找到路径
  119. if(isFinded)
  120. {
  121. CCArray*path=createPath(curStep);
  122.  
  123. destroyLists();
  124.  
  125. returnpath;
  126. }
  127. else//没有找到路径
  128. {
  129. destroyLists();
  130.  
  131. returnNULL;
  132. }
  133. }
  134.  
  135. voiddestroyLists()
  136. {
  137. CC_SAFE_RELEASE_NULL(_openSteps);
  138. CC_SAFE_RELEASE_NULL(_closedSteps);
  139. }
  140.  
  141. ShortestPathStep*step)//intxStart,intyStart
  142. {
  143. CCArray*path=create();
  144.  
  145. CCString*str;
  146.  
  147. do
  148. {
  149. if(step->getParent()!=NULL)
  150. {
  151. str="{%f,%f}",step->getPosition().y);
  152. path->insertObject(str,0);
  153. }
  154.  
  155. step=step->getParent();
  156. }
  157. while(step!=NULL);
  158.  
  159. returnpath;
  160. }
  161.  
  162. voidShortestPathStep*step)
  163. {
  164. unsignedintcount=_openSteps->count();
  165.  
  166. if(count<1)
  167. return;
  168.  
  169. intstepFscore=step->fscore();
  170.  
  171. for(unsignedinti=0;i<count;i++)
  172. {
  173. ShortestPathStep*sps=(objectAtIndex(i);
  174.  
  175. if(stepFscore<=sps->fscore())
  176. _openSteps->insertObject(step,i);
  177.  
  178. if(step->equals(sps->getPosition()))
  179. _openSteps->removeObjectAtIndex(i);
  180. }
  181. }
  182.  
  183. voidShortestPathStep*step)
  184. {
  185. step->setInOpen(true);
  186.  
  187. intstepFscore=step->fscore();
  188. unsignedintcount=_openSteps->count();
  189.  
  190. if(count==0)
  191. _openSteps->addObject(step);
  192. else
  193. {
  194. for(unsignedinti=0;i<count;i++)
  195. {
  196. fscore())
  197. {
  198. _openSteps->i);
  199. return;
  200. }
  201. }
  202. }
  203. }
  204.  
  205. boolCCPointtPt)
  206. {
  207. //1.是否是有效的地图上点(数组边界检查)
  208. if(tPt.x<_pathInfo->startPt.x||tPt.x>=_pathInfo->iCol)
  209. returnfalse;
  210.  
  211. if(tPt.y<_pathInfo->startPt.y||tPt.y>=_pathInfo->iRow)
  212. returnfalse;
  213.  
  214. //2.是否是walkable
  215. return_pathInfo->isWalkable(tPt);
  216. }
  217.  
  218.  
  219. /**
  220. *private计算G值
  221. *
  222. *@paramShortestPathStep*curStep
  223. *@paramShortestPathStep*step
  224. *@returnint
  225. */
  226. intShortestPathStep*step)
  227. {
  228. intg=0;
  229.  
  230. if(curStep->getPosition().y==step->getPosition().y)//横向左右
  231. {
  232. g=curStep->getGscore()+COST_HORIZONTAL;
  233. }
  234. elseif(curStep->getPosition().y+2==step->getPosition().y||curStep->getPosition().y-2==step->getPosition().y)//竖向上下
  235. {
  236. g=curStep->getGscore()+COST_VERTICAL*2;
  237. }
  238. else//斜向左上左下右上右下
  239. {
  240. g=curStep->getGscore()+COST_DIAGONAL;
  241. }
  242.  
  243. returng;
  244. }
  245.  
  246. /**
  247. *private计算H值
  248. *
  249. *@paramShortestPathStep*curStep
  250. *@paramShortestPathStep*endStep
  251. *@paramShortestPathStep*step
  252. *@returnint
  253. */
  254. intShortestPathStep*step)
  255. {
  256. if(curStep==NULL||endStep==NULL||step==NULL)
  257. return0;
  258.  
  259. //节点到0,0点的x轴距离
  260. intto0=step->getPosition().x*COST_HORIZONTAL+((int)step->getPosition().y&1)*COST_HORIZONTAL/2;
  261.  
  262. //终止节点到0,0点的x轴距离
  263. intendTo0=endStep->getPosition().x*COST_HORIZONTAL+((int)endStep->getPosition().y&1)*COST_HORIZONTAL/2;
  264.  
  265. returnabs((float)endTo0-(float)to0)+abs((float)endStep->getPosition().y-(float)step->getPosition().y)*COST_VERTICAL;
  266. }
  267.  
  268. CCPointtPt)
  269. {
  270. CCArray*aroundNodes=create();
  271.  
  272. ///菱形组合的地图八方向与正常不同
  273.  
  274. //左
  275. CCPointp=CCPointMake(tPt.x-1,tPt.y);
  276. CCString*str;
  277.  
  278. if(isWalkable(p)&&!isInClosed(p))//可走并且不在关闭列表
  279. {
  280. str=p.x,p.y);
  281. //CCLOG("left=%s",str->getCString());
  282. aroundNodes->addObject(str);
  283. }
  284.  
  285. //右
  286. p=CCPointMake(tPt.x+1,tPt.y);
  287.  
  288. if(isInClosed(p))
  289. {
  290. str=p.y);
  291. //CCLOG("right=%s",0)">addObject(str);
  292. }
  293.  
  294. //上
  295. p=CCPointMake(tPt.x,tPt.y-2);//-2
  296.  
  297. if(p.y);
  298. //CCLOG("up=%s",0)">addObject(str);
  299. }
  300.  
  301. //下
  302. p=tPt.y+2);//+2
  303.  
  304. if(p.y);
  305. //CCLOG("down=%s",0)">addObject(str);
  306. }
  307.  
  308. //左上
  309. p=CCPointMake(tPt.x-1+((int)tPt.y&1),tPt.y-1);
  310.  
  311. if(p.y);
  312. //CCLOG("leftUp=%s",0)">addObject(str);
  313. }
  314.  
  315. //左下
  316. p=tPt.y+1);
  317.  
  318. if(p.y);
  319. //CCLOG("leftDown=%s",0)">addObject(str);
  320. }
  321.  
  322. //右上
  323. p=CCPointMake(tPt.x+((int)tPt.y&1),p.y);
  324. //CCLOG("rightUp=%s",0)">addObject(str);
  325. }
  326.  
  327. //右下
  328. p=p.y);
  329. //CCLOG("rightDown=%s",0)">addObject(str);
  330. }
  331.  
  332. returnaroundNodes;
  333. }
  334.  
  335. boolCCPointpt)
  336. {
  337. CCObject*temp;
  338. CCARRAY_FOREACH(_closedSteps,temp)
  339. {
  340. ShortestPathStep*)temp;
  341.  
  342. if(sps->equals(pt))
  343. {
  344. returntrue;
  345. }
  346. }
  347.  
  348. returnfalse;
  349. }
  350.  
  351. voidCCArray*var)
  352. {
  353. if(_openSteps!=var)
  354. {
  355. CC_SAFE_RETAIN(var);
  356. _openSteps=var;
  357. }
  358. }
  359.  
  360. voidCCArray*var)
  361. {
  362. if(_closedSteps!=var)
  363. {
  364. CC_SAFE_RELEASE_NULL(_closedSteps);
  365. CC_SAFE_RETAIN(var);
  366. _closedSteps=var;
  367. }
  368. }
  369.  
  370. voidCCArray*var)
  371. {
  372. /*if(shortestPath!=var)
  373. {
  374. CC_SAFE_RELEASE_NULL(shortestPath);
  375. CC_SAFE_RETAIN(var);
  376. shortestPath=var;
  377. }*/
  378. }

猜你在找的Cocos2d-x相关文章