【libgdx】2D地图块(tileset)地图出现缝隙(gap / bleeding)的问题

原创 2016年03月07日 23:06:55

最近按官方wiki写地图块代码时遇到此问题:在Tiled里画好地图,一切都按wiki步骤来,当把地图显示出来,相机在地图上移动时,会发现地图块之间偶尔会出现缝隙(或者是黑线、白线,根据clear用的填充色不同而不同),用英文来描述,就是tiles之间有gap或white/black line,更专业一点的叫法就是tile bleeding。
借用一下别人的图
这里写图片描述
于是google了一顿,终于找到算是OK的解决办法了。
据说此问题是libgdx论坛的日经问题,每隔几天就会有人问,因为一直也没有十分优雅的解决方案,目前唯一据说比较实用的解决办法其原理也是囧得不行,听起来就让人脱力,而给出解答的人往往也都是三言两语,说的都是那种“说起来容易做起来巨麻烦”的话,让人摸不到头脑。于是仍然一直有人在问,恶性循环。。。
然后我终于看到了一篇博客,给出了简单详细的解决办法:http://thekemiren.blogspot.jp/2014/07/tile-bleeding-in-libgdx-using-tiled.html
(注意得翻墙)

我把自己搜到的相关知识总结一下:
首先这个问题让人想到的就是filter方案的问题,是不是误用了linear,而其实应该换成nearest。用过unity3D或者熟习openGL的人估计首先都会想到这个。但是可惜不是,据说libgdx里的OrthogonalTiledMapRenderer渲染器默认用的就是nearest,还有一说这个也不是特别好改(或是改了之后效果不好?感觉论坛上的人都各执一词),总之此路不通。
解决方案二,考虑到之所以出现这种问题,是因为相机(camera)在移动的时候,移动值的类型是float,精度十分高,所以当恰好移动到某一小精度时,可能会导致某两个相邻图块的渲染出现了1象素的位置偏差(比如左边的图块x坐标舍了点,右边的图块x坐标入了点,于是他俩之间出现了一个1象素的纵向的缝)。综上所述,想到的解决办法就是,不让相机的移动有如此高的精度,比如可以让移动的最小单位是0.2,不足0.2的可以补上或者舍掉,这样移动的时候就不会产生缝隙了。更极端的做法是干脆让相机按int精度移动。
这种解决方案在修改相册移动的同时必须也修改画面上物体的移动,不然会觉得物体在画面上各种抖动。而且更糟糕的是,它或许不能完全解决问题。比如我上面说的0.2精度,在原大画面时看起来很完美,但是如果画面被放大或缩小,那么这问题可能会再次出现,只能再不断降低精度。降成int就能百分百解决问题了么?似乎并没有人能给出这样的保证。而且把物体的移动精度降成int的同时也削弱了我们游戏的灵敏平滑程度,这也并不是我们所期望的。
第三种解决方案,也就是最终解决方案了,同时也是最麻烦最让人无语但是却又不得不承认是最有效的一个。做法就是:给一大张tileset里的每一个小图块(tile),都加上1个象素的勾边(gutter)。这里特别强调这个gutter,用的不是常见的padding也不是spacing也更不是margin什么的(妈个币的这几个破词我特么纠结好久,论坛上的老外们也是经常分不清楚地瞎叫),虽然挺多人声称那个勾边叫padding,但是这叫法很误导人,我觉得最准确还是应该叫gutter。至于区别,gutter跟padding/spacing最大的区别是,它增加的这一个象素的勾边,不是透明的,也不是填充某种单色(比如黑色、白色),而是根据图块而产生的一个色的延伸。比如某图块的左边缘一纵列象素都是深绿色,那么相应在左边产生的勾边也是深绿色,如果要是一纵列从红到蓝的渐变色,那么产生的勾边也应该是一个象素列从上到下的渐变色。如下图:
原图:尺寸32x32
这里写图片描述

1象素的透明边(padding/spacing)尺寸34x34
这里写图片描述

1象素的色边(gutter)尺寸34x34
这里写图片描述

到这里,大家应该明白这种解法的原理了。假如我用的是32x32的地图块,加了gutter之后就相当于用的是带1象素边缘的34x34图块,但是那多出的一个象素是彼此重叠放置的(在Tiled地图编辑器里可以这样设置),所以看起来仍然是32x32的图块。那么当再因为相机移动而产生1个象素的缝隙时,原本相互重叠的那一个象素就会露出来,但是因为已经勾上边了,所以就算露出来也很难用肉眼看出来这一破绽…………
听起来真是超级囧,非常有悖于大部分程序员一直追求的“优雅”。而且这种解法还导致了一个效能的问题……你的素材可能因此而尺寸不再是2的幂数值了。比如我的256x1024的tileset图片勾了边之后就变成272x1088……虽然libgdx也能hold得住这种尺寸的图片,但是这完全跟官方wiki中口口声声说的“尽量使用2的幂作为图片的尺寸”这一good practice法则相矛盾,但是很遗憾,这确实是官方论坛上目前给出的最有效解决方案,所以也难怪此问题会成为官方论坛上的日经问题了。
而且说到给图片加gutter这件事,如果不是拼好的素材,而是自己用texturepacker现从一个文件夹打包成atlas的素材那还好,直接改改配置再重新打包就好了。但是如果你只有一张完整的tilset素材,由许多张tile图片拼成(比如直接从RPG Maker的RTP素材里copy过来的那种)。这尼玛一个个加起来岂不是要了人命?打开PS,把图片拆成一块一块,然后再扩大画布,给每一块图片一象素一象素地勾上一个边,卧槽,光听就想死了。程序员们肯定想马上写个程序来帮忙做此事了。事实上貌似确实已经有些这样的现成程序了,我在google code上看到一个,但是不知道怎么搞,所以没试。我试了另一种,使用一款名叫GIMP的免费图片编辑软件,它有一个小插件可以帮忙完成此事。http://registry.gimp.org/node/26044
使用时需要这样配置参数:(我懒得自己截图了,用的上面我给的那个博客里的图)
这里写图片描述
就可以完成勾边。而在Tiled里,也一定要设置好margin和spacing(按上面截图勾出来的tileset的话,应该margin是1,spacing是2),才能正常地画地图。
然后直接用到程序里,不用特地为它们写什么,最终效果就非常OK了。不使劲看根本看不出来(对不明真相的玩家来说,使劲看都看不出来)

cocos2dx TiledMap图块之间有缝隙

调成如下就好了

libgdx之瓦片地图(TiledMap)

把草稿删了,没想到也把发表的文章给删了,只好重新写了。不得不吐槽一下CSDN的博客系统。 简介在我们开发游戏过程中,我们需要设置不同的关卡,如果我们直接使用使用图片来加载游戏,这将会使我们的游戏安装...

用cocos2dx开发斜45度社交游戏(一)地图的设计

 无论什么项目的开发都要有一定的技术积累和实施步骤,就像楼房的建设也是从最基本的地基开始的,地基打不好,大楼盖装饰的再漂亮也只是一个失败的作品。好吧,闲话还是少说,来点实际的,先来介绍一下此系列...

Libgdx专题系列:地图篇 地图移动

地图的移动,其实实质是镜头的移动, 地图还是原地不动的, 只要镜头跟随角色移动,就可以达到地图移动的效果。 这里为了有好的模拟效果, 我添加了两个自定义的Button按钮,代表让主角左右移动,然后镜...

Libgdx专题系列:地图篇 斜45°地图

前面我们使用的都是矩形的图块, 然而在实际的使用中,经常会用到菱形的图块来进行地图绘制。   这里Libgdx也给我们提供了斜视角的地图绘制 IsometricTiledMapRenderer 用法...

介绍一本搜索引擎爬虫方面的好书

这学期去图书馆借书,无意间看带一本书《网络机器人Java编程指南》。看了下感觉如获至宝。市面上将爬虫的书可以说是没有,基本上只有在搜索引擎类的书里有提到,而且只是讲个思想,没有可以用的代码。而《网络机...

java使用freemarker模版导出分页word

1.模版的制作 (1).先用word制作好模版的样式,我的模版样式如下图 (2).将制作好的word模版另存为word 2003 XML文件,具体内容如下 Adminis...

【iOS-Cocos2d游戏开发之十八】解决滚屏背景/拼接地图有黑边(缝隙)/动画播放出现毛边以及禁止游戏中自动锁屏问题!

转载自【黑米GameDev街区】 原文链接: http://www.himigame.com/iphone-cocos2d/507.html      本章节主要为大家介绍在游戏开发过程中经常...

【iOS-Cocos2d游戏开发之十八】解决滚屏背景/拼接地图有黑边(缝隙)/动画播放出现毛边以及禁止游戏中自动锁屏问题!【2011年12月18日补充】

李华明Himi 原创,转载务必在明显处注明: 转载自【黑米GameDev街区】 原文链接: http://www.himigame.com/iphone-cocos2d/507.html ...
  • a287971
  • a287971
  • 2012年04月11日 05:10
  • 577

【iOS-Cocos2d游戏开发之十八】解决滚屏背景/拼接地图有黑边(缝隙)/动画播放出现毛边以及禁止游戏中自动锁屏问题!【2011年12月18日补充】

李华明Himi 原创,转载务必在明显处注明:转载自【黑米GameDev街区】 原文链接: http://www.himigame.com/iphone-cocos2d/507.html     本章节...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【libgdx】2D地图块(tileset)地图出现缝隙(gap / bleeding)的问题
举报原因:
原因补充:

(最多只允许输入30个字)