游戲的趣味性就在于不時(shí)的給你一些驚喜。當(dāng)然如果只是簡(jiǎn)單的子彈打飛機(jī),玩久了也會(huì)膩,所以加入一些好玩的道具可以很好的提高游戲的可玩性。
飛機(jī)大戰(zhàn)中也有不時(shí)從天而降的UFO(UFO是騰訊給他取的,我也是從游戲資源里發(fā)現(xiàn)這么個(gè)名字,照搬啦)。這里主要有兩種道具,雙排子彈和大炸彈。
多子彈和單子彈是一樣的實(shí)現(xiàn)。請(qǐng)參照第五篇和第六篇的處理,這里就不附代碼了。
要注意的地方有:
(1)使用CCSpriteBatchNode處理提高渲染效率。
(2)子彈的初始位置,有兩排,和單子彈層略有不同。
(3)子彈的飛行效果和回收,這和單子彈層是一樣的。
(4)其他差別就是精靈圖片不一樣,發(fā)射頻率不一樣,多子彈是有時(shí)限的,不能是CCRepeateForever了。
UFO層有兩類(lèi)精靈道具:
(1)ufo1,藍(lán)色降落傘道具,吃到了就有多子彈效果。
(2)ufo2,紅色降落傘道具,吃到了屏幕左下角會(huì)出現(xiàn)炸彈數(shù),點(diǎn)擊會(huì)全屏秒殺。
這里以多子彈道具的掉落為例。炸彈道具的掉落類(lèi)似不贅述。
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)控制道具掉落的頻率。
如果玩家未吃到該道具,在超出屏幕范圍后,自動(dòng)回收。
void UFOLayer::mutiBulletsMoveFinished(CCNode* pSender)
{
CCSprite* mutiBullets=(CCSprite*)pSender;
this->removeChild(mutiBullets,true);//從屏幕中移除
this->m_pAllMutiBullets->removeObject(mutiBullets);//從數(shù)組中移除
}
如果玩家吃到該道具,調(diào)用此接口,移除并回收該道具。
void UFOLayer::RemoveMutiBullets(CCSprite* mutiBullets)
{
this->removeChild(mutiBullets,true);
this->m_pAllMutiBullets->removeObject(mutiBullets);
}
在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é)束后切換回單子彈射擊
}
}
給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);//使用后更新炸彈顯示
}
}
效果圖
更多建議: