Cocos2d-x 3.2 大富翁遊戲項目開發-第十三部分 購買空地

先看一下角色各自的土地圖片


1、先在場景中創建一個對話框,這個對話框是用來顯示購買空地的確認信息的。buyLandCallback回調方法,根據點擊的按鈕進行分別處理,

如果確認是買地,則修改空地圖片,如果取消則返回場景繼續其他角色行走。buyLandCallback代碼稍後再看


void GameBaseScene::initPopDialog()
{
	popDialog = PopupLayer::create(DIALOG_BG);
	
   	popDialog->setContentSize(CCSizeMake(Dialog_Size_Width, Dialog_Size_Height)); 
    	popDialog->setTitle(DIALOG_TITLE);
	popDialog->setContentText("", 20, 60, 250);
    	popDialog->setCallbackFunc(this, callfuncN_selector(GameBaseScene::buyLandCallback));

    	popDialog->addButton(BUTTON_BG1, BUTTON_BG3, OK, Btn_OK_TAG);
    	popDialog->addButton(BUTTON_BG2, BUTTON_BG3, CANCEL, Btn_Cancel_TAG);
    	this->addChild(popDialog);
	popDialog->setVisible(false);
}

2、 我們把消息註冊接收重新整理一下,統一寫到一個方法中,這樣便於後期擴展處理

void GameBaseScene::receivedNotificationOMsg(Object* data)
{
……………………

	switch(retMsgType)
	{
	case MSG_BUY_BLANK_TAG: //處理購買空地
		{
			………………………
		}

	case MSG_GO_SHOW_TAG://處理go按鈕顯示
		{
			…………………
		}
	case  MSG_GO_HIDE_TAG://處理go按鈕消失
		{
			……………………..
		}


	}
}

3、 編寫工具類Util,主要包含座標轉換 、 字符串截取相關方法。

struct Util
{
	//把layer層上的座標轉換成GL座標 
	static Point map2GL(const Point& ptMap, TMXTiledMap* map)
	{
		Point ptUI;
		ptUI.x = ptMap.x * map->getTileSize().width;
		ptUI.y = (ptMap.y + 1)* map->getTileSize().height;

		Point ptGL = ptUI;
		ptGL.y = map->getContentSize().height - ptUI.y;
		return ptGL;
	}
	//把GL座標 轉換成layer上的座標,這樣layer層根據座標就可以判斷當前位置的title ID 並進行相關操作
	static Point GL2map(const Point& ptGL, TMXTiledMap* map)
	{
		Point ptUI = ptGL;
		ptUI.y = map->getContentSize().height - ptGL.y;

		int x = ptUI.x / map->getTileSize().width;
		int y = ptUI.y / map->getTileSize().height;
		return ccp(x, y);
	}
	
	static Vector<String*> splitString(const char* srcStr, const char* sSep)
	{
			………………….//截取字符串相關

	}

};


4、角色輪流行走近一步完善:添加變量oneRoundDone,標示一個回合是否結束,false是沒有結束

邏輯同前面文章介紹基本一樣,只不過是新加了個變量oneRoundDone,進行我方角色對話框的特殊處理。

當我方角色走完要求的步數之後,需要判斷停留所在地是否有空地可以購買,有空地就發送消息,彈出對話框提示購買,購買或取消購買完畢後,發送一個MSG_PICKONE_TOGO_TAG ,從角色容器中取出一個角色,進行行走,全部角色行走完畢後,設置oneRoundDone爲true,表示一個回合結束,此時在發送消息,顯示go按鈕,。

 

開始實現我方角色購買地皮的功能

void RicherGameController::endGo()

{

	GameBaseScene::pathMarkVector.at(stepHasGone)->setVisible(false);

	stepHasGone++;

	if(stepHasGone >= stepsCount)
	{
		//角色停留後,判斷如果是我方角色的時候 ,就調用handlePropEvent方法,進行道具事項的處理 
		//這裏的道具暫時是指空地
		if(_richerPlayer->getTag() == PLAYER_1_TAG)
		{			
			handlePropEvent();
			return ;
		}
		// oneRoundDone變量是指:一個回合是否結束。False是沒有結束
		if(!oneRoundDone)
		{
//如果一個回合沒有結束,就調用pickOnePlayerToGo從角色列表中取出一個行走
			pickOnePlayerToGo();
			return;
		}
		return;
	}

	currentRow = nextRow;
	currentCol = nextCol;
	moveOneStep(_richerPlayer);

	log("go end");
	
}

void RicherGameController::handlePropEvent()
{
	oneRoundDone =false;//設置回合變量oneRoundDone
	float playerEnd_X = _colVector[stepsCount]*32; //取得角色所在地點的x座標
 	 float playerEnd_Y = _rowVector[stepsCount]*32 + 32; //取得角色所在地點的y座標

	float** positionAroundEnd; //定義個二維數組,存放角色當前位置的上下左右四個方向上的座標
	positionAroundEnd = new  float*[4];  
	for(int i=0;i<4;i++)
    	positionAroundEnd[i]=new float [2];	

   	 // up
	positionAroundEnd[0][0] = playerEnd_X;
	positionAroundEnd[0][1] = playerEnd_Y + 32;

    	// down
   	 positionAroundEnd[1][0] = playerEnd_X;
    	positionAroundEnd[1][1] = playerEnd_Y - 32;

   	 // left
	positionAroundEnd[2][0] = playerEnd_X - 32;
   	 positionAroundEnd[2][1] = playerEnd_Y;
   
    	// right
	positionAroundEnd[3][0] = playerEnd_X + 32;
  	 positionAroundEnd[3][1] = playerEnd_Y;
	 log("handlePropEvent() called");
	 
//尋找四個相鄰位置 是否存在空地,如果有則發送要求買地的消息MSG_BUY,該消息包含了該空地的座標,這裏主要用到了字符串的操作,
//以“-”做爲字符串分隔符
	for (int i = 0; i < 4; i++) 
	 {
		// GL2map是把當前的座標轉換成landLayer層對應的座標。這部分實現在了Util裏面,不再做解釋了
		 Point ptMap = Util::GL2map(Vec2(positionAroundEnd[i][0],positionAroundEnd[i][1]), GameBaseScene::_map);
		 int titleId = GameBaseScene::landLayer->getTileGIDAt(ptMap);
		 if(titleId == GameBaseScene::blank_land_tiledID)
		 {
			 //send a message to show buy dialog
			 float x = ptMap.x;
			 float y = ptMap.y;
			 String * str = String::createWithFormat("%d-%f-%f",MSG_BUY_BLANK_TAG,x,y);
			  NotificationCenter::getInstance()->postNotification(MSG_BUY,str);
			 break;
		 }
	 }
	 
	
}

在GameBaseScene中註冊了MSG_BUY買地的消息觀察者,當收到該消息後調用receivedNotificationOMsg方法
void GameBaseScene::registerNotificationObserver()
{
	NotificationCenter::getInstance()->addObserver(
		this,
		callfuncO_selector(GameBaseScene::receivedNotificationOMsg),
		MSG_GO,
		NULL);

	NotificationCenter::getInstance()->addObserver(
		this,
		callfuncO_selector(GameBaseScene::receivedNotificationOMsg),
		MSG_BUY,
		NULL);
}

receivedNotificationOMsg 方法,處理所有接收到的消息,然後分別處理


void GameBaseScene::receivedNotificationOMsg(Object* data)
{
//首先對取出消息分割符“-”前的消息類型,並把消息存入容器中messageVector,對於沒有分隔符的則只存放消息類型,
 //對買地消息,還存放了地塊的座標值
	String * srcDate = (String*)data;
	Vector<String*> messageVector = Util::splitString(srcDate->getCString(),"-");

	int retMsgType = messageVector.at(0)->intValue();
	Vector<Node*> vecMenuItem = getMenu()->getChildren();
	log("received go message is: %d",retMsgType);

	switch(retMsgType)
	{
	case MSG_BUY_BLANK_TAG:
		{
			buy_land_x = messageVector.at(1)->floatValue();
			buy_land_y = messageVector.at(2)->floatValue();
			//當收到買地信息後,調用showBuyLandDialog方法,顯示對話框
			showBuyLandDialog(MSG_BUY_BLANK_TAG);
			break;
		}

	case MSG_GO_SHOW_TAG:
		{
			…………………
		}
	case  MSG_GO_HIDE_TAG:
		{
			……………………..
		}


	}
}

void  GameBaseScene::showBuyLandDialog(int landTag)
{
	String showMessage = "";
	switch(landTag)
	{
	
	case MSG_BUY_BLANK_TAG:
		{
			//買空地 顯示的消息
			showMessage = "Do you want to buy the land ? need $1000 ";
			break;
		}
	case MSG_BUY_LAND_1_TAG:
		{
			//給空地升級,顯示的消息
			showMessage = "Do you want to buy the land ? need $2000 ";
			break;
		}
	}
	popDialog->setDataTag(landTag);//給對話框設置一個標示,代表消息類型
	popDialog->getLabelContentText()->setString(showMessage.getCString());//修改對話框提示內容
	popDialog->setVisible(true);//對話框顯示出來

}

//對話框點擊後進入該方法
void GameBaseScene::buyLandCallback(Node *pNode)
{
	if(pNode->getTag() == Btn_OK_TAG)
	{
		switch(popDialog->getDataTag())
		{
			case MSG_BUY_BLANK_TAG:
				{
					//如果點擊的是確認,修改空地圖片爲角色對應的土地標示
					landLayer->setTileGID(player1_building_1_tiledID,ccp(buy_land_x,buy_land_y));
					//landLayer->setTileGID();
					log( "need $1000 ");
					break;
				}
			case MSG_BUY_LAND_1_TAG:
				{
					
					break;
				}
		}
		popDialog->setVisible(false);//購買完畢後,讓對話框消失,併發送消息,讓其他角色行走
		NotificationCenter::getInstance()->postNotification(MSG_PICKONE_TOGO,String::createWithFormat("%d",MSG_PICKONE_TOGO_TAG));
		log("Btn_OK_TAG");
	}else
	{
		//點擊取消,則讓對話框消失,發送消息,讓其他角色行走
		popDialog->setVisible(false);
		NotificationCenter::getInstance()->postNotification(MSG_PICKONE_TOGO,String::createWithFormat("%d",MSG_PICKONE_TOGO_TAG));
	}
	
}

效果如下



點擊下載代碼

http://download.csdn.net/detail/lideguo1979/8312731


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