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

UFO層特殊道具

游戲的趣味性就在于不時(shí)的給你一些驚喜。當(dāng)然如果只是簡(jiǎn)單的子彈打飛機(jī),玩久了也會(huì)膩,所以加入一些好玩的道具可以很好的提高游戲的可玩性。

飛機(jī)大戰(zhàn)中也有不時(shí)從天而降的UFO(UFO是騰訊給他取的,我也是從游戲資源里發(fā)現(xiàn)這么個(gè)名字,照搬啦)。這里主要有兩種道具,雙排子彈和大炸彈。

1.多子彈層

多子彈和單子彈是一樣的實(shí)現(xiàn)。請(qǐng)參照第五篇和第六篇的處理,這里就不附代碼了。

要注意的地方有:

(1)使用CCSpriteBatchNode處理提高渲染效率。

(2)子彈的初始位置,有兩排,和單子彈層略有不同。

(3)子彈的飛行效果和回收,這和單子彈層是一樣的。

(4)其他差別就是精靈圖片不一樣,發(fā)射頻率不一樣,多子彈是有時(shí)限的,不能是CCRepeateForever了。

2.UFO層

UFO層有兩類(lèi)精靈道具:

(1)ufo1,藍(lán)色降落傘道具,吃到了就有多子彈效果。

(2)ufo2,紅色降落傘道具,吃到了屏幕左下角會(huì)出現(xiàn)炸彈數(shù),點(diǎn)擊會(huì)全屏秒殺。

這里以多子彈道具的掉落為例。炸彈道具的掉落類(lèi)似不贅述。

2.1.添加多子彈降落傘道具

    void UFOLayer::AddMutiBullets(float dt)
    {
        //創(chuàng)建多子彈道具精靈
        CCSprite* mutiBullets=CCSprite::create(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("ufo1.png"));
        //獲得隨機(jī)位置
        CCSize mutiBlletsSize=mutiBullets->getContentSize();
        CCSize winSize=CCDirector::sharedDirector()->getWinSize();
        int minX=mutiBlletsSize.width/2;
        int maxX=winSize.width-mutiBlletsSize.width/2;
        int rangeX=maxX-minX;
        int actualX=(rand()%rangeX)+minX;
        //添加到UFO層并加入CCArray數(shù)組
        mutiBullets->setPosition(ccp(actualX,winSize.height+mutiBlletsSize.height/2));
        this->addChild(mutiBullets);
        this->m_pAllMutiBullets->addObject(mutiBullets);//m_pAllMutibullets是CCArray數(shù)組指針,成員變量
        //這是一個(gè)比較cute的動(dòng)畫(huà),也可以采用CCEaseAction類(lèi)處理
        CCMoveBy* move1 = CCMoveBy::create(0.5f, CCPointMake(0, -150));
        CCMoveBy* move2 = CCMoveBy::create(0.3f, CCPointMake(0, 100));
        CCMoveBy* move3 = CCMoveBy::create(1.0f, CCPointMake(0,0-winSize.height-mutiBlletsSize.height/2));
        CCCallFuncN* moveDone = CCCallFuncN::create(this,callfuncN_selector(UFOLayer::mutiBulletsMoveFinished));
        CCFiniteTimeAction* sequence = CCSequence::create(move1,move2,move3,moveDone,NULL);
        //執(zhí)行動(dòng)畫(huà)
        mutiBullets->runAction(sequence);
    }

在init()用schedule來(lái)控制道具掉落的頻率。

2.2.多子彈降落傘道具的回收

如果玩家未吃到該道具,在超出屏幕范圍后,自動(dòng)回收。

    void UFOLayer::mutiBulletsMoveFinished(CCNode* pSender)
    {
        CCSprite* mutiBullets=(CCSprite*)pSender;
        this->removeChild(mutiBullets,true);//從屏幕中移除
        this->m_pAllMutiBullets->removeObject(mutiBullets);//從數(shù)組中移除
    }

2.3.提供的移除接口

如果玩家吃到該道具,調(diào)用此接口,移除并回收該道具。

    void UFOLayer::RemoveMutiBullets(CCSprite* mutiBullets)
    {
        this->removeChild(mutiBullets,true);
        this->m_pAllMutiBullets->removeObject(mutiBullets);
    }

3.碰撞檢測(cè)

在GameLayer的update中執(zhí)行主角與ufo的碰撞檢測(cè)。

    //mutiBullets & airplane CheckCollision
    CCObject *ut;
    CCARRAY_FOREACH(this->ufoLayer->m_pAllMutiBullets,ut)
    {
        CCSprite* mutiBullets=(CCSprite*)ut;
        if (CCRect::CCRectIntersectsRect(PlaneLayer::sharedPlane->boundingBox(),mutiBullets->boundingBox()))//玩家吃到雙子彈道具
        {
            this->ufoLayer->RemoveMutiBullets(mutiBullets);//調(diào)用移除雙子彈道具
            this->bulletLayer->StopShoot();//停止單子彈的射擊
            this->mutiBulletsLayer->StartShoot();//開(kāi)啟雙子彈的射擊
            this->bulletLayer->StartShoot(6.2f);//還記得在第四篇StartShoot我們將它設(shè)置為缺省函數(shù)?這樣一來(lái)就可以實(shí)現(xiàn)雙子彈結(jié)束后切換回單子彈射擊
        }
    }

4.炸彈ufo的使用

給GameLayer加個(gè)成員變量,int bigBoomCount,初始為0,代表主角飛機(jī)當(dāng)前擁有的炸彈數(shù),吃到了(碰撞檢測(cè))就+1,使用(觸摸炸彈按鈕)-1。當(dāng)多個(gè)炸彈就在炸彈圖標(biāo)邊上 x N。。。

給GameLayer增加如下函數(shù),當(dāng)檢測(cè)主角飛機(jī)碰撞炸彈ufo時(shí)調(diào)用。

    //更新炸彈圖標(biāo)和數(shù)量顯示
    void GameLayer::updateBigBoomItem(int bigBoomCount)//傳入當(dāng)前炸彈數(shù)
    {
        CCSprite* normalBomb=CCSprite::create(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("bomb.png"));
        CCSprite* pressedBomb=CCSprite::create(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("bomb.png"));
        if (bigBoomCount<0)
        {
            return;
        }
        else if (bigBoomCount==0)
        {
            if(this->getChildByTag(TAG_BIGBOOM_MENUITEM))
            {
                this->removeChildByTag(TAG_BIGBOOM_MENUITEM,true);//移除炸彈圖標(biāo)
            }
            if (this->getChildByTag(TAG_BIGBOOMCOUNT_LABEL))
            {
                this->removeChildByTag(TAG_BIGBOOMCOUNT_LABEL,true);//移除炸彈數(shù)量
            }
        }
        else if (bigBoomCount==1)
        {
            //加入bigBoomItemMenu
            if (!this->getChildByTag(TAG_BIGBOOM_MENUITEM))
            {
                CCMenuItemImage* pBigBoomItem=CCMenuItemImage::create();
                pBigBoomItem->initWithNormalSprite(normalBomb,pressedBomb,NULL,this,menu_selector(GameLayer::menuBigBoomCallback));
                pBigBoomItem->setPosition(ccp(normalBomb->getContentSize().width/2+10,normalBomb->getContentSize().height/2+10));
                menuBigBoom=CCMenu::create(pBigBoomItem,NULL);
                menuBigBoom->setPosition(CCPointZero);
                this->addChild(menuBigBoom,0,TAG_BIGBOOM_MENUITEM);
            }
            if (this->getChildByTag(TAG_BIGBOOMCOUNT_LABEL))
            {
                this->removeChildByTag(TAG_BIGBOOMCOUNT_LABEL,true);//移除炸彈數(shù)量
            }
        }
        else
        {
            if (!this->getChildByTag(TAG_BIGBOOM_MENUITEM))
            {
                CCMenuItemImage* pBigBoomItem=CCMenuItemImage::create();
                pBigBoomItem->initWithNormalSprite(normalBomb,pressedBomb,NULL,this,menu_selector(GameLayer::menuBigBoomCallback));
                pBigBoomItem->setPosition(ccp(normalBomb->getContentSize().width/2+10,normalBomb->getContentSize().height/2+10));
                menuBigBoom=CCMenu::create(pBigBoomItem,NULL);
                menuBigBoom->setPosition(CCPointZero);
                this->addChild(menuBigBoom,0,TAG_BIGBOOM_MENUITEM);
            }
            if (this->getChildByTag(TAG_BIGBOOMCOUNT_LABEL))
            {
                this->removeChildByTag(TAG_BIGBOOMCOUNT_LABEL,true);
            }
            if (bigBoomCount>=0 && bigBoomCount<=MAX_BIGBOOM_COUNT)//MAX_BIGBOOM_COUNT設(shè)置為100000,夠用了。。。打出來(lái)手都長(zhǎng)繭了。
            {
                CCString* strScore=CCString::createWithFormat("X%d",bigBoomCount);//增加炸彈數(shù)量顯示
                bigBoomCountItem=CCLabelBMFont::create(strScore->m_sString.c_str(),"font/font.fnt");//自定義字體
                bigBoomCountItem->setColor(ccc3(143,146,147));
                bigBoomCountItem->setAnchorPoint(ccp(0,0.5));
                bigBoomCountItem->setPosition(ccp(normalBomb->getContentSize().width+15,normalBomb->getContentSize().height/2+5));
                this->addChild(bigBoomCountItem,0,TAG_BIGBOOMCOUNT_LABEL);
            }
        }
    }

使用炸彈觸發(fā)的回調(diào)函數(shù)

    //使用炸彈的回調(diào)函數(shù)
    void GameLayer::menuBigBoomCallback(CCObject* pSender)
    {
        if(bigBoomCount>0 && !CCDirector::sharedDirector()->isPaused())//炸彈數(shù)大于0,且游戲未暫停,參見(jiàn)后一篇:游戲暫停和觸摸屏蔽
        {
            bigBoomCount--;//炸彈數(shù)-1
            this->enemyLayer->removeAllEnemy();//敵機(jī)全掛掉
            updateBigBoomItem(bigBoomCount);//使用后更新炸彈顯示
        }
    }

效果圖

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

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