【精品教程】Cocos2d-x v3.6制作射箭游戲(一)
最近玩了一個叫做大箭師鮑比的射箭游戲,覺得蠻好玩的,對此也產(chǎn)生了強(qiáng)烈的copy情結(jié)。所以從今天開始,我們將開始新的篇章,同大家分享這款基于 Cocos2d-x-3.6 引擎的游戲的一些制作心得,希望對大家有所幫助。
下圖是原版游戲的效果圖,有興趣的童鞋可以在網(wǎng)上找來玩玩。
PS:之前已寫過多次教程,現(xiàn)如今本人當(dāng)然還是覺得寫初級教程要得心應(yīng)手些(呵呵,畢竟能力所限),不過初級的寫的次數(shù)多了,也稍微有些厭煩了。所以,本教程我們將加大進(jìn)度,游戲中所涉及到的一些基礎(chǔ)概念我們將不會做過多的陳述(當(dāng)然必要的步驟還是會列舉出來的)。所以小白同志們注意了,如果根不上進(jìn)度的請先看看基礎(chǔ)教程哦,這里推薦本人之前寫過的SLG游戲作為入門教程。
那么,下面我們就正式進(jìn)入到游戲的開發(fā)吧。
前期須知
首先,本游戲所用引擎版本為 Cocos2d-x v3.6 ,開發(fā)工具用的是Xcode 5.1。
開發(fā)環(huán)境未配置的童鞋請先移步到這里將環(huán)境配置好。
Cocos2d-x 3.6 創(chuàng)建項(xiàng)目的方式與它之前的幾個版本并沒有什么區(qū)別,打開終端(Windows下是打開cmd)進(jìn)入到引擎文件夾目錄,運(yùn)行setup.py,然后再輸入以下命令行就可以創(chuàng)建一個新項(xiàng)目。
- cocos new arrowGame -p com.cocos2dx.rs -l cpp -d /Users/cocos2d-x/workspace/cocos2dx/projects
new:new后是項(xiàng)目名
-p :-p后是包名
-l :-l后是語言(cpp指c++)
-d :-d后是項(xiàng)目生成路徑
項(xiàng)目初配置
在新建的項(xiàng)目中已經(jīng)有一些默認(rèn)的文件和類,比如這里的 HelloWorldScene 類。它對于我們是沒用的,所以你可以把它刪除,然后再新建一個需要的游戲場景類。
在進(jìn)行以上操作的時候,我們需要修改 AppDelegate.cpp 文件中相應(yīng)的方法來啟動新建的游戲場景。如現(xiàn)在我們新建一個游戲場景類并命名為 GameScene,那么在 AppDelegate.cpp 文件的 applicationDidFinishLaunching() 方法中,我們需要***個就啟動它,而不是啟動原來的 HelloWorldScene。所以如下代碼所示修改 runWithScene 的場景:
- auto scene = GameScene::createScene();
- director->runWithScene(scene);
另外,本游戲所用游戲資源是按 864 * 480 的大小制作的,所以為了讓這套資源能應(yīng)用到市場上各類分辨率大小的移動設(shè)備,接下來我們需要做的事是進(jìn)行分辨率適配。
分辨率適配同樣在 applicationDidFinishLaunching 方法中進(jìn)行,只需添加以下兩行代碼:
- glview->setDesignResolutionSize(480.0f, 320.0f, ResolutionPolicy::FIXED_HEIGHT);
- director->setContentScaleFactor(480.0f / 320.0f);
這里具體的原理我就不解釋了,請大家參考我之前的文章。
GameScene 場景分析
GameScene 場景是本游戲的主場景,開始游戲之前,我們先從原游戲的游戲場景中看看我們需要做些什么?
首先,對于游戲地圖,這里有一些排布整齊的磚塊、箱子、障礙物之類的圖塊??吹竭@個你是不是跟我一樣,***反應(yīng)就是用 TiledMap 編輯器來編輯。不管你是不是,反正我是了,而且我也決定要用了。這樣一來,游戲中玩家和敵人的位置我們也可以通過 TiledMap 的對象屬性來標(biāo)識了。
然后,游戲中玩家射出去的箭是呈拋物線射出去的,一般大家都會覺得這個功能只要讓箭執(zhí)行貝塞爾動作就可以實(shí)現(xiàn)。但不要忘了,箭在按曲線移動的時候它的角度也在不停的變換,所以我們不能單純的認(rèn)為很簡單,這個需要另辟蹊徑,重寫自己需要的貝塞爾動作!
當(dāng)箭射出去后,它碰到磚塊、箱子時會有個一定的反彈效果,所以很顯然這里我們需要用物理引擎來實(shí)現(xiàn)這個模塊的功能。
先就分析到這里,下面我們來看看 GameScene 的聲明。
GameScene的聲明
其實(shí) GameScene 與 HelloWorldScene 差不多,其初定義如下:
- #include "cocos2d.h"
- USING_NS_CC;
- class GameScene : public Layer
- {
- public:
- GameScene();
- static cocos2d::Scene* createScene();
- virtual bool init();
- void addGameBg();
- CREATE_FUNC(GameScene);
- private:
- Size winSize; // 窗口尺寸
- TMXTiledMap *map; // 地圖背景對象
- TMXObjectGroup * objectGroup; // 對象組對象
- float objectPosOffX; // 對象組X方向上的偏移值
- };
在 addGameBg 方法中我們將載入游戲背景,這里我們把游戲背景分為如下的兩部分,一部分是背景圖片,另一部分是地圖背景。這樣的組合有利于關(guān)卡設(shè)計中多樣性的搭配。
#p#
地圖背景
地圖背景是用 TiledMap 編輯器制作出來的,本游戲中它是由27*15個相同大小的圖塊(32*32)組合而來(透明的地方?jīng)]有圖塊)。從上圖你也可以看出,我們已在地圖上設(shè)置了當(dāng)前關(guān)卡地形的大致布局。另外,我們之前不是說好要用 TiledMap 的對象屬性來標(biāo)識玩家和敵人的位置嗎,下面就是 TiledMap 中添加了對象的例子。
注意:對象是為了能讓開發(fā)更方便而設(shè)計的,它并不對應(yīng)于某個地圖圖片,只是標(biāo)明了某個透明物體的位置/形狀/大小等屬性,這樣開發(fā)者就可以通過相關(guān) API 獲取某個對象的位置,從而在相應(yīng)的位置繪制真實(shí)看的見的 Node 對象了。我們在制作 TiledMap 地圖時,可以想上圖一樣給對象取一個標(biāo)示它的名字,這樣我們就可以通過對象的名字來獲取到它的位置等信息了。對象常常用于添加除背景以外的游戲元素(如道具、障礙物等)。
創(chuàng)建教程中的地圖大致可分為以下兩個步驟:
- 創(chuàng)建普通圖層 “logicLayer”,我們在這上邊放置看的到的圖塊。如地圖中的磚塊、箱子、草地等等。這里我們可以根據(jù)自己的想法,創(chuàng)建出各種類型的地圖樣式。
- 創(chuàng)建對象層“object”,同時在對象層上創(chuàng)建各個對象,并給每個對象添加名字屬性。
初學(xué)者如果想了解更多詳細(xì)的地圖制作過程,可參考Quick-Cocos2d-x初學(xué)者游戲教程(七)一文。
載入程序
介紹了地圖背景之后,接下來我們就來看看 addGameBg 的實(shí)現(xiàn),如下所示:
- void GameScene::addGameBg(){
- // 添加圖片背景,把它放在屏幕正中間
- Sprite* spGameBg = Sprite::create("bg1.jpg");
- spGameBg->setPosition(Vec2(winSize.width/2, winSize.height/2));
- this->addChild(spGameBg, -1);
- // 添加地圖背景,把它放在屏幕正中間
- map = TMXTiledMap::create("map1.tmx");
- map->setAnchorPoint(Vec2(0.5f, 0.5f));
- map->setPosition(Vec2(winSize.width / 2, winSize.height/2));
- this->addChild(map, -1);
- // 獲取 objectGroup 對象(也就是地圖中的對象層)
- objectGroup = map->getObjectGroup("object");
- // 計算對象組在 X 方向上的偏移值
- objectPosOffX = -(map->getContentSize().width - winSize.width) / 2;
- }
將 TiledMap 制作出的 .tmx 地圖文件加載到游戲中需要用到 Cocos2dx 提供的 TMXTiledMap 類,它可以直接通過 .tmx 文件名來創(chuàng)建瓦片地圖。
TMXTiledMap 類有很多方法可以操控我們的 地圖文件,如上代碼所示的 getObjectGroup 方法,它可以獲取對應(yīng)名稱的對象層。
這里需要特別說明的是 objectPosOffX 這個屬性。由于對象組中對象的位置坐標(biāo)是從屏幕的(0, 0)點(diǎn)開始的,所以當(dāng)我們把地圖背景放置在屏幕中間時,地圖可能超出屏幕外或不足填滿整個窗口,這時對象的坐標(biāo)就可能會出現(xiàn)如下圖所示的偏移。
所以,我們需要計算出對象的偏移值,以便后面獲取對象時修正它的位置。
好了,此時你在 init 方法中調(diào)用 addGameBg() 就可以看到游戲背景了。
PS:是不是覺得背景兩邊被裁減了,是的,不過不要以為出錯了,因?yàn)槲覀円木褪沁@個效果,這是分辨率適配下選擇 FIXED_HEIGHT 模式的后遺癥。這也是為什么我們要計算對象組在 X 方向上的偏移值的原因。
這章就講到這里,下章我將添加射箭的玩家,敬請期待。