标签:des blog http color io os ar 使用 for
本文转自:http://blog.csdn.net/w18767104183/article/category/1757765
前面一章讲了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<PathSprite*> m_openList;
- static PathSprite* m_inspectArray[MAP_WIDTH][MAP_HEIGHT];
- static vector<PathSprite*> m_pathList;
- static vector<PathSprite*> m_haveInspectList;
-
- 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->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()
- {
- 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* 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<PathSprite*>::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:
-
- virtual bool init();
-
-
- static cocos2d::CCScene* scene();
-
-
- void menuCloseCallback(CCObject* pSender);
-
-
- 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<PathSprite*> PathSearchInfo::m_openList;
-
- PathSprite* PathSearchInfo::m_inspectArray[MAP_WIDTH][MAP_HEIGHT] = {NULL};
-
- vector<PathSprite*> PathSearchInfo::m_pathList;
-
- vector<PathSprite*> 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()
- {
-
- CCScene *scene = CCScene::create();
-
-
- HelloWorld *layer = HelloWorld::create();
-
-
- scene->addChild(layer);
-
-
- return scene;
- }
-
- void HelloWorld::onEnter()
- {
- CCDirector* pDirector = CCDirector::sharedDirector();
- pDirector->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
- CCLayer::onEnter();
-
- }
-
- bool HelloWorld::init()
- {
-
-
- if ( !CCLayer::init() )
- {
- return false;
- }
-
- CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
- CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
-
-
-
-
-
-
-
- CCLabelTTF* pLabel = CCLabelTTF::create("A* + tiledMap", "Arial", 24);
-
-
- pLabel->setPosition(ccp(origin.x + visibleSize.width/2,
- origin.y + visibleSize.height - pLabel->getContentSize().height));
-
-
- 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];
-
-
- _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;
- }
-
-
- 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<PathSprite*>::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);
- 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<PathSprite*>::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_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());
- }
cocos2dx A* + tiledMap
标签:des blog http color io os ar 使用 for
原文地址:http://www.cnblogs.com/liuzhi/p/4036293.html