[Cocos2d Tower Defense Game Development] Cocos2dx-3.X completes the Tower Defense Game Kingdom Defense War--Barrack Tower of Defense Tower...

Original Link: https://my.oschina.net/wuhaoyu/blog/607814

This chapter mainly introduces the barrack tower

Barrack towers can produce three soldiers, and they can set up a rally point where the enemy passes, and the soldiers will stop and fight against the enemy.Every N seconds, replies to the soldier's blood volume, can be upgraded, there are more troops.


When compared to other defence towers, the barrack towers are built, that is, three soldiers are created after the buildingSmokeAnimation in the previous chapter is executed, and the soldiers are set up to assemble, and the soldiers walk to the assemble point by themselves.

setRallyPoint is a reset of the assembly point, and the soldier stops everything and goes to the new assembly point (runToLocation() method).

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 dts) are set to treat a soldier every dt, and automatically create a new soldier if there are dead soldiers.
void BaseBarracksTower::cureSoldiers(float dt)
{
	for(int i = 0;i<Soldiers.size();i++)//Traverse Soldiers
	{
		auto Soldier = Soldiers.at(i);
		if(Soldier->getState() == SoldierStateWait){//If the soldier is not in an attacking state
			Soldier->setCurrHp(Soldier->getMaxHp());//Reply to Soldier's All Blood Volumes
			Soldier->setHpPercentage(100);
			Soldier->getHpBar()->setPercentage(100);
		}
		else if(Soldier->getState() == SoldierStateDeath){//If any soldier dies
			if(level <= 3){
				SoundManager::playBarrackOpendoor();//Play barracks opening sounds and animations
				door->runAction(Animate::create(AnimationCache::getInstance()->getAnimation(String::createWithFormat("level%d_barracks_ope                                       ndoor",getLevel())->getCString())));
				auto point = Soldier->getLocation();
				Soldier ->removeFromParent();
				Soldier = NULL;//Remove dead soldiers
				auto newSoldier = BarrackSoldier::createSoldier(point,level);//Create a new soldier
				Soldiers.replace(i,newSoldier);//Update Soldier Queue
				addChild(newSoldier);
			}//Omit...
         }
}

The main work of the soldier tower is among the soldiers. The soldier tower is only responsible for updating the soldiers according to their status.


The upgrade interface for the Soldier Tower is slightly different, with an additional flag to set the assembly point, and the code section is in 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();
	};

When the flag is clicked, clear the upgrade menu, notify TouchLayer to display the cluster range, and create a listening event

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);
}
When clicked within range, the rally flag is displayed, and the rally point of the reset soldier tower is the setRallyPoint method

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;
}


That is the basic implementation of the Soldier Tower.


Reproduced at: https://my.oschina.net/wuhaoyu/blog/607814

Added by uglyrat on Fri, 13 Sep 2019 00:52:21 +0300