该张补充如何建造防御塔
首先是,点击该图标,会弹出上面那张GIF的建造选项。
具体代码在Terrain(名字是根据资源包图片名起的)中,首先根据每一个地图算好坐标,在地图添加到场景后执行addTerrains()添加到地图层中。在Terrain的Init函数中根据地图类型选择图片生成精灵,并添加触摸监听。
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = CC_CALLBACK_2(Terrain::onTouchBegan,this);
listener->onTouchEnded = CC_CALLBACK_2(Terrain::onTouchEnded,this);
_eventDispatcher->addEventListenerWithSceneGraPHPriority(listener,terrain);
在onTouchEnded中判断
void Terrain::onTouchEnded(Touch* touch,Event* event) { auto target = static_cast<Sprite*>(event->getCurrentTarget()); Point locationInNode = target->convertTouchToNodeSpace(touch); Size size = target->getContentSize(); Rect rect = Rect(0,size.width,size.height); if (rect.containsPoint(locationInNode)&&target->isVisible())//若点击在该区域,且可见(可见是因为若防御塔建造了,就不可以了,就不会执行下面代码) { if(isUpdateMenuShown)//如果已经显示,则隐藏 { hideUpdateMenu(); }else{ showUpdateMenu(); } }else{//若点击其他区域,隐藏 hideUpdateMenu(); } }
在showUpdateMenu()添加建造菜单层
void Terrain::showUpdateMenu() { auto towerPanleLayer = TowerPanleLayer::create(); towerPanleLayer->setPosition(this->getPosition()); towerPanleLayer->setTag(getTag()); towerPanleLayer->setMyTerrain(this); static_cast<BaseMap*>(this->getParent())->mTouchLayer->addChild(towerPanleLayer); towerPanleLayer->inAnimation(); isUpdateMenuShown = true; }
TowerPanleLayer是自定义Layer
bool TowerPanleLayer::init() { if ( !Sprite::init() ) { return false; } circle = Circle::create(); addChild(circle); circle->setVisible(false); planesprite = Sprite::createWithSpriteFrameName("gui_ring.png"); planesprite->setPosition(Point(0,0)); planesprite->setScale(0.5f); addChild(planesprite); isBuilt = false; return true; }其中Circle是自定义精灵,根据射程显示防御塔攻击范围,不做详细介绍了,planesprite是那个铁环
首先通过this->getPosition()获取位置,将它添加在触摸层中,执行从小变大的动画。
void TowerPanleLayer::inAnimation() { SoundManager::playTowerMenu(); planesprite->runAction(Sequence::create(ScaleTo::create(0.1f,1.0f,1.0f),CallFuncN::create(CC_CALLBACK_0(TowerPanleLayer::addIcons,this)),NULL)); }动画执行完毕后,添加4个按键,4个按键是自定义精灵类,具体参见代码,给4个按键添加触摸监听,在触摸开始时:
bool TowerPanleLayer::onTouchBegan(Touch *touch,Event *event) { auto target = static_cast<BaseBuildIcon*>(event->getCurrentTarget()); Point locationInNode = target->convertTouchToNodeSpace(touch); Size size = target->baseIcon->getContentSize(); Rect rect = Rect(0-size.width/2,0-size.height/2,size.height); if (rect.containsPoint(locationInNode)) { if(target->getIsSelected())//如果已经选中(第二次按下) { if(target->getIsAble())//如果钱够用 { int i = target->getType(); addTower(target->getType()); } }else{//第一次按下 archerIcon->setNotSelected(); artilleryIcon->setNotSelected(); barracksIcon->setNotSelected(); magicIcon->setNotSelected(); target->setSelected();//设置为选中状态 addTempTower(target->getType()); } return true; } return false; }
其中addTempTower()是添加临时防御塔,即第一张图的效果,当点击第二次,通过addTower()建造防御塔
void TowerPanleLayer::addTempTower(int type) { if(tempTower!=NULL){ removeChild(tempTower,true);//首先上一个临时塔移除 } circle->setVisible(true);//显示防御塔攻击范围 switch (type) { case(1):{//根据点击类型显示 tempTower = Sprite::createWithSpriteFrameName("tower_preview_archer.png"); tempTower->setPosition(Point(0,25)); static_cast<BaseMap*>(this->getParent()->getParent())->playerState->showTowerInfo(ARCHER_1);}//在菜单层显示防御塔信息 break; .......... }addTower中建造防御塔
void TowerPanleLayer::addTower(int type) { static_cast<BaseMap*>(this->getParent()->getParent())->playerState->removeTowerInfo();//移除防御塔信息 switch (type) { case(2):{//根据选择类型建造 auto barracksTower = BaseBarracksTower::create(); barracksTower->setPosition(Point(0,20)); barracksTower->setTag(terrain->getTag()); barracksTower->setMyTerrain(terrain);//设置塔所属的terrain,防御塔售出时将此设置可见。 terrain->addChild(barracksTower); barracksTower->buildingAnimation(); GameManager::getInstance()->MONEY = GameManager::getInstance()->MONEY - barracksTower->getBuildMoney(); } break; .........省略 } SoundManager::playTowerBuilding();//播放建造音效 isBuilt = true; terrain->terrain->setVisible(false);//将terrain设置不可见,再点击即不会再显示了 this->setVisible(false); }另外,防御塔升级的界面类似建造,就不一一介绍了,升级即将上一个塔remove掉,新建一个新的。卖塔的过程即将防御塔remove掉,并且将terrain设置为可见