cocos2d 高仿doodle jump 無源碼,cocos2ddoodle
1. 遊戲視頻
主角眼熟嗎?沒錯,上次跑酷遊戲中的“30”來Jump了,有三種道具,主角光環,竹蜻蜓,翅膀; 有兩種怪物,螃蟹和鳥; 有5種板子。點擊螢幕,30會把它的嘴巴3給發射出去,可以攻擊怪物。上次的跑酷參考《cocos2d 簡單高仿天天跑酷遊戲》 ,蘋果已經審核通過...但做的很差,後續有時間再更新。後面考慮會出更多的該主角遊戲。
其實蠻討厭"高仿"這兩個字的,爭取下一款遊戲有更多原創部分。
2.向上跳的位移實現
正常情況下,不使用任何的東西,主角在板子上跳,會跳出最上面的螢幕就看不到了!沒有視頻中主角一直在螢幕中間的感覺。那麼如何?這樣的效果呢?非常簡單。這裡不得不吐槽下cocos2d, 學過Opengl 或者 DirectX的,都應該知道有Camera這麼一個東西存在,2D遊戲只是選擇了平行投射(parallel projection)參考這篇文章《DirectX Camera》 .但3.2 之前的Camera根本不能用,3.3才加入了Camera. 如果用Camera這裡會非常容易實現,也跟現實比較吻合。1.如果使用Camera,所有板的PositionY 就定死的,越高的板,它的PositionY 就越大,主角往上跳時,主角的PositionY也不斷變大。有一個Camera,它的位置跟著主角來移動就可以了。就這麼簡單。2.不使用Camera,我用的是3.2的cocos2d,所以不好使用Camera,採用了移動整個Layer的實現。主角會跳出最上面的螢幕的,怎麼辦的?把整個Layer往下移動就可以了。
float minPositionY = 0;void update(float dt){//follow the herofloat nextPositionY = VISIBLE_HEIGHT / 2 - hero->getPositionY();if(nextPositionY < minPositionY){minPositionY = nextPositionY;this->setPositionY(minPositionY);}}
看起來比較簡單,如果是主角掉下螢幕最底下,有一個墜落感覺,邏輯上又比較麻煩了。還是用Camera的比較好。
3.板子產生的邏輯
最塊又比較麻煩了。首先是板子連續產生的邏輯,不可能一次產生幾十個板子,反正螢幕之上和螢幕之下使用者都是看不到的,也就是說10幾個板子,整個遊戲就夠用了。到後面,10個都不用。正常的update是一秒中執行60次。我們需要整一個慢一點的定時器,這樣不會太影響效能,schedule(schedule_selector(GameObjectsLayer::createAndRemoveObjects), 0.064);,專門在裡面建立板和移除不需要的板子。
deque<JumpBoard*> _boardObjects;void generateSomeBoards(const int& lastPositionX,int startPosition,const int& count);void createAndRemoveObjects(float dt){ if(_pause == true){ return; } if(_boardObjects.size() <= 12){//generate some boards if we only have few boards JumpBoard *lastBoard = _boardObjects.back(); generateSomeBoards(lastBoard->getPositionX(), lastBoard->getPositionY() + getGeneratorHigh(),5); } //remove unused boards JumpBoard* firstBoard = _boardObjects.front(); if(hero->getPositionY() - firstBoard->getPositionY() > 600){ firstBoard->removeFromParent(); _boardObjects.pop_front(); }}
再簡單用語言來說下上面中沒有給出詳細代碼的generateSomeBoards。
遊戲要考慮的東西很多:1.剛開始的時候兩個板之間的距離要短些,看起來會密些,這樣遊戲會容易上手些,兩個板之間的距離會隨著主角的變高而增大。2.剛開始的時候產生板的類型要簡單些,我這裡只有最兩種類型,到後面才會出現各種類型的板。我現在越來越意識到,如果一個遊戲的主要玩法能讓不懂程式邏輯的策劃很容易修改的話,這個遊戲寫的就還不錯。這裡遊戲的玩法就是如何控制產生板子。我必須承認這塊做的還不好。
typedef enum{ kNormalBoard, //0 kCloudBoard, //1 kMoveBoard, //2 kMoveLttleBoard, //3 kSpringBoard //4}JumpBoardType;int level1[] = {0,0,0,0,0,0,0,0,0,0,1,1,1};int level2[] = {0,0,0,0,0,0,0,0,0,0,1,1,2,3,4};
這裡簡單有兩個數組,後面會用它們初始化兩個vector<int>,然後用random_shuffle,進行洗牌。會根據當前的hero高度來選擇不同的數組。當index移到最後一個時候,就歸0,再次洗牌。
int getBoardTypeDueToFloorNum(){ int floorCount = getFloorCount(); int result = 0; if(floorCount <= 2){ if(_levelIndex >= _level1.size()){ _levelIndex = 0; random_shuffle(_level1.begin(), _level1.end()); } result = _level1[_levelIndex]; ++_levelIndex; return result; }else if(floorCount > 2 && floorCount <= 10){ if(_levelIndex >= _level2.size()){ _levelIndex = 0; random_shuffle(_level2.begin(), _level2.end()); } result = _level2[_levelIndex]; ++_levelIndex; return result; }else{ //無限模式 }}
當然後面的無限模式更加複雜點,我搞了5種不同類型的數組進行洗牌。這裡不再贅述。
4.道具和怪物產生位置
道具和怪物產生位置我就簡單處理了,每隔幾個螢幕高度就放置一個。
//typedef enum{// kHelicopterItem, //0// kFlyItem, //1// kShortItem, //2// kLongItem, //3// kDefenceBall //4//}EatItemType;int allEatItemType[] = {4,4,4,0,0,1};
為了讓不同道具出現機率不一樣,又用了跟上面板子類似的邏輯。怪物這裡就2種,就50%機率會產生不同怪物。Doodle jump這塊做的變態的好,一般怪物出現之前會有殺死怪物或者躲避怪物的道具出現。
5.主角光環和拋物線掉落
主角光環的橢圓移動,可以參考這篇文章《cocos2d 繞橢圓移動》。還有一個是使用過後道具的掉落軌跡。這塊第一次玩Doodle jump就給我帶來了驚喜,竹蜻蜓或者火箭,時間到後,完美的扔掉,處理的非常自然和有趣。實現起來跟上面的橢圓移動類似。就是數學用的拋物線,只是這個是開口向下的。只用到了左邊紅色的部分。我用的公式是x = t * -400, y = x * x * -0.02 ( x = [0, -400] )。update中,t = [0, 1],代入這個公式就可以了。
6. 其他
其他像道具產生的位置比較講究,最後添加到板子中去,這樣板子移動,就會跟著移動了,會自然點。無論是主角碰上怪物或者主角的嘴巴碰上怪物,怪物都會旋轉地往那個方向飛出去,這個效果非常好,可以簡單地計算下兩個點的角度,給怪物一個速度屬性,在update的每一幀中進行移動。主角的嘴巴飛出去還會飛回來,飛回來的時候,因為主角的位置一直變化的,所以也要在update的每一幀中,不斷改變位置,離主角越來越近,像飛機的跟蹤飛彈。這裡就不再贅述。
感覺Cocos2d-x 3.2這塊重力感應Accelerometer控制的似乎有問題,在這個遊戲中偶爾會失控,我還不知道發生的原因和規律,非常頭痛。還有遊戲的速度,看起來都是60幀,但速度偶爾會有區別。這些高仿的遊戲我想不太可能有好的市場,只能通過它們積累經驗來做真正原創遊戲。不過做這些小遊戲比那些網路遊戲有趣些。有真正遊戲的感覺。
http://www.waitingfy.com/archives/1358