知易遊戲開發教程cocos2d-x移植版005(下)

原文:http://www.cnblogs.com/cocos2d-x/archive/2012/05/18/2508457.html


這一節,我們將使用cocos2d-x開發一個有關瓦片地圖的示例。

在這個示例當中,我們需要完成以下功能:
1)TMX地圖的加載與顯示。
2)在地圖中游走。
3)搞點兒小破壞,動態修改地圖。

內部規則

在開始之前,我們還需要了解一些TMX地圖的內部規則。

1)座標

在TMX地圖中,座標是從零開始計算的,左上角那一塊的座標爲(0,0),右下角那一塊的座標爲(寬度-1,高度-1)。

看到上面這張截圖時請不要驚慌,Qt版的確不能在每個格子上顯示座標,這圖是我拼接出來的。

2)“瓦片”值

如果要操作地圖上的元素,我們還需要知道每個瓦片的內容,即瓦片值。

用文本編輯工具打開之前繪製的坦克大戰的地圖,其實就是一個xml文件。

圖中用紅線標記的這個屬性“firstgid”的值爲"1",也就是說瓦片集中的瓦片是從一開始編號的。

如果地圖中某一塊的GID等於零,那就說明這個地方沒有使用瓦片填充,即透明的。


下面我們學習如何在cocos2d-x中使用TMX地圖,將涉及到CCTMXLayer和CCTMXTiledMap這兩個類。

顯示地圖

要在cocos2d-x中使用TMX地圖,你只需要調用tiledMapWithTMXFile來創建一個CCTMXTiledMap對象,並把它添加到場景中。

1 // Load level map
2 gameWorld = CCTMXTiledMap::tiledMapWithTMXFile("Level1.tmx");
3 this->addChild(gameWorld, 0, 9);

是的,就是這麼簡單。編譯執行,然後地圖就出現在你面前了。

四處遊走

大家都知道,一般來說地圖的尺寸要比遊戲窗口(畫面)大一些,就好像是透過窗子在觀察遊戲裏的世界。這個窗子就是我們常說的視口。

在3D遊戲中,我們只需要將角色放置在正確的位置上,然後移動攝像機改變視口就可以了。

在2D遊戲中,我們通常的做法是,當顯示區域不在地圖邊緣時,把角色放在畫面的中心,反向移動地圖,達到角色移動的效果。當顯示區域到達地圖邊緣時,因爲畫面不能超出地圖範圍,所以這個時候我們就要真的移動角色了。

你還可以繪製一個稍微大一圈的地圖,並設置厚厚的阻擋,這樣角色就永遠不會走到地圖邊緣了。這算是個取巧的方法。

但無論採用上面哪一種方法,我們都需要一個移動地圖的方法。

通過查看CCTMXTiledMap類的聲明,我們知道CCTMXTiledMap其實就是一個CCNode,它也擁有CCNode的setPosition成員方法。調用setPosition就可以達到我們移動地圖的目的。

虛擬按鍵

爲了方便控制,我們最好再設計一組虛擬按鍵來獲取玩家的輸入操作。當然,你在這裏添加一個CCMenu也能實現類似的效果,但多少會有些限制,不如自己的虛擬按鍵方便。

在第4章中我們介紹過觸摸事件的目標代理,添加虛擬按鍵使用的就是這個方法。

我們新建一個控制層,這個層的主要作用就是處理觸摸事件。爲了玩家能直觀的看見虛擬按鍵,這個層還負責虛擬按鍵的顯示,以及切換它們的顯示狀態。畢竟不是系統提供的菜單項,這些都是需要自己處理的。

雖然有點兒繁瑣,但都是以前的知識點,所以就不貼代碼了,如有需要請參考附件

動態修改地圖

對TMX地圖進行動態修改的操作是針對層的。修改的過程就是先要找到對應的層,然後對指定座標上的GID進行修改。

複製代碼
 1 void GameLayer::ccTouchesEnded(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent)
 2 {
 3     CCTouch *pTouch = reinterpret_cast<CCTouch *>(pTouches->anyObject());
 4     // 注意,升級到cocos2d-1.0.1-x-0.13.0-beta這個版本後,下面這個locationInView()是沒有參數的。
 5     CCPoint touchPoint = CCDirector::sharedDirector()->convertToGL(pTouch->locationInView());
 6     // pt是觸摸點轉換到地圖上的座標
 7     CCPoint pt = this->tileCoordinateFromPos(ccp(touchPoint.x - mapX, touchPoint.y - mapY));
 8     if (pt.x != -1)
 9     {
10         // "tile"是我們要操作的層的名字
11         CCTMXLayer *ly = gameWorld->layerNamed("tile");
12         unsigned int gid = ly->tileGIDAt(pt);
13         if (gid != 1)
14             this->ShowExplodeAt(touchPoint);
15         if (gid == 2)
16             ly->setTileGID(5, pt);
17         if (gid == 4)
18             ly->setTileGID(6, pt);
19         if (gid == 5)
20             ly->setTileGID(4, pt);
21         if (gid == 6)
22             ly->setTileGID(1, pt);
23     }
24 }
複製代碼

上面這段代碼實現了對觸摸點顯示爆炸動畫,並根據地形不同修改爆炸後的地面顯示的功能。

小結

在這一章中,我們學會了如何加載並顯示一張TMX地圖,如果獲取某一座標的地形信息以及如何動態修改這一屬性。雖然這些只是十分基礎的地圖操作,但我們已經向着開發更復雜更有意思的遊戲又邁進了一步。

示例代碼下載:http://dl.dbank.com/c094e7ash7

代碼更新

我以前未能理解到LAYER_NODE_FUNC和SCENE_NODE_FUNC這兩個宏定義的精妙之處,所以按照知易的源代碼那樣爲MainScene類加了一個ShowScene靜態成員函數,導致遊戲中節點的關係變成了:CCScene根場景下多了一個用層實現的MainScene,然後纔是GameLayer和ControlLayer。太羅嗦了,所以這裏更新一下。

新的下載地址:http://files.cnblogs.com/cocos2d-x/ZYG005.rar

題外話

大家是不是覺得CCLayer和CCScene裏的"bool init(void);"應該改成虛函數"virtual bool init(void);"會更好一些?


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章