Cocos2d-x UFO層特殊道具

2018-10-02 09:53 更新

UFO層特殊道具

游戲的趣味性就在于不時的給你一些驚喜。當然如果只是簡單的子彈打飛機,玩久了也會膩,所以加入一些好玩的道具可以很好的提高游戲的可玩性。

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

1.多子彈層

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

要注意的地方有:

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

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

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

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

2.UFO層

UFO層有兩類精靈道具:

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

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

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

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

    void UFOLayer::AddMutiBullets(float dt)
    {
        //創(chuàng)建多子彈道具精靈
        CCSprite* mutiBullets=CCSprite::create(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("ufo1.png"));
        //獲得隨機位置
        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ù)組指針,成員變量
        //這是一個比較cute的動畫,也可以采用CCEaseAction類處理
        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í)行動畫
        mutiBullets->runAction(sequence);
    }

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

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

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

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

2.3.提供的移除接口

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

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

3.碰撞檢測

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

    //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);//調用移除雙子彈道具
            this->bulletLayer->StopShoot();//停止單子彈的射擊
            this->mutiBulletsLayer->StartShoot();//開啟雙子彈的射擊
            this->bulletLayer->StartShoot(6.2f);//還記得在第四篇StartShoot我們將它設置為缺省函數(shù)?這樣一來就可以實現(xiàn)雙子彈結束后切換回單子彈射擊
        }
    }

4.炸彈ufo的使用

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

給GameLayer增加如下函數(shù),當檢測主角飛機碰撞炸彈ufo時調用。

    //更新炸彈圖標和數(shù)量顯示
    void GameLayer::updateBigBoomItem(int bigBoomCount)//傳入當前炸彈數(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);//移除炸彈圖標
            }
            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設置為100000,夠用了。。。打出來手都長繭了。
            {
                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ā)的回調函數(shù)

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

效果圖



以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號