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 }