zoukankan      html  css  js  c++  java
  • Cocos2d-x 3.2 大富翁游戏项目开发-第七部分 获取角色路径_3

    点击下载代码   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()方法是怎样推断当前位置上下左右是否可通过的。

    逻辑非常easy,就是依据传进来的方向,推断二维数组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]);
    	}
    …………………
    	
    }
    

    測试结果如图,获取路径显示当前位置能够向 左、右、上 走。




    未完待续………….


  • 相关阅读:
    NOIP 2012 T5 借教室 [洛谷P1083]
    POJ2437 Muddy roads
    POJ2288 Islands and Bridges
    洛谷P2014 TYVJ1051 选课
    POJ1741 Tree
    CODEVS1995 || TYVJ1863 黑魔法师之门
    TYVJ1939 玉蟾宫
    TYVJ1305 最大子序和
    POJ1737 Connected Graph
    TYVJ1864 守卫者的挑战
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5208897.html
Copyright © 2011-2022 走看看