参考了以下文章:
http://blog.sina.com.cn/s/blog_4508e4860101dzkj.html
转载请注明出处
如果cocos2d中的tilemap在移动时会出现黑线的情况的话,网上有很多的解决方案都是将libcocos2d库的ccConfig.h头文件中的宏CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL从0改为1,
这样的确可以解决黑线的问题,但是同时也存在这以下两个问题:
1、这个解决方案直接将所有Sprite的边都裁掉了一点,源码如下:
#if CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
left = (2*rectInPixels.origin.x+1)/(2*atlasWidth);
right = left+(rectInPixels.size.height*2-2)/(2*atlasWidth);
top = (2*rectInPixels.origin.y+1)/(2*atlasHeight);
bottom = top+(rectInPixels.size.width*2-2)/(2*atlasHeight);
#else
left = rectInPixels.origin.x/atlasWidth;
right = (rectInPixels.origin.x+rectInPixels.size.height) / atlasWidth;
top = rectInPixels.origin.y/atlasHeight;
bottom = (rectInPixels.origin.y+rectInPixels.size.width) / atlasHeight;
#endif
2、cocos2d后来更新的版本支持Fast TileMap的使用,我试了一下,的确好用,对于超出屏幕太多的tilemap是一个有效的减少绘制顶点数的方案,
但是像上面那样只时修改宏定义的话,Fast TileMap中的黑线还是存在的。
参考了开头提到的文章,去找了下CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL这个宏定义用到的地方,只有以下四个文件:
其中除了宏定义本身使用的文件(ccConfig.h),只有CCSprite.cpp和tilemap的绘制有关系。这样就简单了,进到CCSprite.cpp文件中,发现也只有一个成员函数中
使用了这个宏,如下图:
再到头文件里看一下,很好,这个setTextureCoords是个virtual函数,这样我们就可以继承一下Sprite类override这个方法了。
自己创建一个类,就叫MySpriteTileMap吧,这里注意一下,最好放在库的cocos/2d目录下,这样和下面要用到的CCTMXTileMap等文件同一目录。
如果放在项目的class目录下的话,由于在编译的时候,先编译库文件,调用MySpriteTileMap中的方法会报错的,因为这个时候MySpriteTileMap文件还没有
编译,自然无法使用了。
继承了这个类后,只需要重写上面提到的那个方法就行了。直接如下图:
#if 1/*CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL*/
left = (2*rectInPixels.origin.x+1)/(2*atlasWidth);
right = left+(rectInPixels.size.height*2-2)/(2*atlasWidth);
top = (2*rectInPixels.origin.y+1)/(2*atlasHeight);
bottom = top+(rectInPixels.size.width*2-2)/(2*atlasHeight);
#else
left = rectInPixels.origin.x/atlasWidth;
right = (rectInPixels.origin.x+rectInPixels.size.height) / atlasWidth;
top = rectInPixels.origin.y/atlasHeight;
bottom = (rectInPixels.origin.y+rectInPixels.size.width) / atlasHeight;
#endif
下面还有一处也这样改
重写的方法只需要修改#if的判断条件就行了,其余的直接复制。这里提一下,因为下面我在修改CCTMXTileMap等文件的时候,为了方便,又写了另外的一个方法,
这个createWithTextureTileMap函数主要是为了替代Sprite类中的createWithTexture函数使用的。由于是static类型的,所以无法重写,只好写一个新的函数。
之后将CCTileMapAtlas.cpp文件中的updateAtlasValueAt函数中的宏像上面那样注释掉,直接运行if后面的语句。
再然后就是将CCTMXLayer.cpp和CCFastTMXLayer.cpp文件中的有关的Sprite修改成MySpriteTileMap就可以了。这里是最麻烦的地方,我就是用createWithTextureTileMap
替代了Sprite的createWithTexture方法。相信有c++基础的仔细看看这两个文件(很多地方相似),理清他们的逻辑,就知道需不需要将对应的Sprite改成MySpriteTileMap了。
这里比较麻烦,我就不截图了,需要的可以联系我要代码。
之后在使用TileMap和Fast TileMap时,就不会出现黑线了,也不会影响其他的Sprite的使用。