瓦片地图 TMX 使用详解(图文)

cocos2d-x 3.0版本以上的请参考这两个文章

[1]瓦片地图官方文档:http://cn.cocos2d-x.org/article/index?type=cocos2d-x&url=/doc/cocos-docs-master/manual/framework/native/v3/tiled-map/zh.md

[2]瓦片地图讲解:http://shahdza.blog.51cto.com/2410787/1613527

我的这个是基于 cocos2d-x 2.2.6说的,因为以前不会用,这两天专门看了看。

【1】瓦片地图的创建

wKiom1TaCJqxQvJfAAD0Q9tVYY4277.jpg

1.首选 tmx 文件

2.大小建议是32*32的倍数

【2】瓦片地图的方向

wKiom1TaARXgxWO9AAHYH4xOOsQ834.jpg

图2

瓦片地图的开始是从左上角开始,右下角结束的,如图2所示

【3】地图的搭建

wKiom1TaB52CVlw-AAD57LWZGqc629.jpg

地图是分几个层的,然后不同的层的显示也不同,越在上,他的 Zorder 也是越大,也就是显示的最靠外

wKiom1TaDFKjrto2AADtW7XanOg526.jpg

这个需要注意的是,一个层里面只能用一个切图里的东西,不能使用多个切图里的图片,比如说图层 background用了图1的这个大的贴图,那么就不能在使用图2里面的贴图,否则会报错的

【4】地图属性

属性是地图最有用的,也是主要的功能,通过属性来获得各个不同的特点判断和操作

屏幕快照 2015-05-07 10.52.29.png

图4.图层设置属性

在图层里面设置属性,是直接设置的贴图的属性,因为图层主要是用来铺背景或者道路用的,所以直接设置的图块属性

屏幕快照 2015-05-07 10.52.46.png

图5.对象层设置属性

对象层是一个个不同的对象,比如说英雄,怪物等,所以是直接针对具体的对象设置属性。

【5】地图gid 的介绍

每一个瓦片素材都有一个全局唯一标识GID,而瓦片的GID就是表示该瓦片所使用的是哪个GID的图块素材。GID的计数从1开始,按顺序编号,一直编号到图块的总数量。如下图的tile图块资源中的 ID = 0 的图块编号 GID = 1,以此类推…… tile图块资源中最后一个 ID = 47 的图块对应的GID = 48。然后对于第二套图块资源中的 ID = 0 的图块,对应的 GID = 49。继续编号下去…

【6】代码操作

地图创建完毕后,就用来使用的

[1]MAP操作

特别要注意的是:


CCSize size = map->getMapSize();//获取瓦片地图数量,单位不是像素
CCSize tilesize =map->getTileSize();//单个瓦片的大小,单位是像素


map 的主要函数


CCTMXLayer* layerNamed(const char *layerName);
CCTMXObjectGroup* objectGroupNamed(const char *groupName);
CCString *propertyNamed(const char *propertyName);
CCDictionary* propertiesForGID(int GID);


map 的创建


CCTMXTiledMap *map=CCTMXTiledMap::create("1.tmx");
    map->setAnchorPoint(CCPoint(0.5, 0.5));
    map->setPosition(CCPoint((origin.x+visibleSize.width)/2, (origin.y+visibleSize.height)/2));
    addChild(map);


然后添加到 layer

[2]CCTMXLayer

图层一般只是做背景,所以一般是判断对应的坐标是否有图层,和图层属性,用来判断是悬崖还是路,所以最主要的是这样用的


//获取 layer
    CCTMXLayer *ground=map->layerNamed("ground");
//属性函数
CCString *propertyNamed(const char *propertyName);


[3]对象层

对象层是主要的操作对象,所以也是主要设置的功能,比如说在指定的那个对象加英雄

 //获取对象层
    CCTMXObjectGroup *obj=map->objectGroupNamed("coin");
    //获取对象名为 huhu 的 b 属性
    CCLog("%d",obj->objectNamed("huhu")->valueForKey("b")->intValue());
    //获取对象层所有对象的坐标
        for (int i=0; i<obj->getObjects()->count(); i++) {
        CCSprite *sprite=CCSprite::create("Icon-s.png");
            float x  = ((CCDictionary*)obj->getObjects()->objectAtIndex(i))->valueForKey("x")->floatValue();
            float y =((CCDictionary*)obj->getObjects()->objectAtIndex(i))->valueForKey("y")->floatValue();
            sprite->setPosition(CCPoint(x, y));
            addChild(sprite);
    }



【7】获取对应坐标对应的属性

//获取对应坐标对应的属性,比如获取(200,100)这个坐标对应的瓦片的属性;
    
    CCSize size = map->getMapSize();//获取瓦片地图数量,单位不是像素
    CCSize tilesize =map->getTileSize();//单个瓦片的大小,单位是像素
    int x= 200/tilesize.width;
    int y= size.height-100/tilesize.height-1;//记得要减一
    CCLog("%d,%d",x,y);
    int gid = ground->tileGIDAt(ccp(x, y));//获取 gid
    CCLog("%d",gid);
    if (gid!=0) {
        map->propertiesForGID(gid);//一个字典
        //获取 x 坐标
        map->propertiesForGID(gid)->valueForKey("x")->intValue();
    }



【8】为什么 y 轴减一

屏幕快照 2015-05-07 16.00.57.png

图7



【9】Tile坐标 与 OpenGL坐标 相互转换

普通瓦片(直90°)的坐标转换

//
    // OpenGL坐标:原点为屏幕左下角(单位:像素)
    // tile坐标:原点为瓦片地图的左上角(单位:瓦片)
 
    // OpenGL坐标 转成 格子坐标
    Vec2 tileCoordForPosition(const Vec2& position) {
        Size mapSize = tiledMap->getMapSize(); 
        Size tileSize = tiledMap->getTileSize();
        int x = position.x / tileSize.width;
        int y = (mapSize.height * tileSize.height - position.y) / tileSize.height-1;
        return Vec2(x, y);
    }
 
    // tile坐标 转成 瓦片格子中心的OpenGL坐标
    Vec2 positionForTileCoord(const Vec2& tileCoord) {
        Size mapSize = tiledMap->getMapSize(); 
        Size tileSize = tiledMap->getTileSize();
        int x = tileCoord.x * tileSize.width + tileSize.width/2;
        int y = (mapSize.height - tileCoord.y) * tileSize.height - tileSize.height/2;
        return Vec2(x, y);
    }
//


Demo下载

Github下载:https://github.com/DamonHu/HudongTmxDemo

GitOsc下载:http://git.oschina.net/DamonHoo/HudongTmxDemo

Last modification:January 1st, 1970 at 08:00 am
如果看了这个文章可以让你少加会班,可以请我喝杯可乐
已打赏名单
微信公众号

Leave a Comment