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
When clicked within range, the rally flag is displayed, and the rally point of the reset soldier tower is the setRallyPoint methodvoid 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); }
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; }
Reproduced at: https://my.oschina.net/wuhaoyu/blog/607814