鍍金池/ 教程/ Java/ 子彈層的處理
游戲暫停和觸摸屏蔽
游戲場景過渡
碰撞檢測
跨平臺(tái)移植和廣告植入
批次渲染
觸摸事件和優(yōu)先級
背景音樂和音效
別急,先處理好CCScene和CCLayer的關(guān)系
自定義敵機(jī)精靈
UFO層特殊道具
主角的登場和幀動(dòng)畫
引擎坐標(biāo)系,錨點(diǎn)和背景滾動(dòng)
分?jǐn)?shù)的本地存儲(chǔ)
子彈層的處理
搞個(gè)飛機(jī)來玩玩

子彈層的處理

這一篇將會(huì)處理完子彈層的其他要點(diǎn)。

1.子彈的初始位置

子彈的初始位置在飛機(jī)的機(jī)頭位置,因?yàn)轱w機(jī)在游戲的過程中會(huì)隨著玩家的觸摸而改變其位置,所以,子彈的初始位置只能以當(dāng)前飛機(jī)位置為基準(zhǔn)進(jìn)行添加。

    CCPoint planePosition=PlaneLayer::sharedPlane->getChildByTag(AIRPLANE)->getPosition();
    CCPoint bulletPosition=ccp(planePosition.x,planePosition.y+PlaneLayer::sharedPlane->getChildByTag(AIRPLANE)->getContentSize().height/2);
    bullet->setPosition(bulletPosition);

還記得當(dāng)時(shí)給飛機(jī)加的tag(AIRPLANE)么?通過sharedPlane的getChildByTag就能獲取到飛機(jī)精靈,然后計(jì)算出子彈初始的位置,添加到子彈層。

其實(shí)更為嚴(yán)謹(jǐn)?shù)姆绞绞窃O(shè)計(jì)一個(gè)子彈管理器,然后在管理器中添加子彈,這里簡單的處理,會(huì)比較好理解,雖然會(huì)影響到編程風(fēng)格。

2.子彈的飛行效果

子彈的飛行效果,很簡單,就是往Y方向移動(dòng),但是X方向不能改變。所以要注意,已發(fā)射的子彈不能隨著飛機(jī)的移動(dòng)而跟著移動(dòng),一旦這顆子彈發(fā)射了,它就是一個(gè)獨(dú)立的個(gè)體,不管飛機(jī)移動(dòng)或者爆炸了,它只會(huì)按照自己的規(guī)則進(jìn)行運(yùn)動(dòng)而不受干擾。

因?yàn)樽訌椀某跏糦位置是不固定的,如果固定死一個(gè)時(shí)間會(huì)導(dǎo)致不同子彈的移動(dòng)速度不同,所以必須先把每顆子彈的運(yùn)動(dòng)時(shí)間計(jì)算出來。

    float length=CCDirector::sharedDirector()->getWinSize().height+bullet->getContentSize().height/2-bulletPosition.y;//飛行距離,超出屏幕即結(jié)束
    float velocity=420/1;//飛行速度:420pixel/sec
    float realMoveDuration=length/velocity;//飛行時(shí)間

    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));//回調(diào)一個(gè)子彈結(jié)束處理函數(shù)

    CCSequence* sequence=CCSequence::create(actionMove,actionDone);
    bullet->runAction(sequence);

3.子彈的管理和回收

cocos2d-x提供了一個(gè)很好用的數(shù)組類CCArray,它相當(dāng)于一個(gè)容器。我們可以把一些創(chuàng)建出來的精靈放在里面進(jìn)行管理,在不需要的時(shí)候,從中刪除它并且從屏幕上刪除它(有時(shí)候看不見不代表它們已經(jīng)從屏幕上刪除了)。

因?yàn)镃CArray::create函數(shù)調(diào)用了autoRelease,所以我們必須在調(diào)用創(chuàng)建后手動(dòng)進(jìn)行retain,以免超出使用范圍后被釋放,同時(shí)在析構(gòu)函數(shù)中再進(jìn)行release防止內(nèi)存泄漏。

(1)創(chuàng)建成員變量指針

    CCArray* m_pAllBullet;

(2)子彈層的構(gòu)造函數(shù)和析構(gòu)函數(shù)

    BulletLayer::BulletLayer(void)
    {
        m_pAllBullet=CCArray::create();
        m_pAllBullet->retain();
    }

    BulletLayer::~BulletLayer(void)
    {
        m_pAllBullet->release();
        m_pAllBullet=NULL;
    }

(3)子彈飛出屏幕后(即子彈運(yùn)動(dòng)結(jié)束后,自然消失而不是和敵機(jī)碰撞)的調(diào)用函數(shù)

    void BulletLayer::bulletMoveFinished(CCNode* pSender)
    {
        CCSprite* bullet=(CCSprite*)pSender;
        m_pAllBullet->removeObject(bullet);//移除CCArray
        this->bulletBatchNode->removeChild(bullet,true);//移除屏幕
    }

4.子彈層其他接口

(1)開始發(fā)射子彈

    void BulletLayer::StartShoot(float delay)//這里使用的是一個(gè)缺省函數(shù),為什么這么用,后面會(huì)解釋到。
    {
        this->schedule(schedule_selector(BulletLayer::AddBullet),0.01f,kCCRepeatForever,delay);
    }

(2)停止發(fā)射子彈

    void BulletLayer::StopShoot()//卸載任務(wù)執(zhí)行器
    {
        this->unschedule(schedule_selector(BulletLayer::AddBullet));
    }

(3)刪除某顆子彈

    void BulletLayer::RemoveBullet(CCSprite* bullet)//一旦子彈和敵機(jī)碰撞,我們就要?jiǎng)h掉這個(gè)子彈
    {
        if (bullet!=NULL)
        {
            this->m_pAllBullet->removeObject(bullet);
            this->bulletBatchNode->removeChild(bullet,true);
        }
    }

好吧,到此為止,子彈層就創(chuàng)建完畢了,我們把它加入GameLayer層的init函數(shù)中,并執(zhí)行開始發(fā)射子彈,看一下飛機(jī)是不是可以發(fā)射子彈了。

    //加入bulletLayer
    this->bulletLayer=BulletLayer::create();
    this->addChild(bulletLayer);
    this->bulletLayer->StartShoot();

效果圖

http://wiki.jikexueyuan.com/project/cocos2d-x-getting-real/images/6.1.jpeg" alt="" />