点击下载代码 http://download.csdn.net/detail/lideguo1979/8291803
新建一个类RouteNavigation,定义getPath()方法,用来获取角色路径,我们采用单例模式设计该类,先看该类的定义
RouteNavigation.h class RouteNavigation{ public: static RouteNavigation* routeNav_Instance; //该类静态对象 static RouteNavigation* getInstance();//获取静态对象方法 void getPath(Sprite* playerSprite,int stepsCount,bool** canPassGrid,int gridRowsCount,int gridColsCount);//定义获取路径的方法 protected: RouteNavigation(void); ~RouteNavigation(void); };
RouteNavigation.cpp RouteNavigation::~RouteNavigation(void) { routeNav_Instance = NULL; } RouteNavigation* RouteNavigation::getInstance() { if(!routeNav_Instance) { routeNav_Instance = new RouteNavigation(); } return routeNav_Instance;
定义好类后,开始实现getPath()方法,还记得前面的getPath流程图吧 我就按前面的流程开始编写该方法
参数说明: playerSprite:要获取路径的角色,就是哪个角色调用getPath方法 ,就把自己传进来 stepsCount: 角色要走多少步 canPassGrid:关卡地图能否走动的二维数组 gridRowsCount:canPassGrid数组的行数 gridColsCount:canPassGrid数组的列数 void RouteNavigation::getPath(Sprite* playerSprite,int stepsCount,bool** canPassGrid,int gridRowsCount,int gridColsCount) { //定义的vector一维数组,用来存放获得的路径行列 我们先清空一下 pathCols_vector.clear(); pathRow_vector.clear(); //定义的角色当前的所在行列,下一步所处的行列 int nextCol, nextRow; int currentCol,currentRow; //获取角色当前所处位置的坐标值 float x = playerSprite->getPositionX(); float y = playerSprite->getPositionY(); //根据角色当前的坐标值 给角色开始的行列变量赋值。就是坐标除以每行列的宽高值 currentCol = x/tiledHeight; //我们为了让角色居中显示,曾经在GameBaseScene:: addPlayer()的方法中,给角色纵向位置+ tiledHeight,此处要减掉,才能得到正确行数 currentRow = (y - tiledWidth)/tiledWidth; //定义canPassGrid_copy,接收传过来的canPassGrid二维数组里的值 bool** canPassGrid_copy = new bool*[gridRowsCount]; for(int row = 0;row<gridRowsCount;row++) { for(int col = 0;col<gridColsCount;col++) { canPassGrid_copy[row][col] = canPassGrid[row][col]; } } //创建一维数组direction_4[] 其中的值表示当前行列位置的上下左右四个相邻位置是否可走 std::vector<bool> direction_4; //建立canPassDirVector_temp存放当前位置上下左右可以通过的位置 std::vector<int> canPassDirVector_temp; int hasGoneNumber = 0; //开始循环查找每一步的能走的行列值 while (hasGoneNumber<stepsCount) { //先清空一下数组,恢复为默认值false direction_4.clear(); for(int i=0;i<4;i++) { direction_4.push_back(false); } canPassDirVector_temp.clear(); //查找当前行列位置的上下左右四个方向,看能否通过,并给direction_4相应位置赋值true或false direction_4[GO_UP] = isCanGoByColRow(currentRow,currentCol,GO_UP,canPassGrid_copy); direction_4[GO_DOWN] = isCanGoByColRow(currentRow,currentCol,GO_DOWN,canPassGrid_copy); direction_4[GO_LEFT] = isCanGoByColRow(currentRow,currentCol,GO_LEFT,canPassGrid_copy); direction_4[GO_RIGHT] = isCanGoByColRow(currentRow,currentCol,GO_RIGHT,canPassGrid_copy); //遍历direction_4,找到可以通过的位置,存入canPassDirVector_temp中 for(int i=0;i<4;i++) { if(direction_4[i]) { canPassDirVector_temp.push_back(i); } } //从记录可以通过的一维数组canPassDirVector_temp中随机取一个方向 int _rand = rand()%canPassDirVector_temp.size(); //根据方向,取得下一步的行列值 switch(canPassDirVector_temp[_rand]) { case GO_UP: { nextRow = currentRow - 1; nextCol = currentCol ; break; } case GO_DOWN: { nextRow = currentRow +1; nextCol = currentCol; break; } case GO_LEFT: { nextRow = currentRow ; nextCol = currentCol - 1; break; } case GO_RIGHT: { nextRow = currentRow ; nextCol = currentCol + 1; break; } } //switch判断完方向,给下一步行列赋值之后,存入到路径数组中 pathCols_vector.push_back(nextCol); pathRow_vector.push_back(nextRow); //让当前所在的行列,置为false,表示已经走过,不可以再走,防止角色踱步不前 canPassGrid_copy[currentRow][currentCol] = false; //让当前行列值指向下一个行列位置,准备从下一个位置,查找可走的路径行列 currentCol = nextCol; currentRow = nextRow; //步数加1,开始查找下一个可走行列 hasGoneNumber++; } //查找完路径后,进行相关变量的内存清理释放工作 CC_SAFE_DELETE(canPassGrid_copy); direction_4.clear(); canPassDirVector_temp.clear(); std::vector<bool>(direction_4).swap(direction_4); std::vector<int>(canPassDirVector_temp).swap(canPassDirVector_temp); }
看一下isCanGoByColRow()方法是如何判断当前位置上下左右是否可通过的。 逻辑很简单,就是根据传进来的方向,判断二维数组canPassGrid相应行列是否是true,如果true,表示可以通过 bool RouteNavigation::isCanGoByColRow(int row,int col,int direction,bool** canPassGrid) { switch(direction) { case GO_UP: { return canPassGrid[row -1][col]; } case GO_DOWN: { return canPassGrid[row +1][col]; } case GO_LEFT: { return canPassGrid[row][col -1]; } case GO_RIGHT: { return canPassGrid[row][col +1]; } } return false;
好了 ,我们修改一下go按键,测试一下是获得的路径 void GameBaseScene::addGoButton() { //修改了一下Go 按键 变为了menu Menu* menu = Menu::create(); menu->setPosition(CCPointZero); //去调用goButtonCallback方法 MenuItemImage* goMenuItemButton = MenuItemImage::create("map/go_normal.png", "map/go_press.png", this, menu_selector(GameBaseScene::goButtonCallback)); goMenuItemButton->setPosition(ccp(tableStartPosition_x+2*tableWidth,tableStartPosition_y-tableHeight*6)); menu->addChild(goMenuItemButton); addChild(menu); } void GameBaseScene::goButtonCallback(cocos2d::CCObject *pSender) { log("go button clicked"); //先让获取走5步的路径 RouteNavigation::getInstance()->getPath(player1,5,canPassGrid,tiledRowsCount,tiledColsCount); std::vector<int> colVector = RouteNavigation::getInstance()->getPathCols_vector(); std::vector<int> rowVector = RouteNavigation::getInstance()->getPathRow_vector(); //打印出路径 for(int i=0;i<rowVector.size();i++) { log(" rowVector row is %d --- colVector col is %d",rowVector[i],colVector[i]); } ………………… }
测试结果如图,获取路径显示当前位置可以向 左、右、上 走。
未完待续………….