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

五:代码&资源

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

资源&代码

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

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

时间: 2024-11-09 19:24:43

cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第三步---编辑器(2)---更方便很多其它操作更像编辑器的相关文章

cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第一步---开始界面&amp;关卡选择

/* 说明: **1.本次游戏实例是<cocos2d-x游戏开发之旅>上的最后一个游戏,这里用3.0重写并做下笔记 **2.我也问过木头本人啦,他说:随便写,第一别完全照搬代码:第二可以说明是学习笔记---好人 **3.这里用cocos2d-x 3.0版本重写,很多地方不同,但是从重写过程中也很好的学习了cocos2d-x */ ***每一步对应的所有代码以及用到的资源都会打包在最后给出 ***为避免代码过多,每一步的代码都做了标记--一看就晓得是第几步实现的避免出错改不回去(难不成还用Git

cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第一步---開始界面&amp;amp;关卡选择

/* 说明: **1.本次游戏实例是<cocos2d-x游戏开发之旅>上的最后一个游戏,这里用3.0重写并做下笔记 **2.我也问过木头本人啦.他说:随便写,第一别全然照搬代码:第二能够说明是学习笔记---好人 **3.这里用cocos2d-x 3.0版本号重写,非常多地方不同.可是从重写过程中也非常好的学习了cocos2d-x */ ***每一步相应的全部代码以及用到的资源都会打包在最后给出 ***为避免代码过多.每一步的代码都做了标记--一看就晓得是第几步实现的避免出错改不回去(难不成还用

cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第九步---英雄发动攻击

/* 说明: **1.本次游戏实例是<cocos2d-x游戏开发之旅>上的最后一个游戏,这里用3.0重写并做下笔记 **2.我也问过木头本人啦,他说:随便写,第一别完全照搬代码:第二可以说明是学习笔记---好人 **3.这里用cocos2d-x 3.0版本重写,很多地方不同,但是从重写过程中也很好的学习了cocos2d-x */ ***每一步对应的所有代码以及用到的资源都会打包在最后给出 ***为避免代码过多,每一步的代码都做了标记--一看就晓得是第几步实现的避免出错改不回去(难不成还用Git

cocos2d-x 3.0游戏实例学习笔记 《卡牌塔防》第0步---知识点总结&amp;效果预览

/* 说明: **1.本次游戏实例是<cocos2d-x游戏开发之旅>上的最后一个游戏,这里用3.0重写并做下笔记 **2.我也问过木头本人啦,他说:随便写,第一别完全照搬代码:第二可以说明是学习笔记 **3.这里用cocos2d-x 3.0版本重写,很多地方不同,但是从重写过程中也很好的学习了cocos2d-x */ 环境:Win7 .cocos2d-x 3.0final .C++ .VS2012 笔记思路:后面就按这种思路写笔记啦 1.首先给出每次实现的效果截图 2.然后给出设计思路 3.

cocos2d-x 3.0游戏实例学习笔记 《跑酷》移植到android手机

说明:这里是借鉴:晓风残月前辈的博客,他是将泰然网的跑酷教程,用cocos2d-x 2.X 版本重写的,目前我正在学习cocos2d-X3.0 于是就用cocos2d-X 3.0重写,并做相关笔记 好吧,自从上次<跑酷>完结之后,就什么没做什么的,主要是修复了一点点bug ,也在相应的文章里面做出了相应的改动.不过,只能在window上看着玩又有什么太大意思呢!!!于是乎又尝试着弄到手机上试试--OK,初生牛犊不要脸,哦不!不怕喷.这里记录一下我的移植过程.(这里会用到新的大小的资源.待会也会

cocos2d-x 3.0游戏实例学习笔记 《跑酷》一 开始界面

开始界面和前辈的基本上差不多:cocos2d-x游戏开发 跑酷(一)开始界面     但是也有不同 下面先给出游戏过程中用到的所有资源 开始界面定义为:MainScene 有如下功能: 1.背景 2.进入游戏界面按钮 3.预先加载背景音乐文件 .h文件 #ifndef __MainScene__H__ #define __MainScene__H__ #include "cocos2d.h" class MainScene : cocos2d::Layer{ public: virtu

cocos2d-x 3.0游戏实例学习笔记 《跑酷》第六步--物理碰撞检测(1)

说明:这里是借鉴:晓风残月前辈的博客,他是将泰然网的跑酷教程,用cocos2d-x 2.X 版本重写的,目前我正在学习cocos2d-X3.0 于是就用cocos2d-X 3.0重写,并做相关笔记 那么这一步,我们先不急着给主角和金币岩石碰撞检测,我这里把cocos2d-x 3.0 的物理碰撞检测单独抽取出来,之前看了cocos的官网,有一个教程:用新物理引擎完成碰撞检测,就是一个车和猫的碰撞检测,车撞倒猫,猫就消失.我之前也单独试了下.但是那个教程的代码好像完整性不好,不能运行...于是我又借

coco2d-x 3.0游戏实例学习笔记 《跑酷》 二 游戏界面--全新的3.0物理世界

从这里开始,就和之前前辈的有很多不同啦. 在MainScene中,开始按钮中,我们就要通过回调函数,进入到我们的游戏场景啦. 那么在游戏场景中我们定义为:PlayScene ,而且是一个带物理世界的场景,cocos2d-x 3.0中要创建物理Scene是很简单的,因为它都帮我们封装好了. 那么这一步,我们在PlayScene 中主要完成以下功能: 1.物理世界创建 2.创建一个地面的物理刚体 相关知识个人见解: 所谓的创建物理世界,个人觉得是一个抽象的东东,作为新手,开始并不能理解,开始你可以就

cocos2d-x 3.0游戏实例学习笔记 《跑酷》第四步--地图循环&amp;主角添加动作

这一步当中,我们主要完成以下功能: 1.地图的无限滚动---让主角看起来真的是在跑动 2.给主角添加Jump跳跃和crouch下蹲动作 那么首先来让背景滚动起来,在PlayScene.h中添加: //初始化背景 void initBG(); //用update函数让地图滚动 virtual void update(float dt); //背景精灵 cocos2d::Sprite* bgSprite1; cocos2d::Sprite* bgSprite2; cocos2d::Sprite* g

cocos2d-x 3.0游戏实例学习笔记 《跑酷》 第三步---主角开跑&amp;同时带着刚体

在这一步,我们主要是把主角加入到游戏场景中来,并且让它跑动,这里的跑动,实际上也就是执行一组动画,让其看起来像是在跑动,而且相对屏幕的位置也不会改变 我们会定义一个主角类:Runner,而这一步就要用到 帧动画 的创建和使用等知识点. 对于Runner,我的设计思路如下: 1.主角有一个动作集合,包括跑动,跳起来,以及蹲下.那么就有不同的帧动画,那么这里借鉴到 晓风残月前辈的方法,将帧动画打包命名,之后根据动作名来执行动作 2.主角需要绑定刚体,并且在不同的动作下的刚体大小不同 3.我们给主角设