Cocos2d-x 3.4 之 消滅星星 > 第三篇(終) <
***************************************轉載請註明出處:http://blog.csdn.net/lttree********************************************
滿滿的淚啊。
從5月22日寫的第一篇,於6月6日結束。
中間各種課程、上機、大作業穿插。焦頭爛額的。
最後最終做出來幾乎相同的樣子了。。
。
PS:寫博客這幾天。宿舍一直停電狀態。。
。真是醉了。。
本篇實現的功能:
> 粒子特效
> 音樂音效
> 漂浮文字
> combo特效 及 每關結束後星星的消除(小於等於10個的一個個消除。剩余的一齊消除)
> 最高分存儲、場景的簡單存儲
> 消除星星的Hint
一、粒子特效
粒子特效,主要是星星消除後的爆炸效果。
這裏主要用了兩個函數:
? 產生爆炸粒子特效
? 獲取點擊星星的顏色
void starSpecialEffect(Star* sta,Point position,Node* node,int staNum) { // 創建爆炸粒子效果,粒子數量為 staNum 個 ParticleExplosion* effect = ParticleExplosion::createWithTotalParticles(staNum); // 設置此粒子特效的紋理圖片 effect->setTexture(Director::getInstance()->getTextureCache()->addImage("star.png")); // 設置開始時候的粒子顏色 effect->setStartColor(getColor4F(sta->getImgIndex())); effect->setStartColorVar(Color4F(0,0,0,1)); effect->setEndColor(getColor4F(sta->getImgIndex())); effect->setEndColorVar(Color4F(0,0,0,1)); // 設置開始時的粒子大小 effect->setStartSize(20.0f); effect->setGravity(Point(0,-300)); // 設置粒子生命周期 effect->setLife(2.0f); // 設置粒子速度 effect->setSpeed(200); effect->setSpeedVar(10); // 設置粒子位置 effect->setPosition(position); node->addChild(effect,2); } Color4F getColor4F(int imgIndex) { switch(imgIndex){ case 0: //red return Color4F::RED; case 1: //blue return Color4F::BLUE; case 2: //green return Color4F::GREEN; case 3: //purple return Color4F(128.0f,0,128.0f,1.0f); case 4: //yellow return Color4F::YELLOW; } return Color4F(1,1,1,0); }
詳細粒子特效的應用,等有時間做一個單獨的博文發出來。。
二、音樂音效
這裏用了UserDefault進行存儲,音樂音效的開關,
音樂和音效同一開關。沒有分開。
主要就是 Android對於 ogg 格式的音樂支持是最好的。
可是在Windows平臺不好測試。由於Windows自帶的WMP(Windows Media Player)不支持這個格式的音樂播放。即使沒有路,我們自己創造路來走,有大牛就開發了一款解碼軟件—— K-Lite Codec Pack,
我的WMP是能夠播放ogg了,cocos2d-x 還是須要修改一下,臨時沒改好,
於是。。。閹割了。。
我是在Windows用 mp3格式 測試,然後在Android用ogg格式的,效果挺好
之前的三消遊戲中。非常多人就說音樂播放不出來。沒有效果,
可是我自己試的是沒問題的。偶爾還真有一兩個音效不好用。我認為還是格式問題,
各個音效部分,我就不多說了。在對應位置插入即可,
背景音樂。須要 重載虛函數
virtual void onEnterTransitionDidFinish(); virtual void cleanup();
onEnterTransitionDidFinish是在場景載入完畢後進行,
不同於onEnter。onEnter是場景開始載入就進行,
cleanup 函數。是在場景被消除時的動作,
我們的背景音樂就是要在這兩個函數中增加:
void WelcomeScene::onEnterTransitionDidFinish() { Layer::onEnterTransitionDidFinish(); if ( userDefault->getBoolForKey("MusicKey") ) { SimpleAudioEngine::getInstance()->playBackgroundMusic("Music/music.ogg", true); } } void WelcomeScene::cleanup() { Layer::cleanup(); SimpleAudioEngine::getInstance()->stopBackgroundMusic(); }
對於音樂音效說的也就這麽多了
三、漂浮文字
漂浮文字效果,單獨開了一個類,
基本的創建函數:
FloatWord* FloatWord::create( const std::string& word,const int fontSize,Vec2 begin ) { FloatWord* fw = new FloatWord(); if( !fw->init(word,fontSize,begin) ) { return NULL; } fw->autorelease(); return fw; }
幾個基本的工具函數:
void FloatWord::floatInOut(const float speed,const float delayTime,std::function<void()> callback){ MoveTo* moveIn = MoveTo::create(speed,Vec2(GAME_SCREEN_WIDTH/2,fw_begin.y)); MoveTo* moveOut = MoveTo::create(speed,Vec2(-fw_label->getContentSize().width,fw_begin.y)); CallFunc* call = CallFunc::create(callback); Sequence* action = Sequence::create(moveIn,DelayTime::create(delayTime),moveOut,call,NULL); fw_label->runAction(action); } void FloatWord::floatIn(const float speed){ MoveTo* moveIn = MoveTo::create(speed,Vec2(GAME_SCREEN_WIDTH/2,fw_begin.y)); Sequence* action = Sequence::create(moveIn,NULL); fw_label->runAction(action); } void FloatWord::floatOut(const float speed,const float delayTime){ MoveTo* moveOut = MoveTo::create(speed,Vec2(-fw_label->getContentSize().width,fw_begin.y)); Sequence* action = Sequence::create(DelayTime::create(delayTime),moveOut,NULL); fw_label->runAction(action); }
就是將動作 Sequence起來了,按順序播放即可了
四、combo特效 及 每關結束後星星的消除
首先是 combo 特效,做一個函數,然後每次消除的時候,推斷消除的個數是否滿足combo特效觸發條件就可以。
void comboEffect(int num,Node* node){ if( num < 5 ) return; Sprite* comboSprite; if( num >= 10 ){ comboSprite = Sprite::create("combo_3.png"); }else if( num >= 7 ){ comboSprite = Sprite::create("combo_2.png"); }else{ comboSprite = Sprite::create("combo_1.png"); } comboSprite->setPosition(Vec2(GAME_SCREEN_WIDTH/2,GAME_SCREEN_HEIGHT/2)); node->addChild(comboSprite,4); Blink* blink = Blink::create(1.0f,5); CallFunc* remove = CallFunc::create([=](){comboSprite->removeFromParentAndCleanup(true);}); Sequence* action = Sequence::create(blink,remove,nullptr); comboSprite->runAction(action); }
最後星星的消除。這裏我的處理比較麻煩:
1.推斷此關卡結束(沒有能夠消除的星星),然後將 全局的 關卡結束 變量 設置為 true,獲得剩余星星的數量,假設剩余星星數量大於10 則 設置為10(由於一個一個消除的效果,最多10個)
2.在 update函數中(每一幀都會調用的函數),會推斷關卡是否結束,若結束。會調用 消除函數,10個以內,每消除一個都會返回,不會繼續消除。並且記錄消除時間,消除一次後一定時間間隔再進行下一次消除
3.消除完10個(或者小於10個)以後,不會再返回,會一次性將剩余星星消除完成,將 關卡結束 變量設置為false。
這裏的: 關卡結束一系列操作:
if( isFinish() ) { isLevelFinish = true; int temp = totalStarNum(); if( temp <= 10 ) { needDelOneByOne = temp; } } else { needDelOneByOne = 10; }
update函數:
void GameScene::update( float dt ) { // 分數變化 Label *labelScore = (Label *)this -> getChildByTag(6); labelScore -> setString( StringUtils::format("Score: %d ",_score)); // 假設當前關卡結束 星星一個個消除的實現 if( isLevelFinish ) { deleteTime += dt; if( deleteTime > DELSTAR_ONEBYONE_TIME ) { popFinishStar(needDelOneByOne); needDelOneByOne--; deleteTime = 0; } } }
消除結束星星函數:
void GameScene::popFinishStar( int n ) { int r,c; Star* sta; for( r = ROWS-1 ; r >= 0 ; r-- ) { for( c = 0 ; c < COLS ; c++ ) { sta = map[r][c]; if( sta ) { starSpecialEffect(sta,sta->getPosition(),this,5); map[r][c]=NULL; sta->removeFromParentAndCleanup(true); return; } else { starSpecialEffect(sta,sta->getPosition(),this,totalStarNum()*4); map[r][c]=NULL; sta->removeFromParentAndCleanup(true); } } } } isLevelFinish = false; scheduleOnce(schedule_selector(GameScene::levelOver),2.0f); }
五、最高分的存儲。場景的簡單存儲
最高分的存儲,還是用了userdefault,
就是在遊戲結束的時候。推斷一下是否破紀錄:
if( userDefault->getIntegerForKey("HightScore") < _score ) userDefault->setIntegerForKey("HightScore",_score);
場景的存儲。用了 push 和 pop,
在主界面定義一個變量,來推斷能否夠繼續,
剛進入主界面時,場景棧是沒有場景存儲的,此時點擊 繼續遊戲 就會退出遊戲,
所以要在場景棧沒有場景時,不同意點擊 繼續遊戲 button。
這個變量,在從遊戲界面跳轉到主界面(通過返回函數跳轉)時。會設置為true。就是能夠點擊。
六、消除星星Hint
當消除幾個星星,我們都要有提示。加了幾分。
遊戲結束,假設剩余星星數量小於10個,都要有額外分數的添加。
星星消除函數是這種:
一個等差數列,第一個星星 5分,第二個15分,第三個25分(首項為5,公差為10的等差數列)
所以,假設消除n個星星,就是用到等差數列的求和公式了:
n*5+n*(n-1)*10/2
剩余星星數量。所獲得的額外分數則建立了一個數組,放在GameDefine頭文件,
// 剩余星星所獎勵的分數 static const int rewardScore[11] = { 2000, 1980, 1920, 1820, 1680, 1500, 1280, 1020, 720, 380, 0 };
到這裏,消滅星星系列完美結束啦~~~
撒花。。。
接下來把歷史遺留下的問題——別踩白塊 剩下部分搞定,
然後要做第一款自己想的遊戲了,
敬請期待呀~~~
本文源代碼: > 這裏 <
終於APK: > here <
***************************************轉載請註明出處:http://blog.csdn.net/lttree********************************************
Cocos2d-x 3.4 之 消滅星星 > 第三篇(終) <