在上一節中,我們使用經典fc遊戲《坦克大戰》的元素設計了一張地圖,來演示tiled map editor工具的基本用法,並在cocos2d-x程式中完成了tmx地圖載入、檢視以及動態修改地圖元素的功能。
這一節,我們將對示例5進一步擴充、完善,使其成為能「玩」一下的遊戲。
為了這個目標,我們需要做以下調整:
1)增加雙方坦克,我方一輛,敵方八輛。
2)坦克在地圖上行走時,需要完成基本的碰撞檢測,不可以穿牆而過。
3)坦克可以開炮,炮彈可以摧毀磚牆和敵對方坦克。
4)視角鎖定在我方坦克上,顯示區域跟隨我方坦克的移動而改變。
5)敵方(電腦)坦克擁有基本的ai來增加點兒樂趣。
我們的目標只是乙個簡單的示例遊戲,所以我準備用同乙個類來表示雙方坦克,通過乙個布林型變數來區分敵我。
1作為乙個「完整」的遊戲,我們需要實現在遊戲地圖中漫遊的功能。這包含兩方面的內容,下面我們來分別描述一下。class tanksprite : public
ccsprite
2
遊戲講究乙個代入感。是誰在玩遊戲?不是上帝,我只是一輛小小的坦克。當操作指令下達時,應該是一輛坦克去完成它,而不是通過上帝的眼睛來觀察。所以,現在需要完成的功能就是讓坦克在tmx地圖上移動。
要實現這樣的功能並不困難,因為ccsprite精靈類為我們準備好的大部分內容。我們要做的只是為坦克增加當前的狀態、移動速度以及四個方向的移動函式。
1在實現四方向移動函式時,因為坦克是tmx地圖的子節點,所以座標不需要太多計算。//tankaction 是乙個列舉型別,用來表示坦克當期的狀態
2tankaction kact;
3float
movestep;
4void moveleft(gamelayer *layer);
5void moveright(gamelayer *layer);
6void moveup(gamelayer *layer);
7void movedown(gamelayer *layer);
1完成上面的功能,坦克就可以在地圖上行走了。但是我們只能看見螢幕大小的地圖,坦克很容易就走到螢幕之外去了。我們不願意做乙隻「井底之蛙」,眼睛要跟上坦克。void tanksprite::moveleft(gamelayer *layer)
2
我們前面介紹過視口這個概念,它就是整個遊戲世界向我們開啟的一扇窗子。而且,在示例5中我們也嘗試了移動視口來觀察整個遊戲地圖。我們現在要做的就是加乙個視口跟隨的功能,讓視口跟隨主角(我方)坦克車移動,將合適的地圖區域展示給我們。
縱觀大多數人的設計,對於視口跟隨,乙個普遍的做法是這樣的。
大部分時間都將主角精靈固定在視口中心,主角的移動是通過反方向移動背景地圖模擬的。只有當視口已經到達地圖邊緣,再沒有更多地圖供我們移動時,才移動主角本身。
句子有點兒拗口,沒理解的朋友請看下面的演示。
將上面的過程寫成**:
1坦克也不是說是無堅不摧的,所以遇到河啊什麼的,還是從橋上走方便一些。所以我們就得判斷是不是沒路了,是不是撞牆了,於是「碰撞檢測」的概念就引入進來了。void gamelayer::setworldposition(void)2
試想,有8輛敵方坦克正在地圖上遊蕩,他們撞牆要檢測,互相之間也要檢測,他們偶爾還會發射炮彈,每個炮彈的飛行和**也都需要檢測。而且這些都是併發進行的。哇!多麼混亂的乙個場面啊!
呵呵,其實「碰撞檢測」並沒有大家想的那麼複雜,不是說要做碰撞檢測就要弄個物理引擎進來,只要不是在實現逼真的物理效果,我們完全可以用自己的方法來檢測碰撞。
大家知道,什麼同時啊,並行啊,這些統統都是理論上的,或者說是在一定精度範圍上的東西。即便是多核cpu,在共享同一資源時,它們也要分優先順序的。所以,在小遊戲這類簡單的應用上,我們完全可以認為,一次碰撞發生時,世界是靜止的。
這樣一來,我們只需要按照一定的優先順序,順次為每乙個需要檢測碰撞的物件進行檢測即可。
對於坦克的行走來說,我們需要做的檢測只有地形乙個因素,又因為是在同一座標系下,事情灰常簡單。
考慮到坦克是有體積的,這裡取3個取樣點檢測碰撞,以避免其邊緣進入牆裡。
1瞧,那輛破坦克搖頭擺尾地開過來了,讓我們乾掉他。fire! boom...//這是坦克左移時的碰撞檢測**
2 ccpoint nextpos = ccp(tankpos.x - tanksize.width / 2
, tankpos.y);
3 unsigned int tid = layer->tileidfromposition(nextpos);
4if (tid != 4)5
return
;6 nextpos = ccp(tankpos.x - tanksize.width / 2, tankpos.y + tanksize.height / 4
);7 tid = layer->tileidfromposition(nextpos);
8if (tid != 4)9
return
;10 nextpos = ccp(tankpos.x - tanksize.width / 2, tankpos.y - tanksize.height / 4
);11 tid = layer->tileidfromposition(nextpos);
12if (tid != 4)13
return;
好吧,既然你想**,那就給每輛坦克都配上炮彈吧。
1 bulletsprite* bulletsprite::bulletwithlayer(gamelayer *layer)212雖然炮彈是坦克的配備,但是為了方便座標計算,我們將炮彈歸為地圖的子節點。換個思路想,炮彈發射後就跟坦克分離了,所以我們這麼設計也是可以接受的。cc_safe_delete(sprite);
13return
null;
14 }
理所當然的,我們還需要為每一輛坦克增加乙個**按鈕。
1大家可以看到,炮彈發射是用系統內建的moveto動作模擬的,最後一行開啟每秒30次的炮彈碰撞檢測。檢測的方法與行走時的檢測類似,這裡不再重複。void tanksprite::onfire(gamelayer *layer)
227 bullet->setposition(bulletpos);
28 bullet->setisvisible(true
);29 ccshow *ac1 =ccshow::action();
30 ccmoveto *ac2 = ccmoveto::actionwithduration(5.0f
, bullettarget);
31 bullet->runaction(ccsequence::actions(ac1, ac2, null));
32//
啟動炮彈的碰撞檢測
33this->schedule(schedule_selector(tanksprite::checkexplosion), 1.0f / 30.0f
);34 }
本章示例**基於cocos2d-1.0.1-x-0.13.0-beta編寫。雖然cocos2d-2.0-rc0a-x-2.0已經發布了,但是變動比較大,主要是得換模板嚮導,我比較懶,所以本系列結束之前,我先不換版本了。
COCOS2D 學習教程
1.在cocos2d裡面如何使用texture packer和畫素格式來優化spritesheet spritesheet.html 2.如何使用cocos2d來做乙個簡單的iphone遊戲教程 第一部分 5 程1.html 3.如何使用cocos2d開發乙個簡單的iphone遊戲 旋轉炮塔。第二部...
使用cocos2d開發iphone遊戲入門概念
簡介 cocos2d iphone是乙個開源框架,利用它可以非常容易的在iphone上開發2d遊戲。它提供了物理,精靈 sprites 時差卷軸 parallax scrolling 支援iphone touch和accelerator等很多功能。一點說明 這一系列文章,翻譯自cocos2d的wik...
使用cocos2d開發iphone遊戲入門概念
簡介 cocos2d iphone是乙個開源框架,利用它可以非常容易的在iphone上開發2d遊戲。它提供了物理,精靈 sprites 時差卷軸 parallax scrolling 支援iphone touch和accelerator等很多功能。一點說明 這一系列文章,翻譯自cocos2d的wik...