cocos2dx打飞机项目笔记二:BulletLayer类

BulletLayer.h 内容如下

 1 class BulletLayer : public cocos2d::CCLayer
 2 {
 3 
 4 public:
 5 
 6     CC_SYNTHESIZE(bool, m_IsHeroLive, IsHeroLive);//hero活着的时候才发射子弹。。。
 7 
 8     CCArray *m_bullets;//存储发射的子弹    
 9     CCNode* pParent;//在类初始化的时候会把Hero赋给它他,因为子弹要根据hero来确定发射的位置
10     CCSpriteBatchNode* batchNode; //对子弹进行批处理
11 
12 
13      BulletLayer(void);
14     ~BulletLayer(void);
15 
16     void startShoot(void);//调用该方法表示开始发射子弹
17     void stopShoot(void);
18 
19     void bulletMoveToFinish(CCNode* pSender);    //直接调用removeBullet
20     void removeBullet(CCSprite* bullet);//子弹飞出屏幕外 或者 和敌机碰撞后,把子弹回收
21 
22     void addBullet(float dt);//已不用
23     void addOneBullet(float dt);//发射一粒子弹
24 
25     CREATE_FUNC(BulletLayer);
26 };

重点一:敌机离hero越来越近时发射子弹的声音频率变快

根据数据成员、函数名可以很容易看得出每个成员的意义,不过该类的设计思想我前后改动比较大,所以会看到 addBullet 和addOneBullet 两个奇怪的方法,所有一切都是为了实现一个效果:当敌机离hero越来越近时发射子弹的那个声音就会变得很急促,这个效果非常必要,否则游戏就一直是固定频率的 砰砰砰 声,感觉很差。详情如下。

原本 startShoot 方法的实现是:

 this->schedule(schedule_selector(BulletLayer::addBullet), 0.15f, kCCRepeatForever, delay); 这样子每隔一定时间就调用 addBullet方法来发射一粒子弹;

现在改成:this->scheduleOnce(schedule_selector(BulletLayer::addOneBullet),0.5f); 只回调一次,就是只调用一次 addOneBullet 方法发射一粒子弹,然后removeBullet 子弹后再回调 addOneBullet 方法发射一粒子弹。

也就是说,其实屏幕上一直只有一粒子弹!当这颗子弹被回收后才发射另一粒子弹,这样子当敌机离hero越来越近时,子弹击中敌机的时间也就越短,发射下一粒子弹的时间间隔就越短,那么那个发射子弹的声音就急促起来了~~

重点二:重复remove子弹的问题

从batchNode删除子弹时出现一个 “node不是batchnode的child” 的错误,原因见代码注释

removeBullet 方法实现如下:

 1 void BulletLayer::removeBullet(CCSprite* bullet)
 2 {
 3     if (bullet!=NULL)  
 4     {  
 5         bullet->stopAllActions();
 6 
 7         //一粒子弹可能同时撞到两台敌机,会造成被remove两次而出错,所以要有判断
 8         if (this->batchNode->getChildren()->containsObject((CCObject*)bullet) )
 9         {
10             this->batchNode->removeChild(bullet,true);
11         }
12 
13         if ( this->m_bullets->containsObject(bullet))
14         {
15             this->m_bullets->removeObject(bullet);
16         }
17 
18     }
19 
20     //一粒子弹可能同时撞到两台敌机,removeBullet 方法就会被调用两次,
21     //那么addOneBullet 也会被调用两次,如果没有 this->m_bullets->count() < 1 ,子弹就会越来越多
22     if (this->m_IsHeroLive && this->m_bullets->count() < 1)
23     {
24         BulletLayer::addOneBullet(0.1f);
25     }
26 
27 }
原文地址:https://www.cnblogs.com/zouzf/p/3490212.html