/* 说明:
**1.本次游戏实例是《cocos2d-x游戏开发之旅》上的最后一个游戏,这里用3.0重写并做下笔记
**2.我也问过木头本人啦。他说:随便写,第一别全然照搬代码;第二能够说明是学习笔记---好人
**3.这里用cocos2d-x 3.0版本号重写,非常多地方不同。可是从重写过程中也非常好的学习了cocos2d-x
*/
***每一步相应的全部代码以及用到的资源都会打包在最后给出
***为避免代码过多,每一步的代码都做了标记--一看就晓得是第几步实现的避免出错改不回去(难不成还用Git?)
***能够依据设计思路(好吧。那名字太高大上。实际就是这一步要干啥)先自己实现---cocos2d-x本来就是如此。同样的功能有很多不同实现方法;先自己折腾是蛮不错的。
***为了方便移植到手机上,对于每一步都进行编译android測试。由于非常多时候代码在win32下能够。编译就会出错,给出的代码会是測试过后的。
本次笔记内容:
1、完毕的效果
2、设计思路
3、依照设计思路看代码
4、下节内容预览
5、本节源代码&资源下载
一:完毕效果
依照前面的设计,我们须要可以添加点在屏幕上,也要能删除已有的点,而且有button控制切换Type,点击屏幕编辑不同的点
能有button控制编辑不同级别关卡的地图,已经输出本关卡内容到文件
效果图:
二:设计思路
1、首先对于屏幕上已有的点,我们要能再次点击能将其删除,那么须要PosBase里面有点击范围推断
2、对于那么多点,我们须要用容器装着。然后能够从容器删除,加入到容器
3、用一个操作层来加入一些button,方便编辑操作
关于操作方法。这里仅仅实现changeMode。然后測试看到结果。其它buttonF5输出调用。方法因为和文件操作有关,留到下次笔记实现
三:依照设计思路看代码
编辑坐标过程中,发现一个点位置放错,那么再点击这个点。让它消失。首先在PosBase里面加入方法:
bool PosBase::isClickMe(Point pos){ //**3**依据posType 设置推断的半径 float radius; if(_posType == enTowerPos){ radius = Tower_Radius; } else{ radius = Monster_Radius; } Point srcPos = Point(_pos.x-radius, _pos.y+radius); Point destPos = Point(_pos.x+radius, _pos.y-radius); if(pos.x >= srcPos.x && pos.x <= destPos.x && pos.y <= srcPos.y && pos.y >= destPos.y){ return true; } return false; }
然后考虑。在PosEditorLayer里面。触摸到一个点的时候,我们调用editPos, 那么这里我们首先须要的是,用一个容器把全部的点保存起来,然后每次 触摸之后,看看这个点是否已经存在。若存在,则删除。不然測创建一个PosBase,增加容器,
方法在PosEditorLayer中加入例如以下
//**3** Vector<PosBase*> m_towerPosList; Vector<PosBase*> m_monsterPosList;
同一时候加入成员函数
void PosEditorLayer::editPos(Point pos){ //**3**改动编辑函数 PosBase* existPos = findExistPos(pos); if(existPos != NULL){ deletePos(existPos); } else{ createPos(pos); } } PosBase* PosEditorLayer::findExistPos(Point pos){ //**3** Vector<PosBase*>posList; if(_posType == enTowerPos){ posList = m_towerPosList; } else{ posList = m_monsterPosList; } for(auto ref : posList){ auto tPos = dynamic_cast<PosBase*>(ref); if(tPos){ if(tPos->isClickMe(pos)){ return tPos; } } } return NULL; } void PosEditorLayer::createPos(Point pos){ //**3** PosBase* tPos = PosBase::create(pos, _posType,true); this->addChild(tPos); if(_posType == enTowerPos){ m_towerPosList.pushBack(tPos); } else{ m_monsterPosList.pushBack(tPos); } } void PosEditorLayer::deletePos(PosBase* existPos){ this->removeChild(existPos); if(_posType == enTowerPos){ m_towerPosList.eraseObject(existPos); } else{ m_monsterPosList.eraseObject(existPos); } }
那么到这里,測试,就能够达到点击屏幕创建任何位置得PosBase对象。 然后不想要的对象,再点击一次就消失
----------------------------------------------------------------------------------------------------------------------
那么到这一步之后。发现,总是在加入删除默认的炮台类的点,想要加入删除怪物的路线点还得改动代码,那么这里就来加入一些操作button
changType:这个button随意切换 _posType 为炮台和怪物的坐标种类;
next Level:编辑下一级的关卡
pre Level:编辑前一关卡
outPut :将本关的 坐标点都输出到文件
好吧,这里採用的方法是。弄一个PosEditorOprLayer层,层里有四个button。 那么这个层保留了PosEditorLayer的引用,四个button相应的功能就有PosEditorLayer 的引用去实现
看看PoaEditorLayer的四个方法:
void PosEditorLayer::changeType(){ CCLOG("change Type"); if(_posType == enTowerPos){ _posType = enMonsterPos; } else{ _posType = enTowerPos; } } void PosEditorLayer::outputPosToPlistFile(){ CCLOG("outputPosToPlistFile"); } void PosEditorLayer::nextLvl(){ CCLOG("edit next level"); } void PosEditorLayer::preLvl(){ CCLOG("edit pre level"); }
然后看看操作层
#include "cocos2d.h" #include "PosEditorLayer.h" #include "cocos-ext.h" USING_NS_CC; USING_NS_CC_EXT; class PosEditorOprLayer : public Layer{ public: PosEditorOprLayer(); ~PosEditorOprLayer(); static PosEditorOprLayer* create(PosEditorLayer* layer); virtual bool init(PosEditorLayer* layer); private: //**3**保留编辑层 PosEditorLayer* _editorLayer; //**3**加入控件 void addWins(); //**3**outPut以及回调函数 void outPutWin(Size visibleSize); void outputPosToPlistFile(Ref* pSender,Control::EventType event); //**3**改变Pos模式控件 void changeTypeWin(Size visibleSize); void changePosType(Ref* pSender,Control::EventType event); //**3**下一关控件 void nextLvlWin(Size visibleSize); void nextLvlToEditor(Ref* pSender,Control::EventType event); //**3**前一关控件 void preLvlWin(Size visibleSize); void pretLvlToEditor(Ref* pSender,Control::EventType event); };
.cpp
PosEditorOprLayer::PosEditorOprLayer(){ _editorLayer = NULL; } PosEditorOprLayer::~PosEditorOprLayer(){ CC_SAFE_RELEASE(_editorLayer); } PosEditorOprLayer* PosEditorOprLayer::create(PosEditorLayer* layer){ PosEditorOprLayer* oprLayer = new PosEditorOprLayer(); if(oprLayer && oprLayer->init(layer)){ oprLayer->autorelease(); } else{ CC_SAFE_DELETE(oprLayer); } return oprLayer; } bool PosEditorOprLayer::init(PosEditorLayer* layer){ if(!Layer::init()){ return false; } CC_SAFE_RETAIN(layer); this->_editorLayer = layer; addWins(); return true; } void PosEditorOprLayer::addWins(){ auto visibleSize = Director::getInstance()->getVisibleSize(); //输出控件 outPutWin(visibleSize); //改变Pos模式控件 changeTypeWin(visibleSize); // nextLvlWin(visibleSize); // preLvlWin(visibleSize); } void PosEditorOprLayer::outPutWin(Size visibleSize){ auto btnTitle = Label::create("output","Arial",30); auto norSprite = Scale9Sprite::create("Button/public_ui_blue_btn.png"); auto highLightSprite = Scale9Sprite::create("Button/public_ui_green_btn.png"); auto outPutBtn = ControlButton::create(btnTitle,norSprite); outPutBtn->setBackgroundSpriteForState(highLightSprite,Control::State::HIGH_LIGHTED); outPutBtn->setPosition( ccp(visibleSize.width-norSprite->getContentSize().width/2, norSprite->getContentSize().height)); outPutBtn->addTargetWithActionForControlEvents( this, cccontrol_selector(PosEditorOprLayer::outputPosToPlistFile), Control::EventType::TOUCH_UP_INSIDE); this->addChild(outPutBtn); } void PosEditorOprLayer::outputPosToPlistFile(Ref* pSender,Control::EventType event){ _editorLayer->outputPosToPlistFile(); }
为了节省篇幅,这里仅仅贴出output button的控件和会滴函数。其它的类似
那么最后再PosEditorScene 里面 把操作层也增加
auto posEditorOprLayer = PosEditorOprLayer::create(posEditorLayer); //依据编辑层来创建 scene->addChild(posEditorOprLayer);
那么測试,点击屏幕,加入炮台,点击chang type button, 之后,在点击屏幕,加入的是怪物的坐标
点击其它button。可F5在输出看到方法调用
四:下节内容预览
那么节实现多Level 的关卡地图编辑,以及和文件打交道,每一关的点坐标都保存到文件。而且对于已保存的文件内容进行改动的话。也须要载入与解析问题
五:代码&资源
-------------------------------
-------------------------------
个人愚昧观点。欢迎指正与讨论