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()方法是如何判斷當前位置上下左右是否可通過的。 
邏輯很簡單,就是根據傳進來的方向,判斷二維數組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]);
	}
…………………
	
}

測試結果如圖,獲取路徑顯示當前位置可以向 左、右、上 走。




 

未完待續………….


發佈了77 篇原創文章 · 獲贊 48 · 訪問量 27萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章