标签:新手入门 c++ cocos2d-x3.0 塔防实例游戏
好吧,到这一步,整个游戏基本上弄完啦,由于自己的水平也就这样.....重写的过程中很多细节处理的不好。
游戏中很多地方都留下了可扩充的代码,可是时间方面有点不够。。。而且也没美工
本次笔记内容:
1、思路&代码&效果展示
2、完结代码&资源下载
一:思路&代码
后面的内容基本上是木头书上的内容,没什么太大修改
和之前很多地方一样,把子弹单独抽离出来,然后绑定在英雄身上,那么英雄就可以带着子弹进行攻击
这样也方便之后的扩展.....毕竟这个游戏很多地方都是基本的,但是也留给可扩展的设计
那么,首先弄一个子弹的基类,也是为了之后扩展,比如英雄升级之后子弹也变了---但是本游戏没有完成那么多
#define SPEED_DEFAULT 10 class BulletBase : public Entity{ public: BulletBase();~BulletBase(); //绑定目标 void lockAim(Entity* entity); //获取目标 Entity* getAim(); void setUsed(bool isUsed); bool isUsed(); //子弹是否攻击到敌人 bool isArrive(); protected: //在攻击目标是调用,子类实现 virtual void onLockAim(Entity* aim)=0; bool _isArrive; bool _isUsed; Entity* _aim; CC_SYNTHESIZE(int,_atkValue,AtkValue); //攻击力 CC_SYNTHESIZE(int,_speed,Speed); //速度 };实现
BulletBase::BulletBase(){ _isUsed = false; _aim = NULL; _speed = SPEED_DEFAULT; _atkValue = 1; } BulletBase::~BulletBase(){ CC_SAFE_RELEASE(_aim); } void BulletBase::setUsed(bool isUsed){ _isUsed = isUsed; setVisible(isUsed); } bool BulletBase::isUsed(){ return _isUsed; } void BulletBase::lockAim(Entity* entity){ if(entity != NULL){ CC_SAFE_RETAIN(entity); CC_SAFE_RELEASE(_aim); _aim = entity; onLockAim(_aim); } } Entity* BulletBase::getAim(){ return _aim; } bool BulletBase::isArrive(){ return _isArrive; }那么这里就实现一个正常情况的子弹
class BulletNormal : public BulletBase{ public: BulletNormal(); ~BulletNormal(); CREATE_FUNC(BulletNormal); virtual bool init(); protected: virtual void onLockAim(Entity* entity); private: void moveEnd(); };实现也比较简单
#define SPEED_NORMAL 5 BulletNormal::BulletNormal(){ _speed = SPEED_NORMAL; } BulletNormal::~BulletNormal(){ } bool BulletNormal::init(){ Sprite* sprite = Sprite::create("sprite/bullet/bulletNor.png"); bindSprite(sprite); return true; } void BulletNormal::onLockAim(Entity* aim){ _isArrive = false; //这里是一个动作的移动 auto moveTo = MoveTo::create(0.5f,aim->getPosition()); //动作完成之后的回调函数 auto callFunc = CallFunc::create(this,callfunc_selector(BulletNormal::moveEnd)); auto action = Sequence::create(moveTo,callFunc,NULL); this->runAction(action); } void BulletNormal::moveEnd(){ _isArrive = true; }那么子弹只是简单的一个精灵,从英雄移动到锁定的目标,那么这里只是一些单独的子弹,我们应该是弄一个子弹管理器,然后绑定在英雄身上
#define BULLET_NUM 10 #define BULLET_TIME 0.07f class BulletManager : public Node{ public: BulletManager(); ~BulletManager(); static BulletManager* create(); bool init(); //virtual void onExit(); //**10**从所有子弹中,娶一个没有在用的 BulletBase* getAnyUnUsedBullet(); private: Vector<BulletBase*> _bulletList; //这里保留parent,是为了把子弹节点cocos的树中,才能被显示出来 void createBullets(Node* parent); //update函数 void bulletLogicCheck(float dt); };子弹管理器也有一个简单的update函数,那么就是让子弹从英雄的位置,移动到怪物
BulletManager::BulletManager(){ } BulletManager::~BulletManager(){ } BulletManager* BulletManager::create(){ BulletManager* bulletMgr = new BulletManager(); if(bulletMgr && bulletMgr->init()){ bulletMgr->autorelease(); } else{ CC_SAFE_DELETE(bulletMgr); } return bulletMgr; } bool BulletManager::init(){ Node* parent = Director::getInstance()->getRunningScene(); createBullets(parent); this->schedule(schedule_selector(BulletManager::bulletLogicCheck),BULLET_TIME); return true; } void BulletManager::createBullets(Node* parent){ for(int i = 0; i < BULLET_NUM; i ++){ BulletBase* bullet = BulletNormal::create(); bullet->setUsed(false); _bulletList.pushBack(bullet); parent->addChild(bullet,10); } } void BulletManager::bulletLogicCheck(float dt){ for(auto bullet : _bulletList){ //正在使用的这个子弹 if(bullet != NULL && bullet->isUsed()){ //get其锁定的目标,后面让其受伤 Entity* aim = bullet->getAim(); if(aim != NULL){ if(bullet->isArrive()){ aim->hurtMe(bullet->getAtkValue()); //打中敌人,就隐藏 bullet->setUsed(false); } } } } } BulletBase* BulletManager::getAnyUnUsedBullet(){ for(auto bullet : _bulletList){ if(bullet != NULL && bullet->isUsed() == false){ bullet->setUsed(true); return bullet; } } return NULL; }那么就给英雄添加一个子弹管理器
//**10** _bulletMgr = BulletManager::create(); this->addChild(_bulletMgr);同时,英雄需要发射子弹,而不是 打印 atk 的文字
void Hero::atk(){ CCLOG("Atk!!"); BulletBase* bullet = _bulletMgr->getAnyUnUsedBullet(); if(bullet != NULL){ bullet->setPosition(getPosition()); bullet->setAtkValue(getCurAtk()); bullet->lockAim(_atkMonster); } _isAtkCoolDown = true; //攻击间隔时间后,冷却时间到 this->scheduleOnce(schedule_selector(Hero::atkCollDownEnd),getAtkSpeed()/1000.0f); }英雄在攻击,但是怪物还没受伤,不会死,你也看不到它在受伤.....
class WidgetHPSlot : public Node{ public: WidgetHPSlot(); ~WidgetHPSlot(); static WidgetHPSlot* create(Entity* entity); bool init(Entity* entity); ControlSlider* getSlider(); private: Entity* _entity; //**控件 ControlSlider* _slider; }; ----------------.cpp WidgetHPSlot::WidgetHPSlot(){ _entity = NULL; _slider = NULL; } WidgetHPSlot::~WidgetHPSlot(){ CC_SAFE_RELEASE(_entity); CC_SAFE_RELEASE(_slider); } WidgetHPSlot* WidgetHPSlot::create(Entity* entity){ WidgetHPSlot* hpSlot = new WidgetHPSlot(); if(hpSlot && hpSlot->init(entity)){ hpSlot->autorelease(); } else{ CC_SAFE_DELETE(hpSlot); } return hpSlot; } bool WidgetHPSlot::init(Entity* entity){ CC_SAFE_RETAIN(entity); _entity = entity; _slider = ControlSlider::create( "widget/sliderBg.png", "widget/sliderValue.png", "widget/sliderThumb.png"); _slider->setTouchEnabled(false); this->addChild(_slider); return true; } ControlSlider* WidgetHPSlot::getSlider(){ return _slider; }然后monster添加成员,并且,重写基类的函数,这些函数是分别在 死亡、绑定、受伤的时候附加调用的,给你自己添加扩展其他作用的
void Monster::onDead(){ this->removeAllChildrenWithCleanup(true); } void Monster::onBindSprite(){ if(_hpSlot == NULL){ Point pos = getPosition(); _hpSlot = WidgetHPSlot::create(this); _hpSlot->setPosition(pos.x,pos.y+getSprite()->getContentSize().height/2); _hpSlot->getSlider()->setMaximumValue(getHP()); _hpSlot->getSlider()->setMinimumValue(0); _hpSlot->getSlider()->setValue(getHP()); this->addChild(_hpSlot); } } void Monster::onHurt(int hurtValue){ if(_hpSlot != NULL){ int curValue = _hpSlot->getSlider()->getValue(); curValue -= hurtValue; if(curValue < 0){ curValue = 0; } _hpSlot->getSlider()->setValue(curValue); } }这里要注意把前面的init 函数中的 绑定精灵放到,set属性后面,不然,bingSprite就把onBindSprite函数中的血量
效果如下:
怪物被消灭之后就没啦.....
二:
---------------------------------------
---------------------------------------
好吧,也只能做到这里啦..........什么游戏胜利、失败什么的...都没完善啦。。。。勿喷
好吧,个人愚昧观点,欢迎指正与讨论
cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第十步---发射子弹&怪物受伤---所有源码和资源完结下载
标签:新手入门 c++ cocos2d-x3.0 塔防实例游戏
原文地址:http://blog.csdn.net/zyy173533832/article/details/38903665