头文件和源文件复制到项目中就能用了! have fun
使用cocos2dx 3.2 原理都一样
淡蓝色的点是地图
深蓝色的点是障碍物
绿色的点是路径
暗绿色的点是搜寻过的点
红色的点是按路径行走的点
dijkstra算法 会发现路径最短,但寻找过的路径比较多(计算速度慢)

最佳优先搜索算法会发现寻找过的路径少了(计算速度提高了),但走了许多弯路

A星算法 结合了上面2种算法 即寻找到了最短路径, 搜寻过的路径也比较少

- #ifndef __HELLOWORLD_SCENE_H__
- #define __HELLOWORLD_SCENE_H__
-
- #include "cocos2d.h"
- #include "vector"
- using namespace std;
- USING_NS_CC;
-
-
- class PathSprite : public cocos2d::Sprite
- {
- PathSprite():Sprite()
- {
- m_parent = NULL;
- m_child = NULL;
- m_costToSource = 0;
- m_FValue = 0;
- };
- public:
- static PathSprite* create(const char* ch)
- {
- PathSprite *pRet = new PathSprite();
- if (pRet )
- {
- pRet->initWithFile(ch);
- pRet->autorelease();
- return pRet;
- }
- else
- {
- delete pRet;
- pRet = NULL;
- return NULL;
- }
- }
- PathSprite* m_parent;
- PathSprite* m_child;
- float m_costToSource;
- int m_x;
- int m_y;
- float m_FValue;
- };
-
- class PathSearchInfo
- {
- public:
-
- static int m_startX;
- static int m_startY;
- static int m_endX;
- static int m_endY;
-
- static vector<PathSprite*> m_openList;
- static vector<PathSprite*> m_inspectList;
- static vector<PathSprite*> m_pathList;
- static void barrierTest( vector<PathSprite*> &pathList,int x, int y)
- {
- PathSprite* _z = getObjByPointOfMapCoord(pathList, x, y);
- if (_z)
- {
- _z->setColor(ccColor3B::MAGENTA);
- removeObjFromList(pathList, _z);
- }
- }
- static float calculateTwoObjDistance(PathSprite* obj1, PathSprite* obj2)
- {
-
- float _x = abs(obj2->m_x - obj1->m_x);
- float _y = abs(obj2->m_y - obj1->m_y);
-
- return _x + _y;
- }
- static void inspectTheAdjacentNodes(PathSprite* node, PathSprite* adjacent, PathSprite* endNode)
- {
- if (adjacent)
- {
- float _x = abs(endNode->m_x - adjacent->m_x);
- float _y = abs(endNode->m_y - adjacent->m_y);
-
- float F , G, H1, H2, H3;
- adjacent->m_costToSource = node->m_costToSource + calculateTwoObjDistance(node, adjacent);
- G = adjacent->m_costToSource;
-
-
- H1 = _x + _y;
- H2 = hypot(_x, _y);
- H3 = max(_x, _y);
-
- #if 1 //A*算法 = Dijkstra算法 + 最佳优先搜索
- F = G + H2;
- #endif
- #if 0//Dijkstra算法
- F = G;
- #endif
- #if 0//最佳优先搜索
- F = H2;
- #endif
- adjacent->m_FValue = F;
-
- adjacent->m_parent = node;
- adjacent->setColor(Color3B::ORANGE);
- node->m_child = adjacent;
- PathSearchInfo::removeObjFromList(PathSearchInfo::m_inspectList, adjacent);
- PathSearchInfo::m_openList.push_back(adjacent);
- }
- }
- static PathSprite* getMinPathFormOpenList()
- {
- if (m_openList.size()>0) {
- PathSprite* _sp =* m_openList.begin();
- for (vector<PathSprite*>::iterator iter = m_openList.begin(); iter != m_openList.end(); iter++)
- {
- if ((*iter)->m_FValue < _sp->m_FValue)
- {
- _sp = *iter;
- }
- }
- return _sp;
- }
- else
- {
- return NULL;
- }
-
- }
- static PathSprite* getObjByPointOfMapCoord( vector<PathSprite*> &spriteVector, int x, int y)
- {
- for (int i = 0; i < spriteVector.size(); i++)
- {
- if (spriteVector[i]->m_x == x && spriteVector[i]->m_y == y)
- {
- return spriteVector[i];
- }
- }
- return NULL;
- }
- static bool removeObjFromList(vector<PathSprite*> &spriteVector, PathSprite* sprite)
- {
- for (vector<PathSprite*>::iterator iter = spriteVector.begin(); iter != spriteVector.end(); iter++)
- {
- if (*iter == sprite)
- {
- spriteVector.erase(iter);
- return true;
- }
- }
- return false;
-
- }
- };
-
- class HelloWorld : public cocos2d::Layer
- {
- public:
-
- static cocos2d::Scene* createScene();
-
-
- virtual bool init();
-
-
- void menuCloseCallback(cocos2d::Ref* pSender);
-
-
- CREATE_FUNC(HelloWorld);
-
- bool onTouchBegan(Touch* touch, Event* event);
- void onTouchMoved(Touch* touch, Event* event);
- void onTouchEnded(Touch* touch, Event* event);
-
- void calculatePath();
- void drawPath();
- vector<PathSprite*> m_mapList;
-
- void clearPath();
-
- PathSprite* m_player;
- int m_playerMoveStep;
- void playerMove();
- };
-
- #endif // __HELLOWORLD_SCENE_H__
- #include "HelloWorldScene.h"
-
- vector<PathSprite*> PathSearchInfo::m_openList;
-
- vector<PathSprite*> PathSearchInfo::m_inspectList;
-
- vector<PathSprite*> PathSearchInfo::m_pathList;
-
- int PathSearchInfo::m_startX;
-
- int PathSearchInfo::m_startY;
-
- int PathSearchInfo::m_endX;
-
- int PathSearchInfo::m_endY;
-
- Scene* HelloWorld::createScene()
- {
-
- auto scene = Scene::create();
-
-
- auto layer = HelloWorld::create();
-
-
- scene->addChild(layer);
-
-
- return scene;
- }
-
- bool HelloWorld::init()
- {
-
-
- if ( !Layer::init() )
- {
- return false;
- }
-
- Size visibleSize = Director::getInstance()->getVisibleSize();
- Vec2 origin = Director::getInstance()->getVisibleOrigin();
- Size winSize = Director::getInstance()->getWinSize();
-
-
-
-
-
-
-
- auto listener = EventListenerTouchOneByOne::create();
- listener->setSwallowTouches(true);
-
- listener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);
- listener->onTouchMoved = CC_CALLBACK_2(HelloWorld::onTouchMoved, this);
- listener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this);
-
- _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
-
-
-
-
- int _width = 25;
- int _heigth = 15;
- for (int i = 0; i < _heigth; i++)
- {
- for (int j = 0; j < _width; j++)
- {
- PathSprite* _sp = PathSprite::create("CloseNormal.png");
- _sp->m_x = j;
- _sp->m_y = i;
- Size _size = _sp->getContentSize();
- _sp->setPosition(CCPoint(j * _size.width + 100, - i * _size.height + 600));
- m_mapList.push_back(_sp);
- this->addChild(_sp);
- }
- }
-
-
- for (int i = 0; i < 10; i++) {
- PathSearchInfo::barrierTest(m_mapList,5+i,10);
- PathSearchInfo::barrierTest(m_mapList,15,i+1);
- }
-
-
-
-
- PathSearchInfo::m_startX =0;
- PathSearchInfo::m_startY = 0;
-
- PathSearchInfo::m_endX = 4;
- PathSearchInfo::m_endY = 9;
-
- m_player = PathSprite::create("CloseSelected1.png");
- m_player->setColor(Color3B::RED);
- this->addChild(m_player);
-
- m_player->m_x = PathSearchInfo::m_startX;
- m_player->m_y = PathSearchInfo::m_startY;
- m_player->setPosition(PathSearchInfo::getObjByPointOfMapCoord(m_mapList, PathSearchInfo::m_startX, PathSearchInfo::m_startY)->getPosition());
- return true;
- }
-
- void HelloWorld::calculatePath()
- {
-
-
- PathSprite* _sp = PathSearchInfo::getObjByPointOfMapCoord(PathSearchInfo::m_inspectList, PathSearchInfo::m_startX, PathSearchInfo::m_startY);
-
- PathSprite* _endNode = PathSearchInfo::getObjByPointOfMapCoord(PathSearchInfo::m_inspectList, PathSearchInfo::m_endX, PathSearchInfo::m_endY);
-
- _sp->m_costToSource = 0;
- _sp->m_FValue = 0;
-
- PathSearchInfo::removeObjFromList(PathSearchInfo::m_inspectList, _sp);
-
- PathSearchInfo::m_openList.push_back(_sp);
-
- PathSprite* _node = NULL;
- while (true)
- {
-
- _node = PathSearchInfo::getMinPathFormOpenList();
- if (!_node)
- {
-
- break;
- }
-
- PathSearchInfo::removeObjFromList(PathSearchInfo::m_openList, _node);
- int _x = _node->m_x;
- int _y = _node->m_y;
-
-
- if (_x ==PathSearchInfo::m_endX && _y == PathSearchInfo::m_endY)
- {
- break;
- }
-
-
- PathSprite* _adjacent = PathSearchInfo::getObjByPointOfMapCoord(PathSearchInfo::m_inspectList, _x + 1, _y + 1);
- PathSearchInfo::inspectTheAdjacentNodes(_node, _adjacent, _endNode);
-
- _adjacent = PathSearchInfo::getObjByPointOfMapCoord(PathSearchInfo::m_inspectList, _x +1, _y);
- PathSearchInfo::inspectTheAdjacentNodes(_node, _adjacent, _endNode);
-
- _adjacent = PathSearchInfo::getObjByPointOfMapCoord(PathSearchInfo::m_inspectList, _x +1, _y-1);
- PathSearchInfo::inspectTheAdjacentNodes(_node, _adjacent, _endNode);
-
- _adjacent = PathSearchInfo::getObjByPointOfMapCoord(PathSearchInfo::m_inspectList, _x , _y -1);
- PathSearchInfo::inspectTheAdjacentNodes(_node, _adjacent, _endNode);
-
- _adjacent = PathSearchInfo::getObjByPointOfMapCoord(PathSearchInfo::m_inspectList, _x -1, _y - 1);
- PathSearchInfo::inspectTheAdjacentNodes(_node, _adjacent, _endNode);
-
- _adjacent = PathSearchInfo::getObjByPointOfMapCoord(PathSearchInfo::m_inspectList, _x -1, _y);
- PathSearchInfo::inspectTheAdjacentNodes(_node, _adjacent, _endNode);
-
- _adjacent = PathSearchInfo::getObjByPointOfMapCoord(PathSearchInfo::m_inspectList, _x -1, _y+1);
- PathSearchInfo::inspectTheAdjacentNodes(_node, _adjacent, _endNode);
-
- _adjacent = PathSearchInfo::getObjByPointOfMapCoord(PathSearchInfo::m_inspectList, _x , _y+1);
- PathSearchInfo::inspectTheAdjacentNodes(_node, _adjacent, _endNode);
-
- }
-
- while (_node)
- {
-
- PathSearchInfo::m_pathList.insert(PathSearchInfo::m_pathList.begin(), _node);
- _node = _node->m_parent;
- }
- }
-
-
- void HelloWorld::drawPath( )
- {
- for (vector<PathSprite*>::iterator iter = PathSearchInfo::m_pathList.begin(); iter != PathSearchInfo::m_pathList.end(); iter++)
- {
- (*iter)->setColor(ccColor3B::GREEN);
- }
-
- }
-
-
- bool HelloWorld::onTouchBegan(Touch* touch, Event* event)
- {
-
- clearPath();
-
- auto nodePosition = convertToNodeSpace( touch->getLocation() );
- log("%f, %f", nodePosition.x, nodePosition.y);
- for (int i = 0; i < PathSearchInfo::m_inspectList.size(); i++)
- {
- PathSprite* _sp = PathSearchInfo::m_inspectList[i];
-
- if (_sp->getBoundingBox().containsPoint(nodePosition))
- {
-
- PathSearchInfo::m_endX = _sp->m_x;
- PathSearchInfo::m_endY = _sp->m_y;
-
- calculatePath();
-
- drawPath( );
- playerMove();
-
- }
-
- }
- return true;
- }
-
- void HelloWorld::onTouchMoved(Touch* touch, Event* event)
- {
-
-
-
-
-
-
-
- }
- void HelloWorld::onTouchEnded(Touch* touch, Event* event)
- {
-
- }
-
-
- void HelloWorld::menuCloseCallback(Ref* pSender)
- {
- #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
- MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
- return;
- #endif
-
- Director::getInstance()->end();
-
- #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
- exit(0);
- #endif
- }
-
- void HelloWorld::clearPath()
- {
- for (vector<PathSprite*>::iterator iter = m_mapList.begin(); iter != m_mapList.end(); iter++)
- {
- (*iter)->setColor(ccColor3B::WHITE);
- (*iter)->m_costToSource = 0;
- (*iter)->m_FValue = 0;
- (*iter)->m_parent = NULL;
- (*iter)->m_child = NULL;
- }
-
-
- PathSearchInfo::m_inspectList = m_mapList;
- PathSearchInfo::m_openList.clear();
- PathSearchInfo::m_pathList.clear();
-
- PathSearchInfo::m_startX = m_player->m_x;
- PathSearchInfo::m_startY = m_player->m_y;
- m_player->stopAllActions();
-
- m_playerMoveStep = 0;
- }
-
- void HelloWorld::playerMove()
- {
- m_playerMoveStep++;
-
- if (m_playerMoveStep >= PathSearchInfo::m_pathList.size()) {
- return;
- }
-
- m_player->m_x = PathSearchInfo::m_pathList[m_playerMoveStep]->m_x;
- m_player->m_y = PathSearchInfo::m_pathList[m_playerMoveStep]->m_y;
-
- m_player->runAction(Sequence::create(MoveTo::create(0.2, PathSearchInfo::m_pathList[m_playerMoveStep]->getPosition()), CallFunc::create(this, SEL_CallFunc(&HelloWorld::playerMove)) , NULL));
-
- }
cocos2dx A*算法
原文:http://www.cnblogs.com/liuzhi/p/4036287.html