国产99久久精品_欧美日本韩国一区二区_激情小说综合网_欧美一级二级视频_午夜av电影_日本久久精品视频

最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題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關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當前位置: 首頁 - 科技 - 知識百科 - 正文

cocos2dxA*算法

來源:懂視網 責編:小采 時間:2020-11-09 15:29:19
文檔

cocos2dxA*算法

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

頭文件和源文件復制到項目中就能用了! have fun 使用cocos2dx 3.2 原理都一樣 淡藍色的點是地圖 深藍色的點是障礙物 綠色的點是路徑 暗綠色的點是搜尋過的點 紅色的點是按路徑行走的點 dijkstra算法 會發現路徑最短,但尋找過的路徑比較多(計算速度慢) 最佳優

頭文件和源文件復制到項目中就能用了! 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//繼承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 m_openList;//開放列表(里面存放相鄰節點)
 static vector m_inspectList;//檢測列表(里面存放除了障礙物的節點)
 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)//計算兩個物體間的距離
 {
// 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)//把相鄰的節點放入開放節點中
 {
 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;
 
 //三種算法, 感覺H2不錯
 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::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)//根據點獲取對象
 {
 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)//從容器中移除對象
 {
 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();//計算路徑
 void drawPath();//繪制路徑
 vector m_mapList;//地圖
 
 void clearPath();//清理路徑
 
 PathSprite* m_player;//人物 用于演示行走
 int m_playerMoveStep;//人物當前的行程
 void playerMove();//人物走動
};

#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);
 }
 }
 
 //設置障礙物
// 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();
 
 //設置起始和終點
 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);
 //因為是開始點 把到起始點的距離設為0
 _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;
 }
 
 //檢測8個方向的相鄰節點是否可以放入開放列表中
 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))
 {
 //獲取觸摸點, 設置為終點
 PathSearchInfo::m_endX = _sp->m_x;
 PathSearchInfo::m_endY = _sp->m_y;
 //計算路徑
 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;
 }
 
 //把移除了障礙物的地圖放入檢測列表中
 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));
 
}


聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

cocos2dxA*算法

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

最新推薦

猜你喜歡

熱門推薦

專題
Top
主站蜘蛛池模板: 欧美亚洲精品在线 | 日韩经典第一页 | 国产中文字幕在线视频 | 国产l精品国产亚洲区在线观看 | 日本精品一区二区三区在线观看 | 91精品一区二区三区久久久久 | 国产区免费在线观看 | 中文字幕美日韩在线高清 | 亚洲一区中文字幕在线观看 | 欧美韩国日本一区 | 久久精品国产亚洲 | 欧美福利一区二区三区 | 日韩经典在线 | 国产成人综合久久精品下载 | 亚洲欧美日本在线 | 在线免费观看国产精品 | 久久91精品国产91久久跳舞 | 美国一级大黄大色毛片视频一 | 亚洲青草 | 亚洲国产精品一区二区九九 | 久热中文字幕在线精品首页 | 一区二区视频在线观看 | 一级毛片免费毛片一级毛片免费 | 91在线视频播放 | 正在播放国产一区 | 国产精品国产三级国产a | 交换国产精品视频一区 | 欧美综合在线观看 | 最近免费中文字幕大全高清片 | 中文字幕 日韩有码 | 成人欧美精品久久久久影院 | 久久91精品久久91综合 | 国产精品久久久久久久专区 | 性久久久久 | 99久久免费国产精品特黄 | 国产网站在线看 | 精品久久久久久久久中文字幕 | 免费在线欧美 | 97日日碰人人模人人澡 | 国产精品视频一区二区三区w | 国产日韩在线观看视频网站 |