如何用cocos2dx 地图编辑器-x来做一个基于tilemap地图块的游戏

Cocos2d-x如何实现动态加载大地图?
RPG游戏里,大地图很大,直接全部加载进去应该比较耗。据我所知好像tieldmap不支持动态加载地图,还有其他地图编辑器支持嘛?或者有没有什么方法去实现?
见过秦姬手机版的加载, 大概是把大地图切成块, 然后根据你当前位置, 预载周边格子的纹理, 要显示时, 显示就可以, 然后做好老资源释放就可以了
必须自己撸一个!不造轮子怎么体现自己的水平啊是吧大地图要切成若干小块,当然还得配合配置文件使用,这个可以写个编辑器来搞。加载的时候,只显示当前可视范围内的地图块。要是做成异步的就更好了。当年页游还得有瓦片分级,先加载一个缩略图,然后从缩略图上取小块拉伸填充到地图瓦片上,然后再异步的去加载清晰的图片。
地图图片纹理异步加载到缓存,然后创建tilemap
已有帐号?
无法登录?
社交帐号登录Pages: 1/3
主题 : cocos2d-x做地图能用tiledMap?渣渣,开什么玩笑,不服来辩!
级别: 新手上路
可可豆: 11 CB
威望: 11 点
在线时间: 1(时)
发自: Web Page
来源于&&分类
cocos2d-x做地图能用tiledMap?渣渣,开什么玩笑,不服来辩!&&&
cocos2d-x做地图能用tiledMap?渣渣,开什么玩笑,不服来辩!cocos2d-x的tiledMap有个很严重的问题,就是不能很好的处理遮挡!什么?你说TestCpp里有例子?那个叉腰眼镜女在树林之间穿梭的很欢乐?我详细的看了TestCpp里的例子,他里面处理层遮挡主要有两种方式:1.使用 iso-test-zorder.tmx 地图文件的,一共只有三排树,每排树就是一个单独的层,文件中分别是trees1,trees2,trees3。坑爹呢你这是,想累死美工啊,如果是100X100的地图,敢情是要做199个层么?   而且不在同一个层里的话,以后怎么做碰撞检测自动寻路之类的?渣渣方案,不适合真正的游戏,否掉。2.使用 iso-test-vertexz.tmx 地图文件的,这下是把树全都放在同一个层Trees里了。你以为这个就能解决实际问题?可里面穿来穿去的小美妞是用layer-&tileAt( ccp(29,29) ) 这个方式取的啊,这是拿地图文件里已经有的瓦片来移来移去啊。你自己做游戏的话,单机还好,可以把主角自己预先写到地图文件里,但网游呢?  你怎么知道会有多少个玩家在这个地图上跑?  把玩家画到.tmx文件里?想吓死爹啊。渣渣方案,不适合真正的游戏,否掉。好吧,那咱是不是该自己想办法解决这个问题呢?1.有了,针对上面的问题,既然.tmx文件里的cc_vertexz的automatic可以把瓦片自动Zorder排序好,我们可以创建额外的精灵sprite,然后用 tmxTiledMap-&addChild的方式把sprite给添加进去,然后在帧循环中对这个sprite修改Zorder不就可以嵌入小树林了吗?好聪明耶~现实总是残忍的,事实结果是,sprite被加进tmxTiledMap之后,不是与瓦片并列的,而是与层并列的…比如tmxTiledMap中有两个层,grass和trees,不管你sprite的值怎么改,要么在grass下面不可见,要么在所有的trees和grass之间,要么在所有的trees之上。也就是说被加进来的sprite的Zorder没有进入trees的Zorder体系中。失败。2.有的读者可能会说,你SB啊,你都知道sprite和trees并列了,那么直接把sprite添加到trees的那个层中不就可以了么?好吧,实践是检验真理的唯一标准。结果是,当我使用tmxLayer-&addChild方法后,会报错...跟到源代码里,发现有一句:CCAssert(0, \\\&addChild: is not supported on CCTMXLayer. Instead use setTileGID:at:/tileAt:\\\&);我勒个擦,直接告诉你不要使用这个方法。3.当你窃喜的看到他说要让你使用setTileGID方法,兴奋的以为找到了解决之道时,再去看看setTileGID方法的源码,不得不怒了,什么玩意啊!这方法连精灵或者节点的参数都没有,添加个毛啊,跟addChild完全是不用的用途,居然好意思写 Instead use xxx,我真是无语了。顺便说说度娘和谷哥,一查,哇咧,好多资源好多博客好多帖子啊,一细看,要么是对TestCpp的代码解释一番,要么是复制转载别人的解释,就连好几个错误都是相同的。国内的程序员同行们,给点力行不?好不容易国人出一个不错的游戏框架,大家不好好努力的话,看样子有被Unity3D搞死搞残的节奏啊。本人QQ
能解决此问题的欢迎沟通。
本帖最近评分记录: 共1条评分记录
干得漂亮,欢迎下次多提一些问题,骂的我面红耳赤,好久没被咬了。
级别: 新手上路
可可豆: 220 CB
威望: 220 点
在线时间: 87(时)
发自: Web Page
关注一下,目前还没做这种游戏
级别: 新手上路
UID: 273966
可可豆: 115 CB
威望: 110 点
在线时间: 41(时)
发自: Web Page
还有对象层里面的对象只能按照先前创建的顺序,不能后来随意更改,而且遍历的顺序就是按照这个来的,不清楚这个的话,在程序中遍历有的时候还会有问题,希望作者在下个版本中改善一下
级别: 新手上路
UID: 134515
可可豆: 20 CB
威望: 20 点
在线时间: 54(时)
发自: Web Page
mark,有时间再细看
级别: 新手上路
可可豆: 117 CB
威望: 117 点
在线时间: 11(时)
发自: Web Page
英文不好,不会google,不会stackoverflow去找,是硬伤。
级别: 圣骑士
可可豆: 3638 CB
威望: 3638 点
在线时间: 380(时)
发自: Web Page
楼主这是激将法么?引擎不支持就自己想想办法实现呗。开源引擎就这点好,不满意可以自己改呀
级别: 精灵王
可可豆: 4555 CB
威望: 4505 点
在线时间: 1464(时)
发自: Web Page
为什么不自己写一个地图编辑器,或者使用其他的现成的地图编辑器呢?“我觉着,这个地方可以这样修改,会更好一点”比起“这个东西是个垃圾”更容易让别人接受。即使围棋达到了9段,也可能被一个年长者批评“臭棋”。
级别: 圣骑士
可可豆: 2524 CB
威望: 2519 点
在线时间: 825(时)
发自: Web Page
lz提到的这些问题确实存在,tiledmap远谈不上好用,当初用的时候也很困惑,现在也没有找到好的解决方案……
级别: 侠客
可可豆: 296 CB
威望: 296 点
在线时间: 99(时)
发自: Web Page
楼主搞的好像做游戏只能tiledMap似的。你不喜欢解放鞋,不等于解放鞋没有存在的价值,买解放鞋的人多的去,关键还是看用来干什么?你参加婚礼会 西装 + 解放鞋么?
级别: 骑士
可可豆: 547 CB
威望: 547 点
在线时间: 338(时)
发自: Web Page
回 楼主(yy) 的帖子
我用cocos2d做的,也碰上了这个问题。我记得我是分开解决了。tiledMap只负责绘制场景,动态元素都是直接在cocos2d的Layer 中解决了。没有在tiledMap中实现。给你截个屏,tiledMap只用了5个层搞定。关于使用tiledMap的逻辑,我写在了楼下。翻页儿。[ 此帖被flashbulb在 21:04重新编辑 ]
图片:屏幕快照
下午8.24.15.png
Pages: 1/3
关注本帖(如果有新回复会站内信通知您)
8*2-5 正确答案:11
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 浏览移动版如何使用Cocos2d制作基于tilemap的游戏(一)
如何使用Cocos2d制作基于tilemap的游戏(一)
引言程序截图:本教程将会教大家如何使用Cocos2d-x来做一个基于tile地图的游戏,当然还有Tiled地图编辑器。(我们小时候玩的小霸王小学机里面的游戏,大部分都是基于tile地图的游戏,如坦克大战、冒险岛、吞食天地等)我们将会创建一个忍者在沙漠中找西瓜吃的小游戏。在第一部分教程中,我将教大家如何使用Tile来创建地图,怎样把地图加到游戏中,怎么让地图跟随玩家滚动,以及怎样使用对象层。在第二部分教程中,我将介绍如何在地图中创建可碰撞的区域,如何使用tile属性,如何制作可拾取的物体和动态修改地图,还有确保忍者不要吃撑了!如果你还没有准备好的话,你可能需要先从《》系列教程开始学起,因为我们这个教程使用了大量的基本概念,而这些概念都可以从上面的教程中获取。好了,让我们玩一玩tile地图吧!创建工程骨架让我们首先创建整个工程的骨架,这样可以确保今后我们需要的文件都包含进来了,并且能够跑起来。首先工程命名为TileGame。接下来,下载。这个资源文件包里包含了以下内容:玩家sprite。这个图片和《如何用Cocos2d-x3.0制作一款简单的游戏》差不多。我使用cxfr这个工具制作的一些音效。我使用Garage Band制作的一些背景音乐。(查看这篇博文获得更多的信息)我们将会使用的tile集合--它实际上会和tile地图编辑器一块儿使用,但是,我想把它放在这里,余下的事情会变得更容易。一些额外的“特殊”的tile,我将会在后面加以说明。一旦你获得了这些资源,解压并把它拖到你的工程的“Resources”分组下面。(编者的话:上面的音频资源都被编者转成了mp3格式)如果一切顺利,所有的文件应该都在你的工程里了。是时候制作我们的地图了!使用Tile来制作地图Cocos2d-x支持使用创建的TMX格式的地图。(建议大家在安装的时候选择英文,本教程的Tile采用英文的)下载完之后,直接双击运行。点击File\New,然后会出现以下对话框:在 orientation部分,你可以选择Orthogonal。Layer format我们也选默认的 Base64(zlib compressed)。接下来,设置地图的大小。记住,这个大小是以tile为单位的,而不是以像素为单位。我们将创建一个尽量小的地图,因此选择50*50。最后,你指定每个tile的宽度和高度。你这里选择的宽度和高度要根据你的实际的tile图片的尺寸来做。这个教程使用的样例tile的尺寸是32*32,所以在上面的选项中选择32*32.接下来,我们把制作地图所需要的tile集合导入进来。点击菜单栏上面的“map”菜单,“New Tileset...”,然后会出现下面的窗口:为了获得图片,点击“Browse...”按钮,然后定位到工程的的Resources文件夹,选择 tmw_desert_spacing.png文件(我们刚才解压进去的),然后加到工程中去。它会基于文件名自动填充名称。然后把新图快 名称命名为“tmw_desert_spacing.png”.同时,设置下面的Tile spacing和Margin都为1。你可以保留宽度和高度为32*32,因为tile的实际大小也是这么多。至于margin和spacing,我还没找到任何好的文档解释如何设置这两个值,下面是我的个人看法:Margin就是当前的tile计算自身的像素的时候,它需要减去多少个像素(宽度和高度都包含在内)。(类比word、css的margin)Spacing 就是相邻两个tile之间的间隔(同时考虑宽度和高度)(类比word、css的spacing)  如果你看看 tmw_desert_spacing.png,你将会看见每一个tile都有一个像素的空白边界围绕着,这意味着我们需要把margin和spacing设置为1。一旦你选择ok,你将会看到Tilesets窗口中显示了一些tiles。现在,你可以制作地图了!在Tilesets小窗口,选择一个tile,然后再在地图上的任意位置单击,你就会看到你选中的tile出现在点中的地方了。因此,继续制作地图吧---充分发挥你的聪明才智!确保增加至少一对建筑物在地图上,因为后面我们需要一些东西来做碰撞。记住一些方便的快捷方式:你可以在Tileset拾取器中拖出一个方框,一次选取多个tile。你可以使用工具栏上的“Bucket Fill Tools”按钮(就是一个桶那个)来基于一个基准tile绘制整个地图。你可以使用“View\Zoom In...”和“View\Zoom out...”来放大和缩小地图。一旦你完成了地图的绘制工作,在Layers选项卡的层上面双击(现在可以说是“Layer1”),然后重命名为“Background”。然后点击“File\Save”并且保存文件到你的工程的资源文件夹中,并且命名为“TileMap.tmx”。后面我们将会使用这个tmx来做一些有趣的事情,好了,让我们把地图加载到游戏中去吧!把tile地图添加到Cocos2d-x的场景中打开HelloWorldScene.h,然后添加一些成员变量:1234cppprivate:&&&&cocos2d::TMXTiledMap&*_tileM&&&&cocos2d::TMXLayer&*_然后在HelloWorldScene.cpp文件中做如下修改:123456789101112131415161718cpp//&Replace&the&init&method&with&the&followingbool&HelloWorld::init(){&&&&if&(&!Layer::init()&)&&&&{&&&&&&&&return&false;&&&&}&&&&std::string&file&=&"TileMap.tmx";&&&&auto&str&=&String::createWithContentsOfFile(FileUtils::getInstance()-&fullPathForFilename(file.c_str()).c_str());&&&&_tileMap&=&TMXTiledMap::createWithXML(str-&getCString(),"");&&&&_background&=&_tileMap-&layerNamed("Background");&&&&addChild(_tileMap,&-1);&&&&&&&&&return&true;}这里,我们调用TMXTiledMap类的一些方法,把我们刚刚创建的地图文件加载进去。一些简明的TMXTiledMap的背景知识。它是一个Node,你可以设置它的位置和比例等。这个地图的孩子是一些层,而且提供了一个帮助函数可以让你通过层的名字得到层对象--我们上面就是通过这种方面获得地图背景的。每一个层都是一个SpriteSheet的子类,这里考虑了性能的原因--但是这也意味着每一个层只能有一个tile集。因此,我们这里做的所有这些,就是指向一个tile地图,然后保存背景层的引用,并且把tile地图加到HelloWorld层中。好了,就这么多!编译并运行工程,你将会看到地图的左下角出现在窗口中。还不错!但是,这还不是一个游戏!我们还需要三个东西:a)游戏主角,b)主角初使位置和c)能够移动视图,这样就好像是第一视角了。好了,接下来让我们来解决这些问题。tiled对象层和设置tile地图位置tiled支持两类层--tile层(就是我们目前使用的层),还有对象层。对象层允许你在地图上圈出一些区域,来指定一些事件的发生。比如,你可能想制作一个区域,在那里怪物将会跳出来,或者是一个区域,只要进入就会死掉。这我们这个例子中,我们将创建一个区域来显示我们的游戏主角。因此,找到Tiled的菜单,点击” Layer\Add Object Group…”,命名为“Objects”,然后选择Ok。如下图所示,首先在图层出,把背景层前的勾选去除。在工具栏上方选择矩形,画一个小矩形,你将会注意到,它并没有绘制一个tile,而是画了一个很难看的灰色矩形,这个矩形我们之后可以扩展,使之能够包含多个tiles或者移动它。我们只想要选择一个tile来让主角显示。因此,在你的地图上选择一个tile。这个区域(下图画出的矩形)的大小实际上并没有关系,因为我们仅仅使用x、y坐标。然后,在矩形上面点右键, 取名为“SpawnPoint",然后选择确定:(下面给出一些技巧。如何把一个对象准确放置到Background的空白区域,只需要调整背景层的opacity就可以了)我们仅仅把这个类型设置为空就行了,最后Cocos2d-x会为我们创建ValueMap保存相关数据,我们可以从中获得对象的各种属性,包含x,y坐标。保存地图,然后返回VS。在HelloWorldScene.h中做如下修改:123cpp//&Inside&the&HelloWorld&class&declarationcocos2d::Sprite&*_同样,修改HelloWorldScene.cpp,代码如下:123456789101112cpp//&Inside&the&init&method,&after&setting&"_background&="&TMXObjectGroup&*objects&=&_tileMap-&getObjectGroup("Objects");CCASSERT(NULL&!=&objects,&"'Objects'&object&group&not&found");auto&spawnPoint&=&objects-&getObject("SpawnPoint");CCASSERT(!spawnPoint.empty(),&"SpawnPoint&object&not&found");int&x&=&spawnPoint["x"].asInt();int&y&=&spawnPoint["y"].asInt();_player&=&Sprite::create("Player.png");_player-&setPosition(x,&y);addChild(_player);setViewPointCenter(_player-&getPosition());好了,让我们先歇会儿,来解释一下对象层和对象组。首先,注意你通过TMXTiledMap对象的getObjectGroup方法来获得对象层(而不是getObject方法)。它返回一个特殊的TMXObjectGroup对象。我们然后调用TMXObjectGroup类的getObject方法来获得一个ValueMap,这个map包含了关于对象的大量信息,包括x和y坐标值,宽度和高度。在这个例子中,我们只关心x和y坐标,因此,我们提取出这两个信息,并且设置player的位置。最后,我想设置这个视图为玩家所在的位置。因此,添加下面一个新方法到文件中:1234567891011121314cppvoid&HelloWorld::setViewPointCenter(Point&position)&{&&&&auto&winSize&=&Director::getInstance()-&getWinSize();&&&&int&x&=&MAX(position.x,&winSize.width&/&2);&&&&int&y&=&MAX(position.y,&winSize.height&/&2);&&&&x&=&MIN(x,&(_tileMap-&getMapSize().width&*&this-&_tileMap-&getTileSize().width)&-&winSize.width&/&2);&&&&y&=&MIN(y,&(_tileMap-&getMapSize().height&*&_tileMap-&getTileSize().height)&-&winSize.height&/&2);&&&&auto&actualPosition&=&Point(x,&y);&&&&auto&centerOfView&=&Point(winSize.width&/&2,&winSize.height&/&2);&&&&auto&viewPoint&=&centerOfView&-&actualP&&&&this-&setPosition(viewPoint);}好了,让我解释一下。假设这个函数是设置camera的中心。我们允许用户传入地图上任何x、y坐标值--但是如果你仔细想一下,有些东西我们并不想让它显示出来--比如,我们不想让屏幕超过地图的边界(那些区域仅仅是一个空白区域!)比如,看看下面这幅图:看一下,什么时候camera的中心会小于winSize.width/2或者winSize.height/2,部分视图将会在屏幕之外?类似的,我们需要检查上面的界限区间,也和我们这里的情形一样。因此,我们把这个函数看作是设置camera的视角中心点。然而。。。那不完全是我们想要的。在Cocos2d-x里面有一种方式可以直接操作一个Node的camera,但是那会使事情变得更复杂。我们需要另一种替代方法,那就是移动整个层。看看下面的图:想像一个大的地图,我们查看从0到winSize.height/width的坐标。我们的视图的中心点是centerOfView,而且我们知道我们要把这个中心设置到哪里(actualPositon)。因此,为了使实际的位置和视图中心相吻合,我们只需要把地图往左下角移动即可!这个可以通过使实际的位置减去视图的中心位置来实现,然后设置HelloWorld层到那个点。唉!太多理论了--让我们看点实际的吧!编译并运行项目,如果一切顺利,你将会看到忍者在场景当中,然而视角也移过来了。使忍者移动我们已经有一个好的开端了,但是我们的忍者只是站在那儿不动!这可不像真正的忍者!让我们使忍者动起来吧,只需要让忍者移动到用户点击的地方就行了。在HelloWorldScene.cpp中增加以下代码:123456789101112131415161718192021222324252627282930313233343536373839404142434445464748cpp//&Inside&init&methodauto&listener&=&EventListenerTouchOneByOne::create();//lambda&expression:&advanced&feature&in&C++&11listener-&onTouchBegan&=&[&](Touch&*touch,&Event&*unused_event)-&bool&{&return&true;&};listener-&onTouchEnded&=&CC_CALLBACK_2(HelloWorld::onTouchEnded,&this);this-&_eventDispatcher-&addEventListenerWithSceneGraphPriority(listener,&this);//add&following&methodvoid&HelloWorld::setPlayerPosition(Point&position){&&&&_player-&setPosition(position);}void&HelloWorld::onTouchEnded(Touch&*touch,&Event&*unused_event){&&&&auto&touchLocation&=&touch-&getLocation();&&&&touchLocation&=&this-&convertToNodeSpace(touchLocation);&&&&auto&playerPos&=&_player-&getPosition();&&&&auto&diff&=&touchLocation&-&playerP&&&&if&(abs(diff.x)&&&abs(diff.y))&{&&&&&&&&if&(diff.x&&&0)&{&&&&&&&&&&&&playerPos.x&+=&_tileMap-&getTileSize().&&&&&&&&}&&&&&&&&else&{&&&&&&&&&&&&playerPos.x&-=&_tileMap-&getTileSize().&&&&&&&&}&&&&}&&&&else&{&&&&&&&&if&(diff.y&&&0)&{&&&&&&&&&&&&playerPos.y&+=&_tileMap-&getTileSize().&&&&&&&&}&&&&&&&&else&{&&&&&&&&&&&&playerPos.y&-=&_tileMap-&getTileSize().&&&&&&&&}&&&&}&&&&if&(playerPos.x&getMapSize().width&*&_tileMap-&getMapSize().width)&&&&&&&&&&&playerPos.y&getMapSize().height&*&_tileMap-&getMapSize().height)&&&&&&&&&&&playerPos.y&&=&0&&&&&&&&&&&playerPos.x&&=&0)&&&&{&&&&&&&&this-&setPlayerPosition(playerPos);&&&&}&&&&this-&setViewPointCenter(_player-&getPosition());}首先,在init方法中设置事件监听器,让监听器的onTouchesBegan和onTouchEnded绑定不同的方法。因为要想onTouchEnded能用,onTouchesBegan必须返回true。我们这里只需onTouchesBegan发挥返回true的作用,所以就直接写c++11的新特征支持的也是Cocos2d-x3.0 支持的lambda表达式,不是太懂的话搜索一下。这样发生触摸事件,监听器就会调用onTouchBegan匿名方法和onTouchEnded方法(注意是单数形式,而不是复数形式的onTouchesBegan和onTouchesEnded方法)你可能会问,为什么我要讲这个,因为我们在 《》里面使用的是onTouchesBegan和onTouchesEnded方法。那两个方法可以,在这个教程里用两种方法都可以。但是,我想向大家介绍一个新方法,因为它有两个优点:“你不需要处理std::vector&,划分Touch并调度的工作全部由Cocos2d-x框架来完成。每一次方法调用,你只获得了一个Touch。““你可以在onTouchBegan中返回true,这样当前的层就可以接收touch事件回调。而且,只有当你返回true的时候,才会响应move/ended/cancelled回调. 这个就使你从一些复杂的多触摸判断中解放出来了。不管怎么说,在我们的onTouchEnded里面,我们转换屏幕touch坐标为本地坐标。这是因为,touch位置只是告诉我们屏幕视口的坐标(比如100,100)。但是,我们我们滚动了地图,这个位置实际可能对应地图的(800,800)。因此,调用这个方法基于我们当前层的位置来决定touch的偏移。接下来,计算出touch点和player的位置之差。我们必须基于touch位置选择一个方向,因此,首先,我们需要计算出是上下移动还是左右移动。然后,我们比较正负值,决定具体的方向。相应的,我们再调整player的位置,并且设置player的位置为视口的中心位置,这个在上一节中已经用到了。更新:注意,我们不得不添加一个安全检查,来确保我们的player不会移到地图之外!这一点,是Geek&Dad指出来的,谢谢你!编译并运行!你现在可以点击鼠标,想让尽者移到哪,它就移到哪儿!何去何从?这只是这个教程的一部分。此时,你应该了解一些创建tile地图的基础了,而且知道如何把它导入到游戏当中。这里有我们目前为止用的完整源代码:接下,期待吧!在那里,我将教大家如何在地图中添加碰撞检测,如果使我们的忍者沿着墙壁快乐的奔跑!
发表评论:
TA的最新馆藏[转]&Tile map is built to be easy to use, yet flexible enough to work with Cocos2D-x, whether your game is an RPG, platformer or Breakout clone. Cocos2D-x supports maps created with the open source
and saved in TMX format.
Cocos2d supports the following TMX maps:
Orientation:
Orthogonal maps
Isometric maps
Hexagonal maps (edges on left-right. edges at top-bottom are not supported… it seems that Tiled doesn’t support them either)
Embedded tiles are NOT supported (i.e., tilesets with embedded images).
Only embedded tilesets are supported (i.e., the tileset is embedded, but not its images).
supports at most 1 tileset per layer.
You can have as many layers are you want
Each layer will be represented internally by a CCTMXLayer (which is a subclass of CCSpriteSheet)
Each tile will be represented by an CCSprite (its parent will be the CCTMXLayer)
Object Groups:
Tiled objectGroups are supported as well
Coordinates and GIDS
Coordinates
The coordinate system used in Tiled in a 64×32 map is:
(0,0): top-left corner
(63,31): bottom-right corner
tile’s GID is the tile’s Global IDentifier. It is an unsigned int that goes from 1 until the quantity of tiles.
If you have 5 different tiles then:
Tile 0 will have GID 1
Tile 1 will have GID 2
Tile 2 will have GID 3
and so on.
The GID 0 is used to represent to empty tile.
How to create a TMX node
auto map = TMXTiledMap::create(&TileMaps/iso-test-vertexz.tmx&);
addChild(map, 0, kTagTileMap);
for (const auto& child : map-&getChildren())
static_cast&SpriteBatchNode*&(child)-&getTexture()-&setAntiAliasTexParameters();
// create a TMX map
map = cc.TMXTiledMap:create(&TileMaps/iso-test-vertexz.tmx&)
layer:addChild(map, 0, kTagTileMap)
// all tiles are aliased by default, let's set them anti-aliased\n
local children = map:getChildren()
for k, child in ipairs(children) do
child:getTexture():setAntiAliasTexParameters()
How to get/add/delete/modify a tile
To obtain a tile (Sprite) at a certain coordinate
auto layer = map-&layerNamed(&Layer 0&);
auto tile = layer-&tileAt(Vec2(1, 63));
local layer = map:layerName(&Layer 0&);
local tile = layer:tileAt(cc.p(1, 63))
To obtain a tile’s GID at a certain coordinate
unsigned int gid = layer-&tileGIDAt(Vec2(0, 63));
local git = layer:tileGIDAt(cc.p(0, 63))
To set a new tile’s GID’s at a certain coordinate
layer-&setTileGID(gid, Vec2(3.0f, (float)3));
layer-&removeTileAt(Vec2(5.0f, 5.0f));
layer:setTileGID(gid, cc.p(3, 3))
layer:removeTileAt(cc.p(5, 5))
To iterate a Layer
Size s = layer-&getLayerSize();
for (int x = 0; x & s. ++x)
for (int y = 0; y & s. ++y)
layer-&setTileGID(newGid, Vec2(x, y));
local s = layer:getLayerSize()
for x = 0, s.width - 1, 1 do
for y = 0, s.height - 1, 1 do
layer:setTileGID(newGid, cc.p(x, y))
z order and depth buffer
Information valid both for Isometric and Orthogonal maps. NOT valid for Hexagonal maps
If your game needs to place the sprites behind/in front of certain tiles according to the sprites’ Y position (a common scenario in isometric maps, and in some orthogonal maps too), then you have 2 options:
Use OpenGL ES depth buffer
Use multiple TMX Layers and z-order
Using Depth Buffer
It is very important to create a map with 2 TMX Layers
A background layer. eg: grass
A foreground layer. eg: trees
The grass layer will be behind the sprites, so its vertexZ value should be the lowest possible value. eg:-1000. The trees layer should have different vertexZ values for the tiles. Tiles that are at the bottom should have higher vertexZ than the tiles that are at the top.
So, in order to achieve this, you should only do:
Open Tiled
Select the background Layer
Tiled → Layer → Layer Properties
Add: cc_vertexz =-1000
Select the foreground Layer (eg: trees)
Tiled → Layer → Layer Properties
Add: cc_vertexz = automatic
Isometric vertex Z example. It has 2 layers: “trees” and “grass”. Uses cc_vertex=automatic for the “trees” layer. And cc_vertexz=–1000 for the “grass” layer.
Orthogonal vertex example. It has 2 layers: “trees” and “grass”. It uses cc_vertexz=automatic and cc_alpha_func=0.5 for the “trees” layer. and cc_vertexz=–1000 for the “grass” layer.
Using multiple TMX Layers and z-order
Each layer in the map is automatically assigned it’s own zOrder value, so there is no need to add any layer attributes in your TMX editor. Adding your sprite as a child of the TMXMap allows you to dynamically place it within the layers of the map object.
auto tamara = Sprite::create(&tamara.png&);
auto p = tamara-&getPosition();
p = CC_POINT_POINTS_TO_PIXELS(p);
float newZ = -(p.y + 32) / 16;
tamara-&setVertexZ(newZ);
local tamara = cc.Sprite:create(&tamara.png&)
local p = tamara:getPosition()
p = CC_POINT_POINTS_TO_PIXELS(p)
local newZ = -(p.y + 32) / 16
tamara:setVertexZ(newZ)
Screenshots
Orthogonal map, with 3D projection and anti-aliased tiles. The tiles were “fixed” using the spritesheet-fixer tool. No artifacts appears even with a 3D projection and anti-aliased tiles
Orthogonal map. map’s tile size is smaller than the tiles
Isometric map, with 2D projection and aliased tiles
Hexagonal map, with 2D projection and aliased tiles. Edges are at the left-right. Bottom-top edges are not supported (yet)
References
(104.6 kB)
(163.2 kB)
Sign up for our newsletter to keep up with the latest developments, releases and updates for Cocos2d-x.

我要回帖

更多关于 cocos地图编辑器 的文章

 

随机推荐