Cocos2d-x 3.1.1 學習日誌16--A星演算法(A*搜尋演算法)的學習,cocos2d-x16--a

來源:互聯網
上載者:User

Cocos2d-x 3.1.1 學習日誌16--A星演算法(A*搜尋演算法)的學習,cocos2d-x16--a

    A *搜尋演算法俗稱A星演算法。這是一種在圖形平面上,有多個節點的路徑,求出最低通過成本的演算法。常用於遊戲中的NPC的移動計算,或線上遊戲的BOT的移動計算上。

   首先:1、在Map地圖中任取2個點,開始點和結束點  

          2、首先判斷該點是不是不可以穿越的點,或者是已經再close中了 

          3、如果2步驟為真,什麼都不做,如果為假,那麼我們就進行添加了  

          4、如果在添加的時候,發現該點在open中不存在,那麼我們直接添加,而且視之為當前節點,如果該點              存在open中,那麼我們比較G值,如果發現當前節點到該節點的G小於原來的G,那麼再重新設定G,F值,              然後設定這個節點為當前節點。  

          5、再添判斷玩之後,再添加它的4個鄰接點,迴圈1-4的步驟。直至找到,或者說是open中為null了的時              候,就結束查詢了。

代碼如下:

#include <iostream> #include <string>#include "AStartMap.h"using namespace std;int main() {    AstartMap *gameMap = new AstartMap;    gameMap->initMap();    if(gameMap != 0) {        delete gameMap;        gameMap = 0;    }    return 0;}#ifndef ASTARTNODE_H_#define ASTARTNODE_H_class AStartNode{public:    AStartNode();    ~AStartNode();public:    void setPos(int icol, int irow);    void setG(int iG);    int getG();    void setH(int iH);    int getH();    void setF(int iF);    void setFID(int iFID);    int getFID();    int getF();    int getCol();    int getRow();    private:    int m_Col;    int m_Row;    int m_G;    int m_H;    int m_F;    int m_FID;};// end of AStartNode#endif // end of ASTARTNODE_H_#include "AStartNode.h"AStartNode::AStartNode() : m_Col(0), //                                         m_Row(0),                                        m_G(0),                                        m_H(0),                                        m_F(0),                                        m_FID(0){}AStartNode::~AStartNode() {}void AStartNode::setPos(int icol, int irow) {    m_Col = icol;    m_Row = irow;}void AStartNode::setG(int iG) {    m_G = iG;}int AStartNode::getG() {    return m_G;}void AStartNode::setH(int iH) {    m_H = iH;}int AStartNode::getH() {    return m_H;}void AStartNode::setF(int iF) {    m_F = iF;}int AStartNode::getF() {    return m_F;}int AStartNode::getCol() {    return m_Col;}int AStartNode::getRow() {    return m_Row;}void AStartNode::setFID(int iFID) {    m_FID = iFID;}int AStartNode::getFID() {    return m_FID;}#ifndef ASTARTMAP_H_#define ASTARTMAP_H_#include <vector>class AStartNode;class AstartMap{public:    typedef enum {        STARTMAP_COL = 10,        STARTMAP_ROW = 10,    } StartMap;    typedef enum {        MAPPATH_BEGINPOINT = -2,        MAPPATH_WALL = -1,        MAPPATH_ROAD = 0,        MAPPATH_ENDPOINT = 2,    } MapPath;    typedef enum {        STARTNODE_G = 10,        STARTNODE_H = 10,    }StartNodeInfo;public:    AstartMap();    ~AstartMap();public:    void initMap();private:    void _initMapBoard();    void _initSelectBeginPoint();    void _addIntoCloseNode(AStartNode *newCloseNode);    void _addIntoOpenNode(AStartNode *newOpenNode);    void _deleteBeginNodefromOpenNode(AStartNode *newOpenNode);    void _add_adjacentnodeToOpenNode(AStartNode *newOpenNode);    void _beginToMove();    void _setStartNode_G_H_Value(AStartNode *newOpenNode, AStartNode *parentNode);    bool _isWater(AStartNode *pStartNode);bool _isInClose(AStartNode *pStartNode);    bool _isInOpen(AStartNode *pStartNode);private:    AStartNode *_getMinFstartNode();    AStartNode *_getAStartNodeAt(int iCol, int iRow);    void _heapRebuild(std::vector<AStartNode *> &rStartNodeArray,int root,int size);    void _heapSort(std::vector<AStartNode *> &rStartNodeArray ,int size);private:    std::vector<AStartNode *> m_AstartNode;    std::vector<AStartNode *> m_openNode;    std::vector<AStartNode *> m_closeNode;    AStartNode *m_pEndNode;    int GameMap[STARTMAP_COL][STARTMAP_ROW]; // map    };// end of AstartMapbool isNum(int inum);#endif // end of ASTARTMAP_H_#include "AStartNode.h"#include <iostream>#include <ctype.h> #include <assert.h>#include <cmath>#include "AStartMap.h"extern bool isNum(int inum);AstartMap::AstartMap() : m_pEndNode(0){}AstartMap::~AstartMap() {}void AstartMap::initMap() {    /*    *@init the game map    */    _initMapBoard();}void AstartMap::_initMapBoard() {    //memset(GameMap, MAPPATH_ROAD, STARTMAP_COL * STARTMAP_ROW * sizeof(int));    for(int i = 0; i < STARTMAP_COL; ++i) {        for(int j = 0; j < STARTMAP_ROW; ++j) {            GameMap[i][j] = MAPPATH_ROAD;            AStartNode *aStartNode = new AStartNode;            aStartNode->setPos(i, j);             m_AstartNode.push_back(aStartNode);        }    }    for(int i = 0; i < 7; ++i) { // set the game wall        GameMap[i + 2][4] = MAPPATH_WALL;    }    _initSelectBeginPoint();}void AstartMap::_initSelectBeginPoint() {    int ibegin_xpos = 0;    int ibegin_ypos = 0;    std::cout<<"Select the Begin Point(X in(0-9), y in (0- 9): \n";    std::cin>>ibegin_xpos;    std::cin>>ibegin_ypos;    if(!isNum(ibegin_xpos) || !isNum(ibegin_ypos))   return;    std::cout<<"Select the End Point(X in(0-9), y in (0- 9): \n";    int iend_xpos = 0;    int iend_ypos = 0;    std::cin>>iend_xpos;    std::cin>>iend_ypos;    if(!isNum(iend_xpos) || !isNum(iend_ypos))   return;    GameMap[iend_xpos][iend_ypos] = MAPPATH_ENDPOINT; // set end point    AStartNode *pBeginNode = _getAStartNodeAt(ibegin_xpos, ibegin_ypos);    m_pEndNode = _getAStartNodeAt(iend_xpos, iend_ypos);    if(pBeginNode == 0) return;    pBeginNode->setG(0);    pBeginNode->setF(0);    pBeginNode->setH(0);    m_openNode.push_back(pBeginNode);    /*    *@Game Begin    *the player begins to move    */    _beginToMove();}void AstartMap::_beginToMove() {    while(true) {        AStartNode *pBeginNode = _getMinFstartNode();        std::cout<<"select point: "<<pBeginNode->getCol()<<", "<<pBeginNode->getRow()<<std::endl;        _add_adjacentnodeToOpenNode(pBeginNode);        _addIntoCloseNode(pBeginNode);        _deleteBeginNodefromOpenNode(pBeginNode);        if(pBeginNode == m_pEndNode) { // find the end position            std::cout<<"fine the end position"<<std::endl<<std::endl;            break;        }    }}AStartNode *AstartMap::_getAStartNodeAt(int iCol, int iRow) {    int iNode_Count = m_AstartNode.size();    for(int i = 0; i < iNode_Count; ++i) {        if(m_AstartNode[i]->getCol() == iCol && m_AstartNode[i]->getRow() == iRow) return m_AstartNode[i];    }    return 0;}void AstartMap::_addIntoCloseNode(AStartNode *newCloseNode) {    if(newCloseNode == 0) return;    m_closeNode.push_back(newCloseNode);}void AstartMap::_addIntoOpenNode(AStartNode *newOpenNode) {    if(newOpenNode == 0) return;    m_openNode.push_back(newOpenNode); // then other 4 node}void AstartMap::_add_adjacentnodeToOpenNode(AStartNode *newOpenNode) {    int ileftNodeRow = newOpenNode->getRow() - 1;    if(ileftNodeRow >= 0) {        AStartNode *leftNode = _getAStartNodeAt(newOpenNode->getCol(), ileftNodeRow);        if(!_isWater(leftNode) && !_isInClose(leftNode) ) {            if(! _isInOpen(leftNode) ) {                // in open                 leftNode->setFID(newOpenNode->getFID());                _addIntoOpenNode(leftNode);                    _setStartNode_G_H_Value(leftNode, newOpenNode);            } else {                // not in open               // _setStartNode_G_H_Value(leftNode, newOpenNode);            }        }    }    int irightNodeRow = newOpenNode->getRow() + 1;    if(irightNodeRow < STARTMAP_ROW) {        AStartNode *rightNode = _getAStartNodeAt(newOpenNode->getCol(), irightNodeRow);        if(!_isWater(rightNode) && !_isInClose(rightNode)) {            if(! _isInOpen(rightNode) ) {                // in open                 rightNode->setFID(newOpenNode->getFID());                _addIntoOpenNode(rightNode);                  _setStartNode_G_H_Value(rightNode, newOpenNode);            } else {                // not in open                //_setStartNode_G_H_Value(rightNode, newOpenNode);            }        }    }    int iupNodeCol = newOpenNode->getCol() - 1;    if(iupNodeCol >= 0) {        AStartNode *upNode = _getAStartNodeAt(iupNodeCol, newOpenNode->getRow());        if(!_isWater(upNode) && !_isInClose(upNode)) {            if( ! _isInOpen(upNode)) {                //in open                upNode->setFID(newOpenNode->getFID());                _addIntoOpenNode(upNode);                _setStartNode_G_H_Value(upNode, newOpenNode);            } else {                //_setStartNode_G_H_Value(upNode, newOpenNode);            }        }    }    int idownNodeCol = newOpenNode->getCol() + 1;    if(idownNodeCol < STARTMAP_COL) {        AStartNode *downNode = _getAStartNodeAt(idownNodeCol, newOpenNode->getRow());        if(!_isWater(downNode) && !_isInClose(downNode)) {            if( ! _isInOpen(downNode)) {                //in open                downNode->setFID(newOpenNode->getFID());                _addIntoOpenNode(downNode);                _setStartNode_G_H_Value(downNode, newOpenNode);            } else {                //_setStartNode_G_H_Value(downNode, newOpenNode);            }        }    }}bool AstartMap::_isWater(AStartNode *pStartNode) {    int icol = pStartNode->getCol();    int irow = pStartNode->getRow();    if(GameMap[icol][irow] == MAPPATH_WALL) return true;    return false;}bool AstartMap::_isInClose(AStartNode *pStartNode) {    assert(pStartNode);    std::vector<AStartNode *>::iterator it = m_closeNode.begin();    for( ; it != m_closeNode.end(); ++it) {        if(*it == pStartNode) {            return true;        }    }    return false;}bool AstartMap::_isInOpen(AStartNode *pStartNode) {    assert(pStartNode);    std::vector<AStartNode *>::iterator it = m_openNode.begin();    for(; it != m_openNode.end(); ++it) {        if(*it == pStartNode) {            return true;        }    }    return false;}void AstartMap::_deleteBeginNodefromOpenNode(AStartNode *newOpenNode) {    if(newOpenNode == 0) return;    std::vector<AStartNode *>::iterator it = m_openNode.begin();    for( ; it != m_openNode.end(); ++it) {        if(*it == newOpenNode) {            m_openNode.erase(it);            break;        }    }}void AstartMap::_setStartNode_G_H_Value(AStartNode *newOpenNode, AStartNode *parentNode) {    if(newOpenNode == 0 || parentNode == 0) return ;    if(newOpenNode->getCol() == 6 && newOpenNode->getRow() == 3) {        int i = 0;    }    newOpenNode->setG( parentNode->getG() + 10);    newOpenNode->setH( ( abs((m_pEndNode->getRow() - newOpenNode->getRow())) + abs((m_pEndNode->getCol() - newOpenNode->getCol())) - 1) * 10);    newOpenNode->setF(newOpenNode->getG() + newOpenNode->getH());}AStartNode *AstartMap::_getMinFstartNode() {    _heapSort(m_openNode, m_openNode.size());    int icount = m_openNode.size();    AStartNode *minNode = m_openNode[0];    return minNode;}void AstartMap::_heapRebuild(std::vector<AStartNode *> &rStartNodeArray, int root, int size)  {      int child = 2 * root + 1;      if(child <= size - 1) {          int rightChild = child + 1;          if(rightChild <= size - 1)              if(rStartNodeArray[child]->getF() < rStartNodeArray[rightChild]->getF())                  child = rightChild;          if(rStartNodeArray[root]->getF() < rStartNodeArray[child]->getF())          {              AStartNode *temp = rStartNodeArray[child];              rStartNodeArray[child] = rStartNodeArray[root];              rStartNodeArray[root] = temp;              _heapRebuild(rStartNodeArray, child, size);          }      }  }  void AstartMap::_heapSort(std::vector<AStartNode *> &rStartNodeArray, int size)  {      for(int i = size-1; i >= 0; i--){          _heapRebuild(rStartNodeArray,i,size);      }      int last=size-1;      for(int i = 1;i <= size; i++, last--) {          AStartNode *temp=rStartNodeArray[0];          rStartNodeArray[0]=rStartNodeArray[last];          rStartNodeArray[last]=temp;          _heapRebuild(rStartNodeArray,0,last);      }  }  //bool isNum(int inum) { // if the num in(0-9) return true, or return false    if(inum >= 0 && inum <= 9) return true;    return false;}

  

速度和精確度之間的選擇前不是靜態。你可以基於CPU的速度、用於路徑搜尋的時間片數、地圖上物體(units)的數量、物體的重要性、組(group)的大小、難度或者其他任何因素來進行動態選擇。取得動態折衷的一個方法是,建立一個啟發學習法函數用於假定通過一個網格空間的最小代價是1,然後建立一個代價函數(cost function)用於測量(scales):g’(n) = 1 + alpha * ( g(n) – 1 )如果alpha是0,則改進後的代價函數的值總是1。這種情況下,地形代價被完全忽略,A*工作變成簡單地判斷一個網格可否通過。如果alpha是1,則最初的代價函數將起作用,然後你得到了A*的所有優點。你可以設定alpha的值為0到1的任意值。你也可以考慮對啟發學習法函數的返回值做選擇:絕對最小代價或者期望最小代價。例如,如果你的地圖大部分地形是代價為2的草地,其它一些地方是代價為1的道路,那麼你可以考慮讓啟發學習法函數不考慮道路,而只返回2*距離。速度和精確度之間的選擇並不是全域的。在地圖上的某些地區,精確度是重要的,你可以基於此進行動態選擇。例如,假設我們可能在某點停止重新計算路徑或者改變方向,則在接近當前位置的地方,選擇一條好的路徑則是更重要的,因此為何要對後續路徑的精確度感到厭煩?或者,對於在地圖上的一個安全區域,最短路徑也許並不十分重要,但是當從一個敵人的村莊逃跑時,安全和速度是最重要的。在遊戲中,路徑潛在地花費了許多儲存空間,特別是當路徑很長並且有很多物體需要尋路時。路徑壓縮,導航點和beacons通過把多個步驟儲存為一個較小資料從而減少了空間需求。Waypoints rely on straight-line segments being common so that we have to store only the endpoints, while beacons rely on there being well-known paths calculated beforehand between specially marked places on the map.如果路徑仍然用了許多儲存空間,可以限制路徑長度,這就回到了經典的時間-空間折衷法:為了節省空間的,資訊可以被丟棄,稍後才重新計算它。




因為一些需要要學習cocos2d-x相關知識用於項目開發指教學習的過程最好給點資源

cn.cocos2d-x.org/document
 
教個問題:學習android的cocos2d-x需要什知識(除了c++),有沒有什好的學習資料?

看java和引擎的sdk,還有上網找例子教程。
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.