zoukankan      html  css  js  c++  java
  • cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第三步---编辑器(2)---更方便很多其它操作更像编辑器

    /* 说明:

    **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 的关卡地图编辑,以及和文件打交道,每一关的点坐标都保存到文件。而且对于已保存的文件内容进行改动的话。也须要载入与解析问题

    五:代码&资源

    -------------------------------

    资源&代码

    -------------------------------

    个人愚昧观点。欢迎指正与讨论

  • 相关阅读:
    Web-js中级-11月13日
    Web-js中级-11月12日
    Web-js中级-11月9日
    Web-js中级-11月8日
    Web-js中级-11月7日
    django中自定义了manager函数,使用的时候报错AttributeError: 'Manager' object has no attribute 'title_count'
    django模型篇:一对一、一对多、多对多,添加,批量插入和查询操作
    from django.core.context_processors import crsf报错
    python报错:Exception Value:can only concatenate str (not "bytes") to str
    使用tkinter设计一个简单的加法计算器
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/6740005.html
Copyright © 2011-2022 走看看