cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第六步---炮台&点击炮台添加英雄&英雄升级
来源:互联网 发布:在vb集成环境中要添加 编辑:程序博客网 时间:2024/05/16 01:08
/* 说明:
**1.本次游戏实例是《cocos2d-x游戏开发之旅》上的最后一个游戏,这里用3.0重写并做下笔记
**2.我也问过木头本人啦,他说:随便写,第一别完全照搬代码;第二可以说明是学习笔记---好人
**3.这里用cocos2d-x 3.0版本重写,很多地方不同,但是从重写过程中也很好的学习了cocos2d-x
*/
***每一步对应的所有代码以及用到的资源都会打包在最后给出
***为避免代码过多,每一步的代码都做了标记--一看就晓得是第几步实现的避免出错改不回去(难不成还用Git?)
***可以根据设计思路(好吧,那名字太高大上。实际就是这一步要干啥)先自己实现---cocos2d-x本来就是如此,相同的功能有许多不同实现方法;先自己折腾是蛮不错的。
***为了方便移植到手机上,对于每一步都进行编译android测试;因为很多时候代码在win32下可以,编译就会出错,给出的代码会是测试过后的。
本次笔记内容:
1、设计思路
2、代码&测试效果
3、下次内容预览
4、本次源码&资源
一:设计思路
在前一步中,进入不同级别的游戏关卡之后,加载了之前自己编辑好的炮台的点
这一步中为这些点用真正的炮台来展示
然后点击炮台能添加英雄
1.首先为了后面的扩展,炮台也是应该有属性的,比如等级什么的。那么英雄和怪物同样也是,速度,防御等各种属性。那么可以抽离出一个基类Entity
2.这一步当中是关于炮台和英雄的 关系,那么首先来设计炮台;炮台继承实体,它通过精灵来展示,并且执行了一个动作---看起来高大上
3.那么在英雄管理器中,前面加载的点保存在容器里面啦,我们对容器遍历,对于每个炮台坐标放一个炮台
4.然后是英雄,这一步中,我们只实现点击炮台产生英雄,英雄的属性和配置文件Csv有关之后说
5.添加英雄之后,我们再次点击英雄,可以有一些操作,升级!删除!
二:代码&效果
首先看看基类:.h
<span style="font-size:14px;">class Entity : public Node{public:Entity();~Entity();void bindSprite(Sprite* sprite);Sprite* getSprite();void hurtMe(int hurtValue);bool isDead();Rect boundingBox();protected:virtual void onDead();virtual void onBindSprite();virtual void onHurt(int hurtValue);private:Sprite* _sprite;bool _isDead;CC_SYNTHESIZE(int,_id,ID);CC_SYNTHESIZE(int,_modeID,ModeID);CC_SYNTHESIZE(__String*,_Name,Name);CC_SYNTHESIZE(int,_hp,HP);CC_SYNTHESIZE(int,_defense,Defense);CC_SYNTHESIZE(int,_speed,Speed);CC_SYNTHESIZE(int,_level,Level);};</span>.cpp
<span style="font-size:14px;">Entity::Entity(){_sprite = NULL;_Name = __String::create("");_hp = 1;_defense = 1;_isDead = false;_speed = 1;_level = 1;}Entity::~Entity(){}void Entity::bindSprite(Sprite* sprite){if(this->_sprite != NULL){_sprite->removeFromParentAndCleanup(true);}this->_sprite = sprite;this->addChild(_sprite);//**6**如果子类绑定时需要其他作用,就重写下面的函数onBindSprite();}Sprite* Entity::getSprite(){return this->_sprite;}void Entity::hurtMe(int hurtValue){if(_isDead){return ;}if(hurtValue <= getDefense()){hurtValue = 1;}int curHP = getHP();int afterHP = curHP-hurtValue;onHurt(hurtValue);if(afterHP > 0){setHP(afterHP);}else{_isDead = true;onDead();}}Rect Entity::boundingBox(){Node::boundingBox();if(getSprite() == NULL){return CCRectMake(0,0,0,0);}Point pos = getPosition();Size size = getSprite()->getContentSize();return CCRectMake(pos.x,pos.y,size.width,size.height);}bool Entity::isDead(){return this->_isDead;}//空函数,留给子类void Entity::onDead(){}void Entity::onBindSprite(){}void Entity::onHurt(int hurtValue){}</span>可以看到它是有一些的属性,也有受伤、死亡、精灵什么的函数;后面对于不同的实体实现不同的功能
炮台TowerBorder.h
<span style="font-size:14px;">class TowerBorder : public Entity{public:TowerBorder(); ~TowerBorder();CREATE_FUNC(TowerBorder);virtual bool init(); bool isClickMe(Point pos);//检测是否点击了炮台private:};</span>.cpp
<span style="font-size:14px;">TowerBorder::TowerBorder(){}TowerBorder::~TowerBorder(){}bool TowerBorder::init(){__String* sFilePath = __String::createWithFormat("sprite/hero/border_%d.png",_level);Sprite* sprite = Sprite::create(sFilePath->getCString());bindSprite(sprite);ActionInterval* rotateBy = RotateBy::create(25.0f,360,360);auto repeat = RepeatForever::create(rotateBy);sFilePath = __String::createWithFormat("sprite/hero/magic_border_%d.png",_level);sprite = Sprite::create(sFilePath->getCString());sprite->setOpacity(80);sprite->runAction(repeat);this->addChild(sprite);return true;}bool TowerBorder::isClickMe(Point pos){Size size = getSprite()->getContentSize();Point borderPos = getPosition();Point srcPos = Point(borderPos.x-size.width,borderPos.y+size.height);Point detPos = Point(borderPos.x+size.width,borderPos.y-size.height);if(pos.x>=srcPos.x && pos.x<=detPos.x && pos.y<=srcPos.y && pos.y>=detPos.y){return true;}return false;}</span>然后测试一下:在HeroManager里面添加成员:
<span style="font-size:14px;">Vector<TowerBorder*> m_towerBorderList;void createTowerBorder();</span>那么在createTowerPos之后,我们调用createTowerBorder,也就是通过点来添加炮台
<span style="font-size:14px;">void HeroManager::createTowerPos(int curLevel){/******************省略代码***************///**6** 加载完所有的点,那么就用点来添加炮台createTowerBorder();}void HeroManager::createTowerBorder(){PosBase* tPos = NULL;for(auto ref : m_towerPosList){tPos = dynamic_cast<PosBase*>(ref);if(tPos != NULL){TowerBorder* border = TowerBorder::create();border->setPosition(tPos->getPos());this->addChild(border);m_towerBorderList.pushBack(border);}}}</span>把之前为了看到点坐标的 调式模式改为false,背景图片不设计透明度。运行测试如下:
接着,实现点击炮台添加英雄,先看看英雄
<span style="font-size:14px;">class Hero : public Entity{public:Hero(); ~Hero();static Hero* createFromCsvFileByID(int heroID);bool initFromCsvFileByID(int heroID);};</span>这里是根据ID来添加,也就是说有不同种类的英雄。但是本游戏只有一种---这里理解了也可以自己扩展
<span style="font-size:14px;">Hero::Hero(){}Hero::~Hero(){}Hero* Hero::createFromCsvFileByID(int heroID){Hero* hero = new Hero();if(hero && hero->initFromCsvFileByID(heroID)){hero->autorelease();}else{CC_SAFE_DELETE(hero);}return hero;}bool Hero::initFromCsvFileByID(int heroID){Sprite* sprite = Sprite::create(__String::createWithFormat("sprite/hero/hero_%d.png",heroID)->getCString());bindSprite(sprite);return true;}</span>那么我们理解添加英雄的过程:点击任意炮台,然后添加。但是,我们需要解决点击了那个炮台?
HeroManager里添加函数:
<span style="font-size:14px;">TowerBorder* findClickTowerBorder(Point pos){TowerBorder* tBorder = NULL;for(auto ref : m_towerBorderList){tBorder = dynamic_cast<TowerBorder*>(ref);if(tBorder){if(tBorder->isClickMe(pos)){return tBorder;}}}return NULL;}</span>同时,一个炮台只有一个英雄,那么TowerBorder里面添加:
<span style="font-size:14px;">Hero* _hero;TowerBorder::TowerBorder(){_hero = NULL;}TowerBorder::~TowerBorder(){CC_SAFE_RELEASE(_hero);}Hero* getHero(){ return _hero;};void bindHero(Hero* hero){ _hero = hero; };</span>那么,在管理器的触摸事件的end函数中:
<span style="font-size:14px;">bool HeroManager::initWithLevel(int curLevel){/*****************省略***************/listener->onTouchEnded = [=](Touch* touch,Event* event){/*****************省略**************/TowerBorder* clickBorder = findClickTowerBorder(pos);if(clickBorder == NULL){return ;}if(clickBorder->getHero() == NULL){Hero* hero = Hero::createFromCsvFileByID(1);hero->setPosition(clickBorder->getPosition());this->addChild(hero);clickBorder->bindHero(hero);}}; /*************省略*************************************/}</span>那么测试,点击炮台添加英雄,效果如下:
三:下节预览
看看Csv中的英雄属性如何加到英雄身上---读取Csv&解析Csv文件,给英雄添加更多操作,让它升级,不想要了把它从炮台删除
--------------------------------
四:源码&资源
-----------------------------------
个人愚昧观点,欢迎指正与讨论
- cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第六步---炮台&点击炮台添加英雄&英雄升级
- cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第七步---英雄要升级&属性--解析csv配置文件
- cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第九步---英雄发动攻击
- cocos2d-x 3.0游戏实例学习笔记 《跑酷》 第六步--金币&岩石添加并且管理
- cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第二步---编辑器(1)--触摸添加点
- cocos2d-x 3.0游戏实例学习笔记 《跑酷》第四步--地图循环&主角添加动作
- cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第五步---着手打造游戏界面
- Flash 游戏设计笔记: 制作炮台
- 点击炮台建炮
- cocos2d-x 3.0游戏实例学习笔记 《跑酷》 第三步---主角开跑&同时带着刚体
- cocos2d-x 3.0游戏实例学习笔记 《跑酷》 第五步--按钮控制主角Jump&Crouch
- cocos2d-x 3.0游戏实例学习笔记 《跑酷》第七步--物理碰撞检测(1)
- cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第0步---知识点总结&效果预览&设计思路
- cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第三步---编辑器(2)---更方便更多操作更像编辑器
- cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第四步---编辑器(3)--坐标保存&加载文件操作
- cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第十步---发射子弹&怪物受伤---所有源码和资源完结下载
- Cocos2d-x中,实现类似捕鱼达人的炮台
- cocos2d-x 3.0游戏实例学习笔记 《跑酷》第七步--物理碰撞检测(2)--主角吃金币
- FPGA之综合篇
- marquee 的浏览器兼容性
- 让我亲亲的告诉你
- 关于编写程序的构架。
- 秒删?我只想说艹你玛
- cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第六步---炮台&点击炮台添加英雄&英雄升级
- Android 实现ListView不可滚动效果
- 如何写一个可以展开的TextView
- libcurl教程
- Nginx配置文件说明
- qsort快速排序
- Merge Sorted Array
- H a r d F a u l t
- 好文章收藏