首页 > 代码库 > cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第五步---着手打造游戏界面

cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第五步---着手打造游戏界面

/* 说明:

**1.本次游戏实例是《cocos2d-x游戏开发之旅》上的最后一个游戏,这里用3.0重写并做下笔记

**2.我也问过木头本人啦,他说:随便写,第一别完全照搬代码;第二可以说明是学习笔记---好人大笑

**3.这里用cocos2d-x 3.0版本重写,很多地方不同,但是从重写过程中也很好的学习了cocos2d-x

*/

***每一步对应的所有代码以及用到的资源都会打包在最后给出

***为避免代码过多,每一步的代码都做了标记--一看就晓得是第几步实现的避免出错改不回去(难不成还用Git?)

***可以根据设计思路(好吧,那名字太高大上。实际就是这一步要干啥)先自己实现---cocos2d-x本来就是如此,相同的功能有许多不同实现方法;先自己折腾是蛮不错的。

***为了方便移植到手机上,对于每一步都进行编译android测试;因为很多时候代码在win32下可以,编译就会出错,给出的代码会是测试过后的。

本次笔记内容:

1、设计思路

2、代码&效果图

3、下次内容预览

4、本次源码&资源下载

一:设计思路:

1、着手打造游戏Scene,Scene中可以添加GetBackLayer

2、根据最开始的总设计流程图,需要一个最重要的游戏Layer,然后添加英雄和怪物的管理器,这里只弄英雄管理器---也比较复杂

3、英雄管理器继承自Layer?这一步中,我们对应当前级别,加载我们编好的TowerPos,TowerPos是通过精灵展示的炮台,我们要点击炮台能添加英雄在上面,因此,需要触摸机制

4、内容页比较多啦......

二:代码&效果图

完成了编辑工作之后,就要来正式开始游戏界面啦;GameScene,单独抽离出来,先添加GetBackLayer;其中,GameScene是根据关卡选择时候的级别来createScene的

class GameScene{
public:
	static Scene* createScene(int level);
};
.cpp

Scene* GameScene::createScene(int level){
	Scene* scene = NULL;

	scene = Scene::create();

	auto getBackLayer = GetBackLayer::create();
	scene->addChild(getBackLayer);

	return scene;
}
那么可以在GameLvlChoose里面的回调函数中,进行场景切换

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

此时,就来准备最后一个Layer,也是游戏中最重要的MapLayer;设计思路中,MapLayer带着两个son,那就是英雄管理器,和怪物管理器;

整个游戏就是如此层次分离开来;也是便于扩展;不禁感叹:木头主程不是盖的!!!
MapLayer.h

class MapLayer : public Layer{
public:
	MapLayer(); ~MapLayer();

	static MapLayer* create(int level);
	bool init(int level);

private:
	//**5**
	int _curLevel;

	//**5**加载等级地图
	void preLoad();

};
.cpp

MapLayer::MapLayer(){
	_curLevel = 1;
}
MapLayer::~MapLayer(){
}

MapLayer* MapLayer::create(int level){
	MapLayer* mapLayer = new MapLayer();
	if(mapLayer && mapLayer->init(level)){
		mapLayer->autorelease();
	}
	else{
		CC_SAFE_DELETE(mapLayer);
	}
	return mapLayer;
}

bool MapLayer::init(int level){
	_curLevel = level;

	preLoad();

	return true;
}

void MapLayer::preLoad(){
	auto visibleSize = Director::getInstance()->getVisibleSize();

	//add map
	__String* sBG = __String::createWithFormat("game/level_%d.jpg",_curLevel);
	Sprite* map = Sprite::create(sBG->getCString());

	map->setPosition(ccp(visibleSize.width/2,visibleSize.height/2));
	this->addChild(map);
}
然后在GameScene中添加:

auto mapLayer = MapLayer::create(level);
mapLayer->setTag(Tag_Map); 
scene->addChild(mapLayer);
为了不把Back按钮挡住,应该在GetBackLayer之前加入,然后Tag_Map是一个宏定义的Tag,后面会用到,至于宏定义值,随便取也没关系

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

这里先撇开怪物不说,先看看英雄管理器。HeroManager;首先注意的是,这个管理器是继承自Layer的,为什么呢?

HeroManager的功能:它会按照当前级别,加载我们事先编好的TowerPos--也就是炮台坐标,然后,对于这些坐标,我们会用一个炮台精灵来展示;我们炮台的目的就是:让你点击炮台之后能添加英雄;那么需要触摸机制,所以这里用继承自Layer的管理器

上马:.h

class HeroManager : public Layer{
public:
	HeroManager(); ~HeroManager();
	static HeroManager* createWithLevel(int curLevel);
	bool initWithLevel(int curLevel);
private:
	//**5**
	Vector<PosBase*> m_towerPosList;

	//--------------------------------------------------
	//**5**
	void createTowerPos(int curLevel);

};
.cpp

HeroManager::HeroManager(){
}
HeroManager::~HeroManager(){
}

HeroManager* HeroManager::createWithLevel(int curLevel){
	HeroManager* heroMgr = new HeroManager();
	if(heroMgr && heroMgr->initWithLevel(curLevel)){
		heroMgr->autorelease();
	}
	else{
		CC_SAFE_DELETE(heroMgr);
	}
	return heroMgr;
}

bool HeroManager::initWithLevel(int curLevel){
	//**5**
	createTowerPos(curLevel);
	
	//-------------------触摸事件-------------------------------
	auto listener = EventListenerTouchOneByOne::create();
	listener->setSwallowTouches(true);

	listener->onTouchBegan = [](Touch* touch,Event* event){
		return true;
	};
	
	listener->onTouchMoved = [](Touch* touch,Event* event){
	};

	listener->onTouchEnded = [=](Touch* touch,Event* event){
		auto touchPos = touch->getLocationInView();
		auto pos = Director::getInstance()->convertToUI(touchPos);

		CCLOG("touch pos.x is %f, pos.y is %f!",pos.x, pos.y);
	};

	_eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this);

	//------------------------------------------------------------

	return true;
}

void HeroManager::createTowerPos(int curLevel){
	//**5**
	__String* towerPosPath = __String::createWithFormat("game/towerPos_Level_%d.plist",curLevel);

	PosLoadUtil::getInstance()->loadPosWithFile(m_towerPosList,enTowerPos,
		towerPosPath->getCString(),this,1,false);//----可以改为true
}
那么这里只完成了加载坐标点;是看不到什么效果的;??没什么没有炮台精灵?

炮台并不是单单用精灵来展示这么简单。。。这个后面解决

那么这里,为了看到点效果,管理器中的createTowerPos函数中,把加载中的调试参数改为 true,然后在MapLayer中的加载地图中,把地图设置透明度;

然后给MapLayer 一个HeroManager* _heroMgr;成员,在init 函数中:

preLoad();
	
_heroMgr = HeroManager::createWithLevel(_curLevel);
this->addChild(_heroMgr);
那么运行结果图:



三:下次内容

只有点算什么回事?通过精灵展示的炮台呢?点击炮台怎么添加英雄?

四:源码&资源

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

源码&资源

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

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



cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第五步---着手打造游戏界面