cocos2d 簡單高仿天天酷跑游戲
來源:程序員人生 發(fā)布時間:2014-10-10 08:00:01 閱讀次數(shù):8166次
1.先直接上視頻來看下這個游戲的樣子(GIF已經(jīng)不能滿足這個游戲的展示了)
跑酷游戲最糾結(jié)的是地圖,碰撞倒是簡單,可以自己寫或者使用box2d等物理引擎。跑酷游戲地圖的特點就是隨機性。但是隨機中又有策劃特意安排的部分,這樣讓玩家有小小驚喜。所以我就打算這樣實現(xiàn):用地圖編輯器編寫個幾十個地圖,然后洗牌掉,從第一個開始取,直到最后最后一個后,再重新洗牌,取第一個。這樣就能突出天天跑酷游戲的特點。隨機中又有特定安排。
游戲中繪制地圖當然不能一次全部完成,那樣太慢了。手機屏幕橫向就那么長,初始化兩個地圖就夠了,當快要穿幫時,趕緊繪制一個新的地圖貼在第二個地圖后面。第一個地圖移到屏幕左邊時,可以刪掉了。這樣一直保持兩個地圖就夠了。跟背景重復(fù)移動類似。
2.自定義簡單地圖編輯器
決定使用地圖編輯器后,一個問題就是使用Tiled Map 還是自己做一個。
Tiled Map讓我不喜歡的地方是它每一個方塊都是一個精靈,這樣大塊的圖片會被分割成小塊的圖,效率很低。如果使用自定義object,又不能實時看地圖效果。就嘗試自己寫一個簡單的地圖編輯器來供這個游戲使用。
我的需求:可以拖動元素擺到地圖上,然后導(dǎo)出一個文件,里面有我自定義格式的內(nèi)容,供我游戲中使用。
用什么來做是接下來的問題:
地圖編輯器可以用普通的Qt來實現(xiàn),做出來類似Tiled Map的效果。Tiled Map是開源的,可以參考它實現(xiàn)一個。但是沒時間這樣搞啊。就用cocos2d來做地圖編輯器了,當然想要實現(xiàn)非常復(fù)雜的編輯器推薦還是參考Tiled Map。
簡單地做了一個地圖編輯器的Demo,發(fā)現(xiàn)比想象中的簡單:
就是初始一些小的精靈放在最右邊,不可移動。每次touch他們的時候,生成一個新的精靈,并且這個精靈是可以拖動的。這樣就可以任意擺放了。
地圖文件數(shù)據(jù)該用什么格式來存儲呢?
大致XML,Json是我考慮的兩種。覺得Json會好點,將來做Cocos2d JS,可以直接包含進來都不需要解析。當然C++這邊還是要解析的。Cocos2d 自帶 rapid json,解析也不是問題。就決定使用json了。
數(shù)據(jù)格式大致是這樣的:
{
"Bones": [{
"positionX": 1657.18,
"positionY": 345.044
}, {
"positionX": 1522.69,
"positionY": 336.114
}, {
"positionX": 1435.41,
"positionY": 259.934
}],
"TopBlocks": [{
"positionX": 2439.34
}],
"Blocks": [{
"blockType": 2
}, {
"blockType": 0
}, {
"blockType": 2
}}]
}
地圖編輯器是下面這樣的

簡單一個列表,點擊一個地圖,就編輯一個文件。因為是跑酷游戲,所以這個地圖編輯器比較長,有3000像素左右。當然還可以往右無限移動。

3.簡單碰撞
碰撞這里我也是自己寫的,沒有用物理引擎。也比較容易。一個小技巧是給主角一個nextPositin的變量。跑酷會不斷改變這個值,通過碰撞后,才真正把角色的position值設(shè)置為nextPosition。
一張圖來說:

for(Square* square : squares){
if(hero->nextRight() >= square->getLeft()){
//右邊碰撞
if(hero->right() < square->getLeft()){
if(hero->bottom() < square->getTop() && hero->top() > square->getBottom()){
hero->fixRightColl(square);//碰撞修復(fù)和觸發(fā)事件
}
}
if(hero->left() <= square->getRight()){
//下面碰撞
if(hero->bottom() >= square->getTop() && hero->nextBottom() <= square->getTop() && hero->top() > square->getTop()){
hero->fixTopColl(square);//碰撞修復(fù)和觸發(fā)事件
}
//上面碰撞
else if(hero->top() <= square->getBottom() && hero->nextTop() >= square->getBottom() && hero->bottom() < square->getTop()){
//碰撞后做的事情
}
}
}
}
當然碰撞金幣等東西,直接判斷兩個矩形是否相交即可。
for(Bone* bone : bones){
if(hero->right() >= bone->getLeft()){
if(bone->getRect().intersectsRect(hero->getRect())){
bone->removeFromParent();
bones.eraseObject(bone);
sRunGlobal->boneCount = sRunGlobal->boneCount + 1;
RunSound::playEffect(boneEffectName);
break;
}
}
}
4.對象重復(fù)使用
跑酷游戲設(shè)計到大量的對象創(chuàng)建,消除。一定要重復(fù)使用對象,搞個簡單的緩存池就行了,可以參考這篇文《cocos2d 緩存池 對象重復(fù)使用》
最后這個不公布源碼和資源。
http://www.waitingfy.com/archives/1318
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機掃描二維碼進行捐贈