<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答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*+tiledMap

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

        cocos2dxA*+tiledMap

        cocos2dxA*+tiledMap:前面一章講了cocos2dx 中使用A星算法 這章中講 A*結合tiledmap 先看下效果圖 圖有點丑,忍受下 綠色的塊 表示人物的行走的路線(A*算法的結果) 紅色部分 表示A*算法搜尋過的點(越少,速度越快) 黑色的部分(其實是無色塊,因為背景是黑色的) 表示障礙物 這張圖
        推薦度:
        導讀cocos2dxA*+tiledMap:前面一章講了cocos2dx 中使用A星算法 這章中講 A*結合tiledmap 先看下效果圖 圖有點丑,忍受下 綠色的塊 表示人物的行走的路線(A*算法的結果) 紅色部分 表示A*算法搜尋過的點(越少,速度越快) 黑色的部分(其實是無色塊,因為背景是黑色的) 表示障礙物 這張圖

        前面一章講了cocos2dx 中使用A星算法 這章中講 A*結合tiledmap 先看下效果圖 圖有點丑,忍受下 綠色的塊 表示人物的行走的路線(A*算法的結果) 紅色部分 表示A*算法搜尋過的點(越少,速度越快) 黑色的部分(其實是無色塊,因為背景是黑色的) 表示障礙物 這張圖是

        前面一章講了cocos2dx 中使用A星算法

        這章中講 A*結合tiledmap

        先看下效果圖


        圖有點丑,忍受下

        綠色的塊 表示人物的行走的路線(A*算法的結果)

        紅色部分 表示A*算法搜尋過的點(越少,速度越快)

        黑色的部分(其實是無色塊,因為背景是黑色的) 表示障礙物


        這張圖是用tiledmap做出來的, 看看里面的內容


        可以看到 我把不能通過的地區的圖塊給刪了

        tiledmap中有2個層 一個是background, 一個是road. 為了方便, 我把road也用同樣的圖片, 最好的方法是用一種同樣的瓦片拼接出來一條能走的路, 讓后把background圖層加到road圖層上就ok了.

        下面直接上源碼, 用的時cocos2.2.3, 拷貝到項目中就能用了.當然別忘了自己做個像樣的tiledMap .

        如果你覺得好用, 就在文章底下頂一個吧 , enjoy it !

        #ifndef __HELLOWORLD_SCENE_H__
        #define __HELLOWORLD_SCENE_H__
        
        #include "cocos2d.h"
        #include "vector"
        using namespace std;
        USING_NS_CC;
        #define MAP_WIDTH 200//要比tmx中的map大
        #define MAP_HEIGHT 200
        class PathSprite 
        {
        public:
         PathSprite(CCSprite* sprite)
         {
         m_parent = NULL;
         m_child = NULL;
         m_costToSource = 0;
         m_FValue = 0;
         m_sprite = sprite;
         };
        public:
         CCSprite* m_sprite;//包含的瓦片精靈
         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 CCSize m_mapSize;//地圖大小
         static CCSize m_tileSize;//地圖的塊大小
         static vector m_openList;//開放列表(里面存放相鄰節點)
         static PathSprite* m_inspectArray[MAP_WIDTH][MAP_HEIGHT];//全部需要檢測的點
         static vector m_pathList;//路徑列表
         static vector m_haveInspectList;//檢測過的列表
        
         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->m_sprite->setColor(ccORANGE);//搜尋過的節點設為橘色(測試用)
         m_haveInspectList.push_back(adjacent);
         node->m_child = adjacent;//設置子節點
        
         PathSearchInfo::m_inspectArray[adjacent->m_x][adjacent->m_y] = NULL;//把檢測過的點從檢測列表中刪除
         PathSearchInfo::m_openList.push_back(adjacent);//加入開放列表
         }
         }
         static PathSprite* getMinPathFormOpenList()//從開放節點中獲取F值最小值的點
         {
         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* getObjFromInspectArray(int x, int y)//根據橫縱坐標從檢測數組中獲取點
         {
         if (x >=0 && y >=0 && x < m_mapSize.width && y < m_mapSize.height) {
         return m_inspectArray[x][y];
         }
         return NULL;
         }
         static bool removeObjFromOpenList( PathSprite* sprite)//從開放列表中移除對象
         {
         if (!sprite) {
         return false;
         }
         for (vector::iterator iter = m_openList.begin(); iter != m_openList.end(); iter++)
         {
         if (*iter == sprite)
         {
         m_openList.erase(iter);
         return true;
         }
         }
         return false;
         
         } 
        };
        class HelloWorld : public cocos2d::CCLayer
        {
        public:
         // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
         virtual bool init(); 
        
         // there's no 'id' in cpp, so we recommend returning the class instance pointer
         static cocos2d::CCScene* scene();
         
         // a selector callback
         void menuCloseCallback(CCObject* pSender);
         
         // implement the "static node()" method manually
         CREATE_FUNC(HelloWorld);
         void onEnter();
         virtual bool ccTouchBegan(CCTouch* touch, CCEvent* event);
         virtual void ccTouchMoved(CCTouch* touch, CCEvent* event);
         virtual void ccTouchEnded(CCTouch* touch, CCEvent* event);
         
         void calculatePath();//計算路徑
         
         void drawPath();//繪制路徑(測試用)
         
         void clearPath();//清理路徑
        
         void playerMove();//人物走動
        
         void update(float dt);//跟新大地圖(行走時, 人不動, 地圖跟著人動);
         
        public:
         CCPoint m_orignPoint;//人物的起始點
         
         PathSprite* m_player;//人物點
         
         int m_playerMoveStep;//人物當前的行程的索引
         
        };
        
        #endif // __HELLOWORLD_SCENE_H__
        
        #include "HelloWorldScene.h"
        
        USING_NS_CC;
        vector PathSearchInfo::m_openList;
        
        PathSprite* PathSearchInfo::m_inspectArray[MAP_WIDTH][MAP_HEIGHT] = {NULL};
        
        vector PathSearchInfo::m_pathList;
        
        vector PathSearchInfo::m_haveInspectList;
        
        CCSize PathSearchInfo::m_mapSize;
        
        CCSize PathSearchInfo::m_tileSize;
        
        int PathSearchInfo::m_startX;
        
        int PathSearchInfo::m_startY;
        
        int PathSearchInfo::m_endX;
        
        int PathSearchInfo::m_endY;
        
        CCScene* HelloWorld::scene()
        {
         // 'scene' is an autorelease object
         CCScene *scene = CCScene::create();
         
         // 'layer' is an autorelease object
         HelloWorld *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
        void HelloWorld::onEnter()
        {
         CCDirector* pDirector = CCDirector::sharedDirector();
         pDirector->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
         CCLayer::onEnter();
        
        }
        
        bool HelloWorld::init()
        {
         //////////////////////////////
         // 1. super init first
         if ( !CCLayer::init() )
         {
         return false;
         }
         
         CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
         CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
        
         /////////////////////////////
         // 2. add a menu item with "X" image, which is clicked to quit the program
         // you may modify it.
        
        
         
         CCLabelTTF* pLabel = CCLabelTTF::create("A* + tiledMap", "Arial", 24);
         
         // position the label on the center of the screen
         pLabel->setPosition(ccp(origin.x + visibleSize.width/2,
         origin.y + visibleSize.height - pLabel->getContentSize().height));
        
         // add the label as a child to this layer
         this->addChild(pLabel, 1);
        
         this->scheduleUpdate();
        
         CCTMXTiledMap* map = CCTMXTiledMap::create("gameMap.tmx");
         this->addChild(map);
         map->setPosition(CCPoint());
         CCTMXLayer* _road = map->layerNamed("road");//行走路徑的地圖
         CCSize _mapSize = map->getMapSize();
         for (int j = 0; j < _mapSize.height; j++) {
         for (int i = 0; i < _mapSize.width; i++) {
         CCSprite* _sp = _road->tileAt(CCPoint(i, j));
         if (_sp) {
         PathSprite* _pathSprite = new PathSprite(_sp);
         _pathSprite->m_x = i;
         _pathSprite->m_y = j;
         PathSearchInfo::m_inspectArray[i][j] = _pathSprite;//把地圖中所有的點一一對應放入檢測列表中
         }
         }
         }
         PathSearchInfo::m_mapSize = _mapSize;//獲取地圖的尺寸
         PathSearchInfo::m_tileSize = map->getTileSize();//獲取瓦片的尺寸
         
         //設置起始和終點
         PathSearchInfo::m_startX =30;
         PathSearchInfo::m_startY = 75;
        
         //創建一個人物
         m_player = new PathSprite(CCSprite::create("10001.png"));
         m_player->m_sprite->setAnchorPoint(CCPoint(0.5,0));
         this->addChild(m_player->m_sprite);
         
         m_player->m_x = PathSearchInfo::m_startX;//設置人物的起始的地圖坐標
         m_player->m_y = PathSearchInfo::m_startY;
         
         m_orignPoint = PathSearchInfo::m_inspectArray[PathSearchInfo::m_startX][PathSearchInfo::m_startY]->m_sprite->getPosition();
         m_player->m_sprite->setPosition(m_orignPoint);//設置人物的起始的世界坐標
        
         
         
         return true;
        }
        void HelloWorld::calculatePath()
        {
         
         //得到開始點的節點
         PathSprite* _startNode = PathSearchInfo::m_inspectArray[PathSearchInfo::m_startX][PathSearchInfo::m_startY];
         //得到結束點的節點
         PathSprite* _endNode = PathSearchInfo::m_inspectArray[PathSearchInfo::m_endX][PathSearchInfo::m_endY];
         
         //因為是開始點 把到起始點的距離設為0, F值也為0
         _startNode->m_costToSource = 0;
         _startNode->m_FValue = 0;
         
         //把已經檢測過的點從檢測列表中刪除
         PathSearchInfo::m_inspectArray[PathSearchInfo::m_startX][PathSearchInfo::m_startY] = NULL;
         //把該點放入已經檢測過點的列表中
         PathSearchInfo::m_haveInspectList.push_back(_startNode);
         //然后加入開放列表
         PathSearchInfo::m_openList.push_back(_startNode);
         
         PathSprite* _node = NULL;
         while (true)
         {
         //得到離起始點最近的點(如果是第一次執行, 得到的是起點)
         _node = PathSearchInfo::getMinPathFormOpenList();
         if (!_node)
         {
         //找不到路徑
         break;
         }
         //把計算過的點從開放列表中刪除
         PathSearchInfo::removeObjFromOpenList( _node);
         int _x = _node->m_x;
         int _y = _node->m_y;
         
         //
         if (_x ==PathSearchInfo::m_endX && _y == PathSearchInfo::m_endY)
         {
         break;
         }
         
         //檢測8個方向的相鄰節點是否可以放入開放列表中
         CCLog("%d, %d",_x, _y);
         PathSprite* _adjacent = PathSearchInfo::getObjFromInspectArray( _x + 1, _y + 1);
         PathSearchInfo::inspectTheAdjacentNodes(_node, _adjacent, _endNode);
         
         _adjacent = PathSearchInfo::getObjFromInspectArray( _x +1, _y);
         PathSearchInfo::inspectTheAdjacentNodes(_node, _adjacent, _endNode);
         
         _adjacent = PathSearchInfo::getObjFromInspectArray( _x +1, _y-1);
         PathSearchInfo::inspectTheAdjacentNodes(_node, _adjacent, _endNode);
         
         _adjacent = PathSearchInfo::getObjFromInspectArray( _x , _y -1);
         PathSearchInfo::inspectTheAdjacentNodes(_node, _adjacent, _endNode);
         
         _adjacent = PathSearchInfo::getObjFromInspectArray( _x -1, _y - 1);
         PathSearchInfo::inspectTheAdjacentNodes(_node, _adjacent, _endNode);
         
         _adjacent = PathSearchInfo::getObjFromInspectArray( _x -1, _y);
         PathSearchInfo::inspectTheAdjacentNodes(_node, _adjacent, _endNode);
         
         _adjacent = PathSearchInfo::getObjFromInspectArray( _x -1, _y+1);
         PathSearchInfo::inspectTheAdjacentNodes(_node, _adjacent, _endNode);
         
         _adjacent = PathSearchInfo::getObjFromInspectArray( _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::iterator iter = PathSearchInfo::m_pathList.begin(); iter != PathSearchInfo::m_pathList.end(); iter++)
         {
         (*iter)->m_sprite->setColor(ccGREEN);
         }
         
        }
        CCRect getBoundingBox(float x, float y, float width, float height)
        {
         return CCRect(x - width/2, y - height/2, width, height);
        }
        bool HelloWorld::ccTouchBegan(CCTouch* touch, CCEvent* event)
        {
        
         //清除之前的路徑
         clearPath();
         
         auto nodePosition = convertToNodeSpace( touch->getLocation() );
         CCLog("%f, %f", nodePosition.x, nodePosition.y);
        // for (int i = 0; i < PathSearchInfo::m_inspectList.size(); i++)
        // {
        // PathSprite* _sp = PathSearchInfo::m_inspectList[i];
        // 
        // CCRect _rect = getBoundingBox( _sp->m_sprite->getPositionX(), _sp->m_sprite->getPositionY(), _sp->m_sprite->getContentSize().width, _sp->m_sprite->getContentSize().height);
        // 
        // if (_rect.containsPoint(nodePosition))
        // {
         PathSprite* _sp = PathSearchInfo::m_inspectArray[(int)(nodePosition.x/PathSearchInfo::m_tileSize.width)][(int)(PathSearchInfo::m_mapSize.height - nodePosition.y/PathSearchInfo::m_tileSize.height)];
         if (_sp) {
         CCLog("%f, %f", _sp->m_sprite->getPositionX(), _sp->m_sprite->getPositionY());
         //獲取觸摸點, 設置為終點
         PathSearchInfo::m_endX = _sp->m_x;
         PathSearchInfo::m_endY = _sp->m_y;
         //計算路徑
         calculatePath();
         //繪制路徑
         drawPath( );
         //移動物體
         playerMove();
         }
         
         
        // }
        // 
        // }
        
         return true;
        }
        
        void HelloWorld::ccTouchMoved(CCTouch* touch, CCEvent* event)
        {
        
        }
        
        
        
        void HelloWorld::ccTouchEnded(CCTouch* touch, CCEvent* event)
        {
        
        }
        
        void HelloWorld::menuCloseCallback(CCObject* pSender)
        {
        #if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
        	CCMessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
        #else
         CCDirector::sharedDirector()->end();
        #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
         exit(0);
        #endif
        #endif
        }
        
        void HelloWorld::clearPath()
        {
         for (vector::iterator iter = PathSearchInfo::m_haveInspectList.begin(); iter != PathSearchInfo::m_haveInspectList.end(); iter++)
         {
         (*iter)->m_sprite->setColor(ccWHITE);
         (*iter)->m_costToSource = 0;
         (*iter)->m_FValue = 0;
         (*iter)->m_parent = NULL;
         (*iter)->m_child = NULL;
         
         PathSearchInfo::m_inspectArray[(*iter)->m_x][(*iter)->m_y] = (*iter);
         }
         
         //把移除了障礙物的地圖放入檢測列表中
         //PathSearchInfo::m_inspectList = PathSearchInfo::m_mapList;
         PathSearchInfo::m_openList.clear();
         PathSearchInfo::m_pathList.clear();
         PathSearchInfo::m_haveInspectList.clear();
         PathSearchInfo::m_startX = m_player->m_x;
         PathSearchInfo::m_startY = m_player->m_y;
         m_player->m_sprite->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->m_sprite->runAction(CCSequence::create(CCMoveTo::create(1/24.0, PathSearchInfo::m_pathList[m_playerMoveStep]->m_sprite->getPosition()), CCCallFunc::create(this, SEL_CallFunc(&HelloWorld::playerMove)) , NULL));
         
        }
        void HelloWorld::update(float dt)
        {
         this->setPosition(m_orignPoint - m_player->m_sprite->getPosition());
        }
        

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

        文檔

        cocos2dxA*+tiledMap

        cocos2dxA*+tiledMap:前面一章講了cocos2dx 中使用A星算法 這章中講 A*結合tiledmap 先看下效果圖 圖有點丑,忍受下 綠色的塊 表示人物的行走的路線(A*算法的結果) 紅色部分 表示A*算法搜尋過的點(越少,速度越快) 黑色的部分(其實是無色塊,因為背景是黑色的) 表示障礙物 這張圖
        推薦度:
        標簽: 前面 講了 coc
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 亚洲人成网站在线在线观看| 91天堂素人精品系列全集亚洲 | 亚洲AV色香蕉一区二区| 曰批全过程免费视频免费看| 永久黄网站色视频免费直播| 亚洲精品av无码喷奶水糖心| 国产精品嫩草影院免费| 久久水蜜桃亚洲AV无码精品| 免费乱码中文字幕网站| 国产黄在线播放免费观看| 久久久久亚洲AV综合波多野结衣 | 中文字幕亚洲码在线| 啦啦啦中文在线观看电视剧免费版| 亚洲娇小性xxxx色| 成人免费淫片在线费观看| 蜜芽亚洲av无码一区二区三区| 成人爱做日本视频免费| 日本一区二区三区免费高清在线| 亚洲精品视频在线观看你懂的| 久久免费香蕉视频| 久久久久亚洲AV无码网站| 成年人免费的视频| 免费AA片少妇人AA片直播| 亚洲91精品麻豆国产系列在线| 成人a视频片在线观看免费| 自拍偷自拍亚洲精品播放| 亚洲精品A在线观看| 久久伊人免费视频| 亚洲人成网站色在线观看| 免费一级毛片不卡不收费| 99精品免费视频| 久久精品国产亚洲Aⅴ香蕉| 久久福利青草精品资源站免费| 亚洲熟妇av一区| 免费国产真实迷j在线观看| 久青草视频在线观看免费| 亚洲国产美女精品久久| 免费观看亚洲人成网站| 亚洲久热无码av中文字幕| 久久久久亚洲精品男人的天堂| 天天影院成人免费观看|