• (12)瓦片地图


    在游戏开发过程中,我们会遇到超过屏幕大小的地图,例如即时战略游戏,使得玩家可以在地图中滚动游戏画面。这类游戏通常会有丰富的背景元素,如果直接使用背景图切换的方式,需要为每个不同的场景准备一张背景图,而且每个背景图都不小,这样会造成资源浪费。

    瓦片地图就是为了解决这问题而产生的。一张大的世界地图或者背景图可以由几种地形来表示,每种地形对应一张小的的图片,我们称这些小的地形图片为瓦片。把这些瓦片拼接在一起,一个完整的地图就组合出来了,这就是瓦片地图的原理。

    TileMap方案

    在Cocos2d-x中,瓦片地图实现的是TileMap方案,TileMap要求每个瓦片占据地图上一个四边形或六边形的区域。把不同的瓦片拼接在一起,就可以组成完整的地图了。我们需要很多较小的纹理来创建瓦片。通常我们会将这些较小的纹理放在一张图片中,这样做会提高绘图性能。

    瓦片地图编辑器

    Cocos2d-x支持由瓦片地图编辑器Tiled Map Editor制作并保存为TMX格式的地图。Tiled Map Editor是一个开源项目,支持Windows、Linux及Mac OS X多个操作系统,我们可以从官网下载到编辑器的Java和QT版本。

    如何使用Tiled工具建立地图可以参考以下文章:

    如何使用Cocos2dx3.0制作基于tilemap的游戏

    地图方向

    Tiled地图支持直角鸟瞰地图(90°地图)、等距斜视地图(斜45°地图)和六边形地图,不支持左右或上下边界的六边形地图。

    地图资源

    • 建议瓦片地图素材大小为32*32的倍数
    • 瓦片素材组与其他图片不能混合使用
    • 只有瓦片素材图能被导入TMX文件
    • 每个Layer最多支持1套瓦片素材组。

    瓦片层

    • TMX文件中瓦片层的数量没有上限
    • 每一个瓦片层只能由一种瓦片素材组成
    • 每一个瓦片层可以被TMXLayer类表示-为SpriteSheet的子类
    • 每一个单一的瓦片被Sprite表示-父节点为TMXLayer

    对象层

    • 瓦片地图支持对象组
    • 用来添加除背景以外的游戏元素-道具、障碍物等
    • 对象组中的对象在TMX文件中以键值对形式存在,因此可以直接在TMX文件中对他进行修改

    瓦片地图坐标系

    对于一个16*16的瓦片地图文件的坐标系统为

    • (0, 0): 左上角
    • (15, 15): 右下角

    在Cocos2d-x中使用TMX

    创建TMX节点

        TMXTiledMap *map = TMXTiledMap::create("bg.tmx");
        addChild(map, 0);

    遍历子节点

        Vector<Node*> pChildrenArray = map->getChildren();
    
        SpriteBatchNode* child = NULL;
    
        Ref* pObject = NULL;
    
        for (Vector<Node*>::iterator it = pChildrenArray.begin(); it != pChildrenArray.end(); it++) {
            pObject = *it;
            child = (SpriteBatchNode*)pObject;
    
        }

    获取/删除一个瓦片

        TMXLayer* layer = map->getLayer("layer0");
        Sprite* tile0 = layer->getTileAt(Point(1, 15));
        layer->removeTileAt(Point(1, 15));

    遍历对象层中对象

        TMXObjectGroup* objectGroup = map->getObjectGroup("center");
        ValueVector object = objectGroup->getObjects();
    
        for (ValueVector::iterator it = object.begin(); it != object.end(); it++) {
            Value obj = *it;
            ValueMap map = obj.asValueMap();
            log("x = %d y = %d", map.at("x").asInt(), map.at("y").asInt());
        }

    Fast TileMap

    概述

    在游戏中常常会有丰富的背景元素,如果直接使用大的背景图实现,这会造成资源浪费。TileMap就是为了解决这问题而产生的。Cocos2d-x支持使用Tile地图编辑器创建的TMX格式的地图。

    Cocos2d-x为我们提供了TMXTileMap和TMXLayer两个类来处理瓦片地图。通过使用TMXTileMap和TMXLayer,我们可以很方便的加载TMX格式的地图文件,获取地图上的图层、对象、属性等信息。

    新发布的3.2版本,对瓦片地图进行了大幅改进,通过自动裁剪不在视图范围内的瓦片来提升性能,并支持渲染更大尺寸的瓦片地图!我们称之为"Fast TileMap",下面我们就来一起研究Fast TileMap。

    TileMap VS Fast TileMap

    Fast TileMap的不同

    在3.2版本,新增了CCFastTMXTiledMap.h/CCFastTMXTiledMap.cpp/CCFastTMXLayer.h/CCFastTMXLayer.cpp文件用于实现快速高效的瓦片地图功能。

    在cocos2d::experimental的名字空间下重新实现了TMXTiledMap和TMXLayer。其中对TMXLayer的改动较大。TMXLayer不在继承SpriteBatchNode,改为继承Node。并重新实现TileMap的绘制来提升性能。

    • old
    class CC_DLL TMXLayer : public SpriteBatchNode
    • new
    class CC_DLL TMXLayer : public Node

    新的TMXTiledMap接口和原有的保持一致。我们依然可以像以前那样使用TMXTiledMap创建瓦片地图。

    Fast TileMap的用法

        auto map = cocos2d::experimental::TMXTiledMap::create("tilemap.tmx");
        addChild(map, 0, kTagTileMap);

    上面代码演示了,使用Fast TileMap加载tilemap.tmx文件创建一幅地图,并加到场景中。

    更多API使用方法参考:

    性能对比

    我们分别使用以前的TileMap和Fast TileMap加载同一个tmx文件创建地图,并在同一设备上进行测试。

    测试设备:

    MacBook Pro Retina,13-inch,Late 2012 OS X 10.9.4

    • TileMap

      auto map = TMXTiledMap::create("TileMaps/iso-test-bug787.tmx");
      addChild(map, 0, kTagTileMap);
      map->setScale(0.25f);

      运行结果:

    • Fast TileMap

       auto map = cocos2d::experimental::TMXTiledMap::create("TileMaps/iso-test-bug787.tmx");
      addChild(map, 0, kTagTileMap);
      map->setScale(0.25f);

      运行结果:

      运行结果对比:

    • 两者的GL calls都相同
    • 使用Fast TileMap的GL verts更少
    • 使用Fast TileMap的帧率更高

    因为相同的GL calls(渲染次数)下,GL verts(显卡绘制的顶点数)越少,绘制效率越高。FPS(帧率)越高游戏越流畅。所以 使用Fast TileMap渲染地图的性能更优

     
  • 相关阅读:
    宿主机( win 7 系统) ping 虚拟机VMware( cent os 6.6 ) 出现“请求超时”或者“无法访问目标主机”的解决方法
    Java实现 LeetCode 23 合并K个排序链表
    Java实现 LeetCode 23 合并K个排序链表
    Java实现 LeetCode 23 合并K个排序链表
    Java实现 LeetCode 22 括号生成
    Java实现 LeetCode 22 括号生成
    Java实现 LeetCode 22 括号生成
    Java实现 LeetCode 21 合并两个有序链表
    Java实现 LeetCode 21 合并两个有序链表
    Java实现 LeetCode 21 合并两个有序链表
  • 原文地址:https://www.cnblogs.com/damowang/p/5177198.html
Copyright © 2020-2023  润新知