這一篇將會處理完子彈層的其他要點。
子彈的初始位置在飛機的機頭位置,因為飛機在游戲的過程中會隨著玩家的觸摸而改變其位置,所以,子彈的初始位置只能以當前飛機位置為基準進行添加。
CCPoint planePosition=PlaneLayer::sharedPlane->getChildByTag(AIRPLANE)->getPosition();
CCPoint bulletPosition=ccp(planePosition.x,planePosition.y+PlaneLayer::sharedPlane->getChildByTag(AIRPLANE)->getContentSize().height/2);
bullet->setPosition(bulletPosition);
還記得當時給飛機加的tag(AIRPLANE)么?通過sharedPlane的getChildByTag就能獲取到飛機精靈,然后計算出子彈初始的位置,添加到子彈層。
其實更為嚴謹?shù)姆绞绞窃O計一個子彈管理器,然后在管理器中添加子彈,這里簡單的處理,會比較好理解,雖然會影響到編程風格。
子彈的飛行效果,很簡單,就是往Y方向移動,但是X方向不能改變。所以要注意,已發(fā)射的子彈不能隨著飛機的移動而跟著移動,一旦這顆子彈發(fā)射了,它就是一個獨立的個體,不管飛機移動或者爆炸了,它只會按照自己的規(guī)則進行運動而不受干擾。
因為子彈的初始Y位置是不固定的,如果固定死一個時間會導致不同子彈的移動速度不同,所以必須先把每顆子彈的運動時間計算出來。
float length=CCDirector::sharedDirector()->getWinSize().height+bullet->getContentSize().height/2-bulletPosition.y;//飛行距離,超出屏幕即結束
float velocity=420/1;//飛行速度:420pixel/sec
float realMoveDuration=length/velocity;//飛行時間
CCFiniteTimeAction* actionMove=CCMoveTo::create(realMoveDuration,ccp(bulletPosition.x,CCDirector::sharedDirector()->getWinSize().height+bullet->getContentSize().height/2));
CCFiniteTimeAction* actionDone=CCCallFuncN::create(this,callfuncN_selector(BulletLayer::bulletMoveFinished));//回調一個子彈結束處理函數(shù)
CCSequence* sequence=CCSequence::create(actionMove,actionDone);
bullet->runAction(sequence);
cocos2d-x提供了一個很好用的數(shù)組類CCArray,它相當于一個容器。我們可以把一些創(chuàng)建出來的精靈放在里面進行管理,在不需要的時候,從中刪除它并且從屏幕上刪除它(有時候看不見不代表它們已經從屏幕上刪除了)。
因為CCArray::create函數(shù)調用了autoRelease,所以我們必須在調用創(chuàng)建后手動進行retain,以免超出使用范圍后被釋放,同時在析構函數(shù)中再進行release防止內存泄漏。
(1)創(chuàng)建成員變量指針
CCArray* m_pAllBullet;
(2)子彈層的構造函數(shù)和析構函數(shù)
BulletLayer::BulletLayer(void)
{
m_pAllBullet=CCArray::create();
m_pAllBullet->retain();
}
BulletLayer::~BulletLayer(void)
{
m_pAllBullet->release();
m_pAllBullet=NULL;
}
(3)子彈飛出屏幕后(即子彈運動結束后,自然消失而不是和敵機碰撞)的調用函數(shù)
void BulletLayer::bulletMoveFinished(CCNode* pSender)
{
CCSprite* bullet=(CCSprite*)pSender;
m_pAllBullet->removeObject(bullet);//移除CCArray
this->bulletBatchNode->removeChild(bullet,true);//移除屏幕
}
(1)開始發(fā)射子彈
void BulletLayer::StartShoot(float delay)//這里使用的是一個缺省函數(shù),為什么這么用,后面會解釋到。
{
this->schedule(schedule_selector(BulletLayer::AddBullet),0.01f,kCCRepeatForever,delay);
}
(2)停止發(fā)射子彈
void BulletLayer::StopShoot()//卸載任務執(zhí)行器
{
this->unschedule(schedule_selector(BulletLayer::AddBullet));
}
(3)刪除某顆子彈
void BulletLayer::RemoveBullet(CCSprite* bullet)//一旦子彈和敵機碰撞,我們就要刪掉這個子彈
{
if (bullet!=NULL)
{
this->m_pAllBullet->removeObject(bullet);
this->bulletBatchNode->removeChild(bullet,true);
}
}
好吧,到此為止,子彈層就創(chuàng)建完畢了,我們把它加入GameLayer層的init函數(shù)中,并執(zhí)行開始發(fā)射子彈,看一下飛機是不是可以發(fā)射子彈了。
//加入bulletLayer
this->bulletLayer=BulletLayer::create();
this->addChild(bulletLayer);
this->bulletLayer->StartShoot();
效果圖
更多建議: