天天看點

cocos2d-x 學習筆記——瓦片地圖TiledMapcocos2d-x 學習筆記——瓦片地圖TiledMap

` 轉

cocos2d-x 學習筆記——瓦片地圖TiledMap

2016年08月07日 16:14:08 閱讀數:4804 标簽: cocos2d-x TiledMap 瓦片地圖 更多 個人分類: cocos2d-x

本文出自 “夏天的風” 部落格,轉載時請務必保留此出處:http://shahdza.blog.51cto.com/2410787/1613527

【唠叨】

    還記得我們小時候玩的小霸王裡面的遊戲嗎?大部分都是基于Tile地圖的遊戲,如坦克大戰、冒險島、魂鬥羅、吞食天地等。而在手遊中,基于瓦片地圖的遊戲也很常見。如:《保衛蘿蔔》。

    瓦片地圖有專門的地圖編輯器:Tiled Map Editor 。

    先給大家看個酷炫的圖吧。

cocos2d-x 學習筆記——瓦片地圖TiledMapcocos2d-x 學習筆記——瓦片地圖TiledMap

此圖來自:http://blog.csdn.net/aa4790139/article/details/8135831

【參考】

    http://cn.cocos2d-x.org/tutorial/lists?id=70    (制作基于TileMap的遊戲)

    http://cn.cocos2d-x.org/article/index?type=cocos2d-x&url=/doc/cocos-docs-master/manual/framework/native/v3/tiled-map/zh.md    (瓦片地圖使用經驗總結)

    http://cn.cocos2d-x.org/tutorial/show?id=1516    (使用瓦片地圖詳解)

【代碼實踐】

    瓦片地圖的應用十分廣泛,其知識點也非常豐富。

    是以我建議在代碼實踐中,邊寫邊學,并掌握其基本的用法。

    然後再深入研究,效果更佳。

    推薦教程: http://cn.cocos2d-x.org/tutorial/lists?id=70

【瓦片地圖——概念篇】

    在看這部分的概念知識之前,首先保證你已經學習過上面代碼實踐中推薦的那篇教程。

    因為接下來本文所要介紹的知識是:對瓦片地圖基本概念的總結以及深化。

    本文不再贅述地圖編輯器如何使用,或是怎麼将瓦片地圖導入Cocos工程中使用,之類的問題。

1、地圖格式

    (1)支援 TMX檔案格式 的瓦片地圖。(這也是推薦使用的檔案格式)

    (2)建議瓦片的塊大小為32 * 32的倍數。

cocos2d-x 學習筆記——瓦片地圖TiledMapcocos2d-x 學習筆記——瓦片地圖TiledMap

2、地圖方向

    地圖編輯器可以制作三類地圖:普通地圖(直90°) 、 斜45°地圖 、 斜45°交錯地圖。

    除此之外,而Cocos引擎還支援六邊形地圖。

    (1)普通地圖(直90°)

cocos2d-x 學習筆記——瓦片地圖TiledMapcocos2d-x 學習筆記——瓦片地圖TiledMap

    (2)斜45°地圖

cocos2d-x 學習筆記——瓦片地圖TiledMapcocos2d-x 學習筆記——瓦片地圖TiledMap

    (3)斜45°交錯地圖

cocos2d-x 學習筆記——瓦片地圖TiledMapcocos2d-x 學習筆記——瓦片地圖TiledMap

    (4)支援六邊形地圖

cocos2d-x 學習筆記——瓦片地圖TiledMapcocos2d-x 學習筆記——瓦片地圖TiledMap

3、瓦片地圖坐标系

    瓦片地圖的坐标系為:

        > 原點:在左上角。

        > 機關:瓦片數量。

        > X軸正方向:從左到右。

        > Y軸正方向:從上到下。

    例如:對于一個 10*10 的瓦片地圖檔案的坐标系統為:(0, 0)左上角、(9, 9)右下角。    

    PS:具體坐标表示,已在上面的幾幅圖中标出。

    另外,在地圖編輯器中,其實也已經标出了瓦片的坐标。

    滑鼠移動到某瓦片格子上,左下角就會顯示格子的坐标,以及所使用的瓦片素材的GID(關于GID,後面會介紹)。

    如下如所示,被選中瓦片格子的坐标為(2,3),所使用的瓦片素材GID為29。

cocos2d-x 學習筆記——瓦片地圖TiledMapcocos2d-x 學習筆記——瓦片地圖TiledMap

4、地圖層(TMXLayer)

    瓦片地圖支援地圖層(TMXLayer)、對象層(TMXObjectGroup)。

    (1)每一個地圖層可以被表示為TMXLayer類,并設定了名稱。(如下圖有三個地圖層:Meta、Foreground、BackGround)。

    (2)每一個單一的瓦片被表示為Sprite類,父節點為TMXLayer。

    (3)每一個地圖層隻能由一套瓦片素材組成,否則會出問題。(如下面的右圖所示,有兩套瓦片素材(tile、meta),但是一個地圖層隻能使用一套瓦片素材)。

cocos2d-x 學習筆記——瓦片地圖TiledMapcocos2d-x 學習筆記——瓦片地圖TiledMap
cocos2d-x 學習筆記——瓦片地圖TiledMapcocos2d-x 學習筆記——瓦片地圖TiledMap

5、對象層(TMXObjectGroup)

    (1)用來添加除背景以外的遊戲元素資訊,如道具、障礙物等對象。

    (2)一個對象層可以添加多個對象,每個對象的區域形狀的機關是:像素點。

    (3)對象層中的對象在TMX檔案中以鍵值對(key-value)形式存在,是以可以直接在TMX檔案中對其進行修改。

cocos2d-x 學習筆記——瓦片地圖TiledMapcocos2d-x 學習筆記——瓦片地圖TiledMap

6、瓦片的全局辨別GID

    在Cocos遊戲中,每一個瓦片素材都有一個全局唯一辨別GID,而瓦片的GID就是表示該瓦片所使用的是哪個GID的圖塊素材。(如上面第三小節提到的那幅圖)

    GID的計數從1開始,按順序編号,一直編号到圖塊的總數量。如下圖的tile圖塊資源中的 ID = 0 的圖塊編号 GID = 1,以此類推…… tile圖塊資源中最後一個 ID = 47 的圖塊對應的GID = 48。

    然後對于第二套meta圖塊資源中的 ID = 0 的圖塊,對應的 GID = 49。(是的,繼續編号下去……)

cocos2d-x 學習筆記——瓦片地圖TiledMapcocos2d-x 學習筆記——瓦片地圖TiledMap
cocos2d-x 學習筆記——瓦片地圖TiledMapcocos2d-x 學習筆記——瓦片地圖TiledMap
cocos2d-x 學習筆記——瓦片地圖TiledMapcocos2d-x 學習筆記——瓦片地圖TiledMap

7、瓦片地圖的屬性值(Properties)

    瓦片地圖由許多子產品構成(瓦片地圖、地圖層、對象層、瓦片圖塊、瓦片、對象),其結構圖見下面《代碼篇》那張圖。

    每一個子產品都可以設定自定義的屬性值(Custom Properties)。我想你在學習《代碼實踐》中那篇教程時,肯定也設定了自定義的屬性。(給瓦片圖塊設定“碰撞檢測”屬性、給對象層的某一對象設定“敵人類型”屬性等等……)

    這些自定義的屬性可以在地圖編輯器中進行設定,并且可以在代碼中擷取這些屬性以及對應的屬性值。

    隻要點選“目标”,就可以看到它的屬性,并且可以添加自定義屬性(Custom Properties)。

cocos2d-x 學習筆記——瓦片地圖TiledMapcocos2d-x 學習筆記——瓦片地圖TiledMap

【瓦片地圖——代碼篇】

    瓦片地圖的整體結構圖如下:

cocos2d-x 學習筆記——瓦片地圖TiledMapcocos2d-x 學習筆記——瓦片地圖TiledMap

1、TMXTiledMap

    TMXTiledMap類為瓦片地圖類。其中包含了所有的地圖層、對象層、以及瓦片地圖的尺寸資訊。

    其中:

        > MapSize :瓦片地圖的尺寸。(以瓦片數量為機關)

        > TileSize  :瓦片的尺寸。(以像素點為機關)

    核心函數如下:

  1. //
  2. class CC_DLL TMXTiledMap : public Node {
  3. /**
  4. * 建立TMX瓦片地圖
  5. **/
  6. // 使用 .tmx 格式的檔案建立瓦片地圖
  7. static TMXTiledMap* create(const std::string& tmxFile);
  8. /**
  9. * 擷取瓦片地圖的屬性資訊
  10. **/
  11. // 擷取 瓦片地圖的指定名稱的屬性值
  12. Value getProperty(const std::string& propertyName) const;
  13. // 擷取 瓦片地圖的所有屬性。(鍵-值對)
  14. void setProperties(const ValueMap& properties); // 可以修改屬性
  15. ValueMap& getProperties();
  16. // 擷取 瓦片地圖的尺寸。(機關:瓦片數量,而不是像素)
  17. void setMapSize(const Size& mapSize);
  18. Size& getMapSize() const;
  19. // 擷取 單個瓦片的尺寸。(機關:像素)
  20. void setTileSize(const Size& tileSize);
  21. Size& getTileSize() const;
  22. // 通過GID擷取圖塊的屬性,傳回Value字典。
  23. // 其實傳回的是:ValueMap,即(鍵-值對)。
  24. Value getPropertiesForGID(int GID) const;
  25. /**
  26. * 擷取地圖層、對象層
  27. **/
  28. // 擷取 指定名稱的地圖層 TMXLayer
  29. TMXLayer* getLayer(const std::string& layerName) const;
  30. // 擷取 指定名稱的對象層 TMXObjectGroup
  31. TMXObjectGroup* getObjectGroup(const std::string& groupName) const;
  32. // 擷取 瓦片地圖的所有對象層。傳回對象數組 Vector<TMXObjectGroup*>
  33. void setObjectGroups(const Vector<TMXObjectGroup*>& groups);
  34. Vector<TMXObjectGroup*>& getObjectGroups() const;
  35. };
  36. //

2、TMXLayer

    TMXLayer類為地圖層類。包含了該地圖層中,每個瓦片格子的資訊。

    其中:

        > 每一個瓦片(Tile):都被表示為Sprite類。

    核心函數如下:

  1. //
  2. class CC_DLL TMXLayer : public SpriteBatchNode {
  3. /**
  4. * 擷取地圖層的屬性資訊
  5. **/
  6. // 擷取 地圖層的名字
  7. void setLayerName(const std::string& layerName); // 可以重新設定地圖層名字
  8. std:: string& getLayerName();
  9. // 擷取 地圖層的propertyName屬性值
  10. Value getProperty(const std::string& propertyName) const;
  11. // 擷取 地圖層的所有自定義屬性字典。(鍵-值對)
  12. void setProperties(const ValueMap& properties);
  13. ValueMap& getProperties();
  14. // 擷取地圖層尺寸。一般等于瓦片地圖的尺寸。(機關:瓦片數量)
  15. void setLayerSize(const Size& size);
  16. Size& getLayerSize() const;
  17. // 設定瓦片尺寸的大小。一般與瓦片地圖的瓦片尺寸是一樣的。(機關:像素)
  18. void setMapTileSize(const Size& size);
  19. Size& getMapTileSize() const;
  20. /**
  21. * 對地圖層的瓦片進行操作
  22. **/
  23. // 擷取 指定tile坐标的瓦片(Sprite)
  24. Sprite* getTileAt(const Vec2& tileCoordinate);
  25. // 可通過調用如下對其進行删除:
  26. // layer->removeTileAt(Vec2(x,y));
  27. // 或 layer->removeChild(sprite, cleanup);
  28. void removeTileAt(const Vec2& tileCoordinate);
  29. void removeChild(Node* child, bool cleanup) override;
  30. // 擷取 指定tile坐标的瓦片對應的OpenGL坐标位置
  31. Vec2 getPositionAt(const Vec2& tileCoordinate);
  32. // 設定 指定tile坐标的瓦片,将其圖檔變為GID的圖塊。
  33. void setTileGID(uint32_t gid, const Vec2& tileCoordinate);
  34. // 擷取 指定tile坐标的瓦片,所使用的圖塊的GID。
  35. uint32_t getTileGIDAt( const Vec2& tileCoordinate);
  36. };
  37. //

3、TMXObjectGroup

    TMXObjectGroup類是對象層類。包含了該對象層中,每個對象的資訊。

    其中:

        > 每一個對象:其所有屬性,被存儲為ValueMap,即鍵-值對 的映射。

    核心函數如下:

  1. //
  2. class CC_DLL TMXObjectGroup : public Ref {
  3. /**
  4. * 擷取對象層的屬性資訊
  5. **/
  6. // 擷取 對象層的名稱
  7. void setGroupName(const std::string& groupName); // 可以重新設定對象層名稱
  8. std:: string& getGroupName();
  9. // 擷取 對象層的propertyName屬性值
  10. Value getProperty(const std::string& propertyName) const;
  11. // 擷取 對象層所有屬性。(鍵-值對)
  12. void setProperties(const ValueMap& properties);
  13. ValueMap& getProperties();
  14. /**
  15. * 擷取對象層的 對象
  16. **/
  17. // 擷取對象層指定的objectName對象,其所有屬性被存儲為ValueMap(鍵-值對)
  18. ValueMap getObject(const std::string& objectName) const;
  19. // 擷取對象層的所有對象
  20. void setObjects(const ValueVector& objects);
  21. ValueVector& getObjects();
  22. };
  23. //

4、關于瓦片地圖的錨點位置

    瓦片地圖的錨點預設為( 0,0),每個瓦片的錨點預設也為(0,0)。

    PS:錨點是可以設定的,因為它不是繼承于Layer,而是直接繼承于Node。

    下面講解一下預設錨點的位置資訊。

    (1)普通瓦片錨點資訊

cocos2d-x 學習筆記——瓦片地圖TiledMapcocos2d-x 學習筆記——瓦片地圖TiledMap

    (2)斜45°瓦片錨點資訊

cocos2d-x 學習筆記——瓦片地圖TiledMapcocos2d-x 學習筆記——瓦片地圖TiledMap

    (3)斜45°交錯瓦片錨點資訊

cocos2d-x 學習筆記——瓦片地圖TiledMapcocos2d-x 學習筆記——瓦片地圖TiledMap

5、Tile坐标 與 OpenGL坐标 互相轉換

    這裡介紹一下普通瓦片(直90°)的坐标轉換。

    至于,斜45°的瓦片地圖,自己推公式把。。。

  1. //
  2. // OpenGL坐标:原點為螢幕左下角(機關:像素)
  3. // tile坐标:原點為瓦片地圖的左上角(機關:瓦片)
  4. // OpenGL坐标 轉成 格子坐标
  5. Vec2 tileCoordForPosition(const Vec2& position) {
  6. Size mapSize = tiledMap->getMapSize();
  7. Size tileSize = tiledMap->getTileSize();
  8. int x = position.x / tileSize.width;
  9. int y = (mapSize.height * tileSize.height - position.y) / tileSize.height;
  10. return Vec2(x, y);
  11. }
  12. // tile坐标 轉成 瓦片格子中心的OpenGL坐标
  13. Vec2 positionForTileCoord(const Vec2& tileCoord) {
  14. Size mapSize = tiledMap->getMapSize();
  15. Size tileSize = tiledMap->getTileSize();
  16. int x = tileCoord.x * tileSize.width + tileSize.width/ ;
  17. int y = (mapSize.height - tileCoord.y) * tileSize.height - tileSize.height/ ;
  18. return Vec2(x, y);
  19. }
  20. //

6、遮罩關系

    瓦片地圖可以包含許多個地圖層,那麼地圖層的遮罩關系是怎麼确定的呢?

    (1)地圖層之間的遮罩關系

    如下圖所示,每個地圖層的 zOrder(渲染順序)會根據在地圖編輯器中設定的前後關系進行設定。由下往上設定 zOrder 值,最靠後的 zOrder = 0,随後每個圖層zOrder+1。

cocos2d-x 學習筆記——瓦片地圖TiledMapcocos2d-x 學習筆記——瓦片地圖TiledMap

    (2)瓦片之間的遮罩關系

        其 zOrder(渲染順序)的值如下所示。

        也就是說渲染順序為:從左往右,從上到下。

        即:下邊的瓦片可以遮住上邊的瓦片,右邊的瓦片可以遮住左邊的瓦片。

cocos2d-x 學習筆記——瓦片地圖TiledMapcocos2d-x 學習筆記——瓦片地圖TiledMap

【函數使用舉例】

1、瓦片地圖類(TMXTiledMap)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
  1. //
  2. // TMXTiledMap::create()
  3. // 加載TMX瓦片地圖
  4. tileMap = TMXTiledMap::create( “TileMap.tmx”);
  5. this->addChild(tileMap, );
  6. // tileMap->getMapSize()、getTileSize()
  7. // 擷取一個瓦片的尺寸
  8. tileSize = tileMap->getTileSize();
  9. // 擷取地圖的尺寸大小(轉為像素點大小)
  10. // tileMap->getMapSize() 為擷取地圖寬高的瓦片數量
  11. tileMapSize = Size(tileMap->getMapSize().width * tileSize.width,
  12. tileMap->getMapSize().height * tileSize.height);
  13. // tileMap->getPropertiesForGID()
  14. // 擷取圖塊素材的 GID=49 的所有自定義屬性
  15. auto properties = tileMap->getPropertiesForGID( ).asValueMap();
  16. for( auto& value : properties) {
  17. CCLOG( “Properties:%s, %s”, value.first.c_str(), value.second.asString().c_str());
  18. }
  19. // tileMap->getLayer()
  20. // 擷取背景層、前景層、元層
  21. backGround = tileMap->getLayer( “Background”);
  22. foreGround = tileMap->getLayer( “Foreground”);
  23. meta = tileMap->getLayer( “Meta”);
  24. // tileMap->getObjectGroup()
  25. // 擷取對象層
  26. objects = tileMap->getObjectGroup( “Objects”);
  27. //

2、地圖層類(TMXLayer)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  1. //
  2. // backGround->getTileAt()
  3. // 擷取瓦片(Sprite),進行放縮
  4. Sprite* sp = backGround->getTileAt(Vec2( , ));
  5. sp->setScale( );
  6. // backGround->setTileGID
  7. // 将(5,17)位置的瓦片,圖檔設定為 GID=46 的圖塊素材
  8. unsigned int gid = ;
  9. backGround->setTileGID(gid, Vec2( , ));
  10. // backGround->getTileGIDAt
  11. // 擷取(2,19)位置的瓦片,所使用的圖塊素材的GID
  12. gid = backGround->getTileGIDAt(Vec2( , ));
  13. CCLOG( “gid = %d”, gid);
  14. //

3、對象層類(TMXObjectGroup)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

  1. //
  2. // objects->getObject()
  3. // 擷取HeroInfo對象
  4. ValueMap heroInfo = objects->getObject( “HeroInfo”);
  5. // 擷取坐标 x,y 屬性
  6. float x = heroInfo[ “x”].asFloat();
  7. float y = heroInfo[ “y”].asFloat();
  8. // 建立主角
  9. hero = Sprite::create( “Player.png”);
  10. hero->setPosition(x, y);
  11. tileMap->addChild(hero);
  12. // objects->getObjects()
  13. // 添加敵人
  14. // getObjects:擷取對象數組 ValueVector
  15. for ( auto&enemy : objects->getObjects()) {
  16. // 擷取對象的屬性
  17. ValueMap& dict = enemy.asValueMap();
  18. if (dict[ “Enemy”].asInt() == ) { // 自定義屬性“Enemy”
  19. x = dict[ “x”].asFloat(); // x坐标
  20. y = dict[ “y”].asFloat(); // y坐标
  21. this->addEnemyAtPos(Vec2(x, y));
  22. }
  23. }
  24. //