歡迎轉載:http://blog.csdn.net/fylz1125/article/details/8492497
上一篇文章已經實現了MoonWarriors開始菜單的大部分元素,還差一個運動的飛船和一個點擊newGame的特效和音效。
1.飛船
// ships CCTexture2D *textCache = CCTextureCache::sharedTextureCache()->addImage(s_ship01); m_ship = CCSprite::createWithTexture(textCache, CCRectMake(0, 45, 60, 38)); this->addChild(m_ship, 0, 4); CCPoint position = ccp(CCRANDOM_0_1() * winSize.width, 0); m_ship->setPosition(position); m_ship->runAction(CCMoveBy::create(2, ccp(CCRANDOM_0_1() * winSize.width, position.y + winSize.height + 100)));
這裡的飛船就是一個sprite,後面我會建一個飛船的類,但這個只是一個Sprite。
緩衝飛船圖片,create一個飛船,添加,設定位置,執行動作。
在設定飛船位置的時候注意,每次飛船出來位置都是隨機的。引擎封裝了一個隨機函數CCRANDON_0_1(),這個是隨機一個0到1之間的float數。用一個MoveBy來實現飛船移動,同樣移動的目標點也有一定的隨機性。
你以為這樣就完了嗎,那你就錯了。所有的這些元素都在init()函數完成的,即使runAction了,也就只是執行一次。
為了看到不斷有飛船在螢幕上飛,需要加點料。這裡用schedule()函數來不斷更新。這個函數就是任務調度,每隔dt調用一次回呼函數,這裡就是每0.1秒執行update函數
this->schedule(schedule_selector(StartMenu::update), 0.1);
然後看update的實現
if (m_ship->getPosition().y > 480) { CCPoint pos = ccp(CCRANDOM_0_1() * winSize.width, 10); m_ship->setPosition(pos); m_ship->runAction(CCMoveBy::create(floor(5 * CCRANDOM_0_1()), ccp(CCRANDOM_0_1() * winSize.width, pos.y + 480))); }
飛船飛出螢幕後就重新設定其位置再執行動作。
2.音效
這個很簡單,直接用了聲音引擎
SimpleAudioEngine::sharedEngine()->setBackgroundMusicVolume(0.7); SimpleAudioEngine::sharedEngine()->playBackgroundMusic(s_mainMainMusic, true);
3.點擊特效
html5版的這個效果直接一個匿名函數搞定了,我不知道2dx怎麼用一個回調搞定,就做了個特效類,專門來搞這個,嘿嘿。
記得前面有個flareEffec函數,就是在這裡處理的。
void StartMenu::flareEffect(CCNode *node){ onButtonEffect(); Effect* flareEffect = Effect::create(); CCCallFunc *callback = CCCallFunc::create(this, callfunc_selector(StartMenu::newGame)); flareEffect->flareEffect(this, callback);}
onButtonEffect是聲音特效,Effect就是用來做動畫特效的,關鍵就是其flareEffect函數。
void Effect::flareEffect(CCNode *parent, CCCallFunc *callback){ // 特效圖片 CCSprite *flare = CCSprite::create(s_flare); // 設定混合模式 ccBlendFunc cbl = {GL_SRC_ALPHA, GL_ONE}; flare->setBlendFunc(cbl); // 添加到父節點 parent->addChild(flare, 10); // 設定初始透明度 flare->setOpacity(0); // 設定初始位置 flare->setPosition(ccp(-30, 297)); // 設定初始角度 flare->setRotation(-120); // 設定初始放大係數 flare->setScale(0.2); // 透明度漸層 CCActionInterval *opacityAnim = CCFadeTo::create(0.5, 255); CCActionInterval *opacDim = CCFadeTo::create(1, 0); // 大小漸層 CCActionInterval *bigAnim = CCScaleBy::create(0.7, 1.2, 1.2); // 漸層速率,正玄變化,由快到慢 CCEaseSineOut *biggerEase = CCEaseSineOut::create(bigAnim); CCActionInterval *moveAnim = CCMoveBy::create(0.5, ccp(328, 0)); CCEaseSineOut *moveEase = CCEaseSineOut::create(moveAnim); // 角度旋轉 CCActionInterval *roteAnim = CCRotateBy::create(2.5, 90); // 角度旋轉速度,指數變化 CCEaseExponentialOut * rotateEase = CCEaseExponentialOut::create(roteAnim); // 放大到原大小 CCScaleTo *bigger = CCScaleTo::create(0.5, 1); // 動畫完成後回呼函數 CCCallFuncN *onComplete = CCCallFuncN::create(flare, callfuncN_selector(Effect::killFlare)); // 執行動畫和回呼函數 flare->runAction(CCSequence::create(opacityAnim, biggerEase, opacDim, onComplete, callback, NULL)); flare->runAction(moveEase); flare->runAction(rotateEase); flare->runAction(bigger);}
這個還是按照js的邏輯寫的。傳了一個parent的node和一個回呼函數進來,然後一系列動作,最後執行動作和回調。
回呼函數裡有個killFlare函數,其實就是用來幹掉這個特效精靈的,因為如果不幹掉,會一直添加。
到這裡,這個菜單的準系統就做完了,還差一些回調,狀態控制等沒有加,後續再來弄。