[Cocos2d塔防遊戲開發]Cocos2dx-3.X完成塔防遊戲《王國保衛戰》--防禦塔(六)之兵營塔

該章節主要介紹兵營塔

兵營塔可以產生三個士兵,可以設置士兵集結點,當週圍有敵人通過時,士兵會攔下敵人,並與敵人進行搏鬥。每隔N秒,會回覆士兵血量,可以升級,有更多的兵種。


去其他防禦塔相比,兵營塔在建造完畢,即上一章節中的buildingSmokeAnimation執行完畢後創建3個士兵,給士兵設置集結點,由士兵自行走到集結點。

setRallyPoint是重新設置集結點,士兵會停止一切動作,走到新的集結點(runToLocation()方法)。

void BaseBarracksTower::setRallyPoint(Point point)
{
	auto rally = point - this->getParent()->getPosition();

	Soldiers.at(0)->setLocation(Point(rally.x + 20,rally.y - 20));
	Soldiers.at(1)->setLocation(Point(rally.x - 20,rally.y - 20));
	Soldiers.at(2)->setLocation(Point(rally.x ,rally.y + 20));

	for(int i = 0; i< Soldiers.size()&& Soldiers.at(i)!=NULL && Soldiers.at(i)->getState()!=SoldierStateDeath;i++)
	{
	    if(Soldiers.at(i)->nearestMonster!=NULL && Soldiers.at(i)->nearestMonster->getState()!=stateDeath)
		Soldiers.at(i)->nearestMonster->restartWalking();			
	    Soldiers.at(i)->runToLocation(Soldiers.at(i)->getLocation());
	}
}

cureSoldiers(float dt)是設置在每隔dt時間,對士兵進行一次治療,若有死掉的士兵,自動製造一名新的士兵。
void BaseBarracksTower::cureSoldiers(float dt)
{
	for(int i = 0;i<Soldiers.size();i++)//遍歷士兵
	{
		auto Soldier = Soldiers.at(i);
		if(Soldier->getState() == SoldierStateWait){//若士兵沒有處於攻擊狀態
			Soldier->setCurrHp(Soldier->getMaxHp());//回覆士兵所有血量
			Soldier->setHpPercentage(100);
			Soldier->getHpBar()->setPercentage(100);
		}
		else if(Soldier->getState() == SoldierStateDeath){//若有士兵死亡
			if(level <= 3){
				SoundManager::playBarrackOpendoor();//播放兵營開門聲音以及動畫
				door->runAction(Animate::create(AnimationCache::getInstance()->getAnimation(String::createWithFormat("level%d_barracks_ope                                       ndoor",getLevel())->getCString())));
				auto point = Soldier->getLocation();
				Soldier ->removeFromParent();
				Soldier = NULL;//將死亡的士兵清除
				auto newSoldier = BarrackSoldier::createSoldier(point,level);//創建新的士兵
				Soldiers.replace(i,newSoldier);//更新士兵隊列
				addChild(newSoldier);
			}//省略。。。。。
         }
}

士兵塔主要工作都放在士兵類當中,士兵塔只負責根據士兵的狀態更新士兵


士兵塔的升級界面略有不同,多了一個旗幟用於設置集結點,代碼部分在UpdatePanleLayerWithFlag中

        auto flaglistener = EventListenerTouchOneByOne::create();
	flaglistener->onTouchBegan = [&](Touch* touch, Event* event){
		
		auto target = static_cast<Sprite*>(event->getCurrentTarget());

		Point locationInNode = target->convertTouchToNodeSpace(touch);

		Size size = target->getContentSize();
		Rect rect = Rect(0, 0, size.width, size.height);
		if (rect.containsPoint(locationInNode))
		{  	
			return true;  
		}  
		return false;
	};
	flaglistener->onTouchEnded = [&](Touch* touch, Event* event){
		static_cast<TouchLayer*>(this->getParent())->tower = this->getTower();
		static_cast<TouchLayer*>(this->getParent())->setRallyFlagTouchShield();
		tower->isUpdateMenuShown = false;
		this->removeFromParent();
	};

當點擊旗幟後,清除升級菜單,通知TouchLayer顯示集結點範圍,並且創建監聽事件

void TouchLayer::setRallyFlagTouchShield()
{
	rallyCircle = RallyCircle::create();
	rallyCircle->setPosition(tower->getParent()->getPosition());
	rallyCircle->setTag(1001);
	addChild(rallyCircle);
	listener = EventListenerTouchOneByOne::create();
	listener->onTouchBegan = CC_CALLBACK_2(TouchLayer::onRallyFlagTouchBegan, this);
	listener->onTouchEnded = CC_CALLBACK_2(TouchLayer::onRallyFlagTouchEnded, this);
	listener->setSwallowTouches(true);
	_eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this);
}
當點擊在範圍內,顯示集結點旗幟,重設士兵塔的集結點即setRallyPoint方法

bool TouchLayer::onRallyFlagTouchBegan(Touch* touch, Event* event)
{
	auto target = static_cast<TouchLayer*>(event->getCurrentTarget());
	Point locationInNode = target->convertTouchToNodeSpace(touch);
	if(locationInNode.distance(tower->getParent()->getPosition())<160 && locationInNode.distance(tower->getParent()->getPosition())>80){
		addRallyFlag(locationInNode);
		tower->setRallyPoint(locationInNode);
		SoundManager::playRallyPointPlaced();
		isFlag = true;
	}else{
		addWrongPlace(static_cast<TouchLayer*>(event->getCurrentTarget())->convertTouchToNodeSpace(touch));
	}
	return true;
}


以上即士兵塔基本實現方法。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章