最新文章專(zhuān)題視頻專(zhuān)題問(wèn)答1問(wèn)答10問(wèn)答100問(wèn)答1000問(wèn)答2000關(guān)鍵字專(zhuān)題1關(guān)鍵字專(zhuān)題50關(guān)鍵字專(zhuān)題500關(guān)鍵字專(zhuān)題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專(zhuān)題關(guān)鍵字專(zhuān)題tag2tag3文章專(zhuān)題文章專(zhuān)題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專(zhuān)題3
問(wèn)答文章1 問(wèn)答文章501 問(wèn)答文章1001 問(wèn)答文章1501 問(wèn)答文章2001 問(wèn)答文章2501 問(wèn)答文章3001 問(wèn)答文章3501 問(wèn)答文章4001 問(wèn)答文章4501 問(wèn)答文章5001 問(wèn)答文章5501 問(wèn)答文章6001 問(wèn)答文章6501 問(wèn)答文章7001 問(wèn)答文章7501 問(wèn)答文章8001 問(wèn)答文章8501 問(wèn)答文章9001 問(wèn)答文章9501
當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

cocos2dxA*算法

來(lái)源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-09 15:29:19
文檔

cocos2dxA*算法

cocos2dxA*算法:頭文件和源文件復(fù)制到項(xiàng)目中就能用了! have fun 使用cocos2dx 3.2 原理都一樣 淡藍(lán)色的點(diǎn)是地圖 深藍(lán)色的點(diǎn)是障礙物 綠色的點(diǎn)是路徑 暗綠色的點(diǎn)是搜尋過(guò)的點(diǎn) 紅色的點(diǎn)是按路徑行走的點(diǎn) dijkstra算法 會(huì)發(fā)現(xiàn)路徑最短,但尋找過(guò)的路徑比較多(計(jì)算速度慢) 最佳
推薦度:
導(dǎo)讀cocos2dxA*算法:頭文件和源文件復(fù)制到項(xiàng)目中就能用了! have fun 使用cocos2dx 3.2 原理都一樣 淡藍(lán)色的點(diǎn)是地圖 深藍(lán)色的點(diǎn)是障礙物 綠色的點(diǎn)是路徑 暗綠色的點(diǎn)是搜尋過(guò)的點(diǎn) 紅色的點(diǎn)是按路徑行走的點(diǎn) dijkstra算法 會(huì)發(fā)現(xiàn)路徑最短,但尋找過(guò)的路徑比較多(計(jì)算速度慢) 最佳

頭文件和源文件復(fù)制到項(xiàng)目中就能用了! have fun 使用cocos2dx 3.2 原理都一樣 淡藍(lán)色的點(diǎn)是地圖 深藍(lán)色的點(diǎn)是障礙物 綠色的點(diǎn)是路徑 暗綠色的點(diǎn)是搜尋過(guò)的點(diǎn) 紅色的點(diǎn)是按路徑行走的點(diǎn) dijkstra算法 會(huì)發(fā)現(xiàn)路徑最短,但尋找過(guò)的路徑比較多(計(jì)算速度慢) 最佳優(yōu)

頭文件和源文件復(fù)制到項(xiàng)目中就能用了! have fun

使用cocos2dx 3.2 原理都一樣

淡藍(lán)色的點(diǎn)是地圖

深藍(lán)色的點(diǎn)是障礙物

綠色的點(diǎn)是路徑

暗綠色的點(diǎn)是搜尋過(guò)的點(diǎn)

紅色的點(diǎn)是按路徑行走的點(diǎn)



dijkstra算法 會(huì)發(fā)現(xiàn)路徑最短,但尋找過(guò)的路徑比較多(計(jì)算速度慢)



最佳優(yōu)先搜索算法會(huì)發(fā)現(xiàn)尋找過(guò)的路徑少了(計(jì)算速度提高了),但走了許多彎路



A星算法 結(jié)合了上面2種算法 即尋找到了最短路徑, 搜尋過(guò)的路徑也比較少



#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"
#include "vector"
using namespace std;
USING_NS_CC;


class PathSprite : public cocos2d::Sprite//繼承Sprite類(lèi), 因?yàn)橐诶锩婕有┢渌兞?{
 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;//父節(jié)點(diǎn)
 PathSprite* m_child;//子節(jié)點(diǎn)
 float m_costToSource;//到起始點(diǎn)的距離
 int m_x;//地圖坐標(biāo)
 int m_y;
 float m_FValue;
};

class PathSearchInfo//尋路類(lèi)(主要負(fù)責(zé)尋路的參數(shù)和邏輯)
{
public:
 
 static int m_startX;//開(kāi)始點(diǎn)
 static int m_startY;
 static int m_endX;//結(jié)束點(diǎn)
 static int m_endY;
 
 static vector m_openList;//開(kāi)放列表(里面存放相鄰節(jié)點(diǎn))
 static vector m_inspectList;//檢測(cè)列表(里面存放除了障礙物的節(jié)點(diǎn))
 static vector m_pathList;//路徑列表
 static void barrierTest( vector &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)//計(jì)算兩個(gè)物體間的距離
 {
// float _offsetX = obj1->m_x - obj2->m_x;
// float _offsetY = obj1->m_y - obj2->m_y;
// return sqrt( _offsetX * _offsetX + _offsetY * _offsetY);
 
 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)//把相鄰的節(jié)點(diǎn)放入開(kāi)放節(jié)點(diǎn)中
 {
 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);//獲得累計(jì)的路程
 G = adjacent->m_costToSource;
 
 //三種算法, 感覺(jué)H2不錯(cuò)
 H1 = _x + _y;
 H2 = hypot(_x, _y);
 H3 = max(_x, _y);

#if 1 //A*算法 = Dijkstra算法 + 最佳優(yōu)先搜索
 F = G + H2;
#endif
#if 0//Dijkstra算法
 F = G;
#endif
#if 0//最佳優(yōu)先搜索
 F = H2;
#endif
 adjacent->m_FValue = F;
 
 adjacent->m_parent = node;//設(shè)置父節(jié)點(diǎn)
 adjacent->setColor(Color3B::ORANGE);//搜尋過(guò)的節(jié)點(diǎn)設(shè)為橘色
 node->m_child = adjacent;//設(shè)置子節(jié)點(diǎn)
 PathSearchInfo::removeObjFromList(PathSearchInfo::m_inspectList, adjacent);//把檢測(cè)過(guò)的點(diǎn)從檢測(cè)列表中刪除
 PathSearchInfo::m_openList.push_back(adjacent);//加入開(kāi)放列表
 }
 }
 static PathSprite* getMinPathFormOpenList()//從開(kāi)放節(jié)點(diǎn)中獲取路徑最小值
 {
 if (m_openList.size()>0) {
 PathSprite* _sp =* m_openList.begin();
 for (vector::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 &spriteVector, int x, int y)//根據(jù)點(diǎn)獲取對(duì)象
 {
 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 &spriteVector, PathSprite* sprite)//從容器中移除對(duì)象
 {
 for (vector::iterator iter = spriteVector.begin(); iter != spriteVector.end(); iter++)
 {
 if (*iter == sprite)
 {
 spriteVector.erase(iter);
 return true;
 }
 }
 return false;
 
 }
};

class HelloWorld : public cocos2d::Layer
{
public:
 // there's no 'id' in cpp, so we recommend returning the class instance pointer
 static cocos2d::Scene* createScene();
 
 // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
 virtual bool init(); 
 
 // a selector callback
 void menuCloseCallback(cocos2d::Ref* pSender);
 
 // implement the "static create()" method manually
 CREATE_FUNC(HelloWorld);
 
 bool onTouchBegan(Touch* touch, Event* event);
 void onTouchMoved(Touch* touch, Event* event);
 void onTouchEnded(Touch* touch, Event* event);
 
 void calculatePath();//計(jì)算路徑
 void drawPath();//繪制路徑
 vector m_mapList;//地圖
 
 void clearPath();//清理路徑
 
 PathSprite* m_player;//人物 用于演示行走
 int m_playerMoveStep;//人物當(dāng)前的行程
 void playerMove();//人物走動(dòng)
};

#endif // __HELLOWORLD_SCENE_H__
#include "HelloWorldScene.h"

vector PathSearchInfo::m_openList;

vector PathSearchInfo::m_inspectList;

vector PathSearchInfo::m_pathList;

int PathSearchInfo::m_startX;

int PathSearchInfo::m_startY;

int PathSearchInfo::m_endX;

int PathSearchInfo::m_endY;

Scene* HelloWorld::createScene()
{
 // 'scene' is an autorelease object
 auto scene = Scene::create();
 
 // 'layer' is an autorelease object
 auto layer = HelloWorld::create();
 
 // add layer as a child to scene
 scene->addChild(layer);
 
 // return the scene
 return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
 //////////////////////////////
 // 1. super init first
 if ( !Layer::init() )
 {
 return false;
 }
 
 Size visibleSize = Director::getInstance()->getVisibleSize();
 Vec2 origin = Director::getInstance()->getVisibleOrigin();
 Size winSize = Director::getInstance()->getWinSize();
 
 /////////////////////////////
 // 2. add a menu item with "X" image, which is clicked to quit the program
 // you may modify it.
 
 // add a "close" icon to exit the progress. it's an autorelease object
 
 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);
 
 
 
 //模擬一張地圖 左上角 為(0,0) 主要是模擬tiledmap 每塊的寬度為1
 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);
 }
 }
 
 //設(shè)置障礙物
// for (int i = 0; i < _heigth*_width/2; i++)
// {
// 
// int _x = CCRANDOM_0_1()*_width;
// int _y = CCRANDOM_0_1()*_heigth;
// if (_x ==0 && _y == 0) {
// continue;
// }
// PathSearchInfo::barrierTest(m_mapList,_x,_y);
// }
 for (int i = 0; i < 10; i++) {
 PathSearchInfo::barrierTest(m_mapList,5+i,10);
 PathSearchInfo::barrierTest(m_mapList,15,i+1);
 }
 
 //PathSprite::getObjByPointOfMapCoord(m_inspectList, 2, 5)->removeFromParent();
 
 //設(shè)置起始和終點(diǎn)
 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()
{
 
 //得到開(kāi)始點(diǎn)的節(jié)點(diǎn)
 PathSprite* _sp = PathSearchInfo::getObjByPointOfMapCoord(PathSearchInfo::m_inspectList, PathSearchInfo::m_startX, PathSearchInfo::m_startY);
 //得到開(kāi)始點(diǎn)的節(jié)點(diǎn)
 PathSprite* _endNode = PathSearchInfo::getObjByPointOfMapCoord(PathSearchInfo::m_inspectList, PathSearchInfo::m_endX, PathSearchInfo::m_endY);
 //因?yàn)槭情_(kāi)始點(diǎn) 把到起始點(diǎn)的距離設(shè)為0
 _sp->m_costToSource = 0;
 _sp->m_FValue = 0;
 //把已經(jīng)檢測(cè)過(guò)的點(diǎn)從檢測(cè)列表中刪除
 PathSearchInfo::removeObjFromList(PathSearchInfo::m_inspectList, _sp);
 //然后加入開(kāi)放列表
 PathSearchInfo::m_openList.push_back(_sp);
 
 PathSprite* _node = NULL;
 while (true)
 {
 //得到離起始點(diǎn)最近的點(diǎn)
 _node = PathSearchInfo::getMinPathFormOpenList();
 if (!_node)
 {
 //找不到路徑
 break;
 }
 //把計(jì)算過(guò)的點(diǎn)從開(kāi)放列表中刪除
 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;
 }
 
 //檢測(cè)8個(gè)方向的相鄰節(jié)點(diǎn)是否可以放入開(kāi)放列表中
 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)
 {
 //PathSprite* _sp = node;
 PathSearchInfo::m_pathList.insert(PathSearchInfo::m_pathList.begin(), _node);
 _node = _node->m_parent;
 }
}


void HelloWorld::drawPath( )
{
 for (vector::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))
 {
 //獲取觸摸點(diǎn), 設(shè)置為終點(diǎn)
 PathSearchInfo::m_endX = _sp->m_x;
 PathSearchInfo::m_endY = _sp->m_y;
 //計(jì)算路徑
 calculatePath();
 //繪制路徑
 drawPath( );
 playerMove();
 
 }
 
 }
 return true;
}

void HelloWorld::onTouchMoved(Touch* touch, Event* event)
{
 // If it weren't for the TouchDispatcher, you would need to keep a reference
 // to the touch from touchBegan and check that the current touch is the same
 // as that one.
 // Actually, it would be even more complicated since in the Cocos dispatcher
 // you get Sets instead of 1 UITouch, so you'd need to loop through the set
 // in each touchXXX method.
 
}
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::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;
 }
 
 //把移除了障礙物的地圖放入檢測(cè)列表中
 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));
 
}


聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

cocos2dxA*算法

cocos2dxA*算法:頭文件和源文件復(fù)制到項(xiàng)目中就能用了! have fun 使用cocos2dx 3.2 原理都一樣 淡藍(lán)色的點(diǎn)是地圖 深藍(lán)色的點(diǎn)是障礙物 綠色的點(diǎn)是路徑 暗綠色的點(diǎn)是搜尋過(guò)的點(diǎn) 紅色的點(diǎn)是按路徑行走的點(diǎn) dijkstra算法 會(huì)發(fā)現(xiàn)路徑最短,但尋找過(guò)的路徑比較多(計(jì)算速度慢) 最佳
推薦度:
標(biāo)簽: 復(fù)制 文件 就能
  • 熱門(mén)焦點(diǎn)

最新推薦

猜你喜歡

熱門(mén)推薦

專(zhuān)題
Top