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