【问题标题】:How to remove gaps between tiled textures?如何消除平铺纹理之间的间隙?
【发布时间】:2013-04-10 08:15:50
【问题描述】:

我正在使用 LibGDX 制作平台游戏。我在平台上使用方形瓷砖,但是当它们被绘制时,其中一些在它们之间有间隙。当我放大/缩小或围绕间隙移动位置移动相机时。

更多细节:

  • 瓷砖是 32x32,我尝试过 32x32 和 64x64。
  • 图块以 32 像素间隔排列​​(例如,第一个图块将是 x=0 y=0,第二个图块是 x=32 y=0,以此类推,在 x 和 y 方向上)。
  • 我已经检查过,这些间隙不是纹理伪影。
  • 我使用带有填充的TexturePacker

我最好的猜测是,将纹理转换为屏幕坐标时会出现问题,但不知道如何解决这个问题,我找不到任何解决方案。我用瓷砖尺寸检查并仔细检查了我的精度并将它们对齐。

有没有人遇到过同样的问题或知道如何解决?

【问题讨论】:

    标签: java libgdx textures sprite tile


    【解决方案1】:

    我通过将TexturePacker.Settings 类的duplicatePadding 字段设置为true 来修复它。

    示例代码:

    import com.badlogic.gdx.tools.texturepacker.TexturePacker;
    import com.badlogic.gdx.tools.texturepacker.TexturePacker.Settings;
    
    Settings settings = new Settings();
    settings.maxWidth = 1024;
    settings.maxHeight = 1024;
    settings.duplicatePadding = true;
    
    TexturePacker.process(settings, "source", "destination", "name");
    

    【讨论】:

    • 好的,你如何实际使用它...?什么应该进入“源”“目的地”和“名称”? source = 我相信的tileset?
    • 您可以通过多种方式使用它,例如在您的 Launcher 类中,或者像我一样,创建一个新类并在 main 方法中运行此代码。 “源”是您拥有图像的位置,“目标”是您想要纹理文件的位置,“名称”是您命名纹理文件的位置。
    • 你也可以使用pack.json文件代替Settings类-LibGDX texture packer documentation
    【解决方案2】:

    好吧,我是来拯救你的!

    解决方案称为“边缘填充”。现在,如果您正在使用图块集,我可以向您保证这将起作用。

    就我个人而言,我使用 Tiled,它允许我调整我的图块集中的边距和间距。唯一的缺点是你必须使用 GIMP 和这个插件:http://registry.gimp.org/node/26044

    此插件可让您将边缘填充应用于您的图块集,瞧!不再有丑陋的文物。

    【讨论】:

      【解决方案3】:

      Bleeding

      Gaps

      简短的回答是它可能是您的过滤器,可能需要设置为 NEAREST。

      可能还想查看Libgdx. 的工作教程

      【讨论】:

        【解决方案4】:

        这被称为“纹理出血”。您需要为您的图块添加填充,以便在纹理流血时,它可以收集正确的像素数据来填补空白。

        【讨论】:

          【解决方案5】:

          我知道在这个帖子上回答有点晚了,但是当我在寻找解决方案时,我来到了这里。

          但是,对我来说,我找到了一种更简单的方法来消除瓷砖之间随机出现的闪烁或间隙。

          我只是在我为玩家位置得到的非常长的小数点上添加了一个演员:

          camera.position.set((int)robot.position.x, (int)robot.position.y, 0);
          

          这让玩家移动非常奇怪,为了让他再次平稳移动,我还在其渲染方法中添加了一个演员:

          batcher.draw(robotSprite, (int)robot.position.x, (int)robot.position.y, 16, 16);
          

          等等!非常适合我。

          【讨论】:

            【解决方案6】:

            我会在这里发布我的解决方案以及我为 Libgdx 尝试过的关于这个问题的方法。

            --

            T1. 制作从某处下载到 padding 2 的原始 spritesheet(无图集文件)。

            A1. 这对没有图集的spritesheet进行重新打包是不可能的,即使你找到了切片/分割工具,也应该是一堆需要重新打包的图片适合 TiledMap(.tmx)

            A1(已更新)。@Nine Magics 提供的脚本将是最好的方法! (我用这个作为我的最终解决方案)

            --

            T2.使用libgdx-nightygdx-toolg提供的TiledMapPacker,批处理代码应为:

            java -classpath "gdx.jar";"gdx-natives.jar";"gdx-backend-lwjgl.jar";"gdx-backend-lwjgl-natives.jar";"gdx-tiled-preprocessor.jar";"extensions/gdx-tools/gdx-tools.jar" com.badlogic.gdx.tiledmappacker.TiledMapPacker "PathToYourProject\android\assets\RawMap" "PathToYourProject\android\assets\Map" --strip-unused
            

            A2. Tiled 无法读取的输出 .tmx 如果您使用复杂的文件夹路径对您的 .png 文件进行分类。并且输出文件可能会被AtlasTmxMapLoader加载失败。

            --

            T3. 相机位置校正,使相机位置为整数。喜欢@Julian 或@strangecat 的代码来自libgdx tiledmap flicker with Nearest filtering

            A3。我使用这个解决方案没有问题,并且还发布了与他们不同的代码。

                float cameraX = (int)(mainCamera.position.x * Game.PPM_X) / Game.PPM_X;
                float cameraY = (int)(mainCamera.position.y * Game.PPM_X) / Game.PPM_X;
                float cameraZ = mainCamera.position.z;
                mainCamera.position.set(cameraX, cameraY, cameraZ);
            

            同时使用TmxMapLoader.Parameters加载它

                TmxMapLoader.Parameters params = new TmxMapLoader.Parameters();
                params.textureMinFilter = Texture.TextureFilter.Linear;
                params.textureMagFilter = Texture.TextureFilter.Nearest;
                params.generateMipMaps = true;
                assetManager.load(TILED_MAP_SETS.FIRST_MAP, TiledMap.class, params);
            

            如果您使用 PPM 并希望逐像素移动,您可以在游戏中使用此整数校正,否则您可以将位置转换为整数。

            我几乎浪费了一整天的时间来解决这个问题,希望这些调查可以帮助每个游戏开发者:)

            编辑(2018/04/21) 我发现 Unity 也有相同的 problem,但我还没有测试如果 Libgdx 默认有 2x Anti-Alias 设置。 Libgdx 可能会通过关闭 Anti-Alias 来解决 Unity 的问题。

            【讨论】: