3

I have a problem with rendering tiled map in LibGDX. When I move the camera appear artifacts.

This is my tileset with margin and spacing (fragment): tileset

When I move the camera appear artifacts: artifacts

And here is my rendering world class.

private GameApp game;

private OrthographicCamera gameCamera;
private Viewport viewport;

private TiledMap map;
private TmxMapLoader mapLoader;
private OrthogonalTiledMapRenderer mapRenderer;

private MainCharacter character;

private World world;
private Box2DDebugRenderer worldRenderer;

public GameplayScreen(GameApp game) {
    this.game = game;

    gameCamera = new OrthographicCamera();

    viewport = new FitViewport(
            game.getDisplayWidth() / GameApp.PPM,
            game.getDisplayHeight() / GameApp.PPM,
            gameCamera
        );

    mapLoader = new TmxMapLoader();
    map = mapLoader.load("testmap1.tmx");
    mapRenderer = new OrthogonalTiledMapRenderer(map, 1 / GameApp.PPM);

    gameCamera.position.set(new Vector2(600 / GameApp.PPM, 200 / GameApp.PPM), 0);
    gameCamera.zoom -= 0.5;

    world = new World(new Vector2(0, -10), true);
    worldRenderer = new Box2DDebugRenderer();

    BodyDef bDef = new BodyDef();
    PolygonShape shape = new PolygonShape();
    FixtureDef fDef = new FixtureDef();
    Body body;

    for (MapObject mapObject : map.getLayers().get("obstacles").getObjects().getByType(RectangleMapObject.class)) {
        Rectangle rectangle = ((RectangleMapObject) mapObject).getRectangle();

        bDef.type = BodyDef.BodyType.StaticBody;
        bDef.position.set(
                (rectangle.getX() + rectangle.getWidth() / 2) / GameApp.PPM, 
                (rectangle.getY() + rectangle.getHeight() / 2) / GameApp.PPM
        );

        body = world.createBody(bDef);

        shape.setAsBox(rectangle.getWidth() / 2 / GameApp.PPM, rectangle.getHeight() / 2 / GameApp.PPM);
        fDef.shape = shape;

        body.createFixture(fDef);
    }

    character = new MainCharacter(world);
}

@Override
public void show() {

}

public void handleInput(float delta) {
    if (Gdx.input.isKeyJustPressed(Input.Keys.UP)) {
        character.getBody().applyLinearImpulse(new Vector2(0, 3.8f), character.getBody().getWorldCenter(), true);
    }

    if (Gdx.input.isKeyPressed(Input.Keys.RIGHT) && character.getBody().getLinearVelocity().x <= 1) {
        character.getBody().applyLinearImpulse(new Vector2(0.05f, 0), character.getBody().getWorldCenter(), true);
    }

    if (Gdx.input.isKeyPressed(Input.Keys.LEFT) && character.getBody().getLinearVelocity().x >= -1) {
        character.getBody().applyLinearImpulse(new Vector2(-0.05f, 0), character.getBody().getWorldCenter(), true);
    }
}

public void update(float delta) {
    handleInput(delta);

    world.step(1/60f, 6, 2);

    gameCamera.position.x = character.getBody().getPosition().x;
    gameCamera.position.y = character.getBody().getPosition().y;

    gameCamera.update();
    mapRenderer.setView(gameCamera);
}

@Override
public void render(float delta) {
    update(delta);

    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    mapRenderer.render();
    worldRenderer.render(world, gameCamera.combined);
}

@Override
public void resize(int width, int height) {
    viewport.update(width, height);
}

...

I read that the spacing in the tileset help. But it still does not work properly.


EDIT:

TmxMapLoader.Parameters par = new TmxMapLoader.Parameters();
  par.textureMinFilter = TextureFilter.Nearest;
  par.textureMagFilter = TextureFilter.Nearest;

map = mapLoader.load("testmap1.tmx", par);

I edit my code, but still not work. Seeking solutions for a few days.


EDIT2

I try again. Code:

atlasMapLoader = new AtlasTmxMapLoader();
testMap = atlasMapLoader.load("testmap1.tmx");

This load my map. I have ".txt" file:

enter image description here

In Tiled Editor I add property to a map called "atlas" value "TilesetBig.txt".

Now, the map does not display tiles. Obstacles with box2d are still visible. What can I do wrong?


Finally i used OrthoCachedTiledMapRendered.

Forest
  • 33
  • 5

1 Answers1

2

You should pack your tileset with Nearest texture filter being set.

If you are using Linear one the GL is averaging border pixels using surrounding one what causes glitches like this.

Read this article to get more information about texture filters in LibGDX.

m.antkowicz
  • 13,268
  • 18
  • 37
  • Thank you. I edit my question. I try to use Nearest filter, but it still does not work. – Forest Mar 22 '16 at 10:31
  • Have you used "reduce border artifact" in Texture Packer also? – m.antkowicz Mar 22 '16 at 10:42
  • I do not use texture packer. I have prepared a graphic with spaces between tiles in Gimp. I understand that I have to use it? – Forest Mar 22 '16 at 10:55
  • 1
    Yup you should definitely use TexturePacker - it is far more convenient than making it manually :) Free version should be enough for your purposes. I suppose that in your prepared graphic there are some almost-transparent artifacts on borders and they cause issues – m.antkowicz Mar 22 '16 at 10:57
  • Its easy, Gimp have a plugin for that :). Ok, I try this solutions. But I have a big picture of the tiles, so I put it to the texture packer and he will create for me a ready graphics (with spaces) and a data file? – Forest Mar 22 '16 at 11:02
  • you need only graphic file that you will load into TIled - in TP set option not to trim graphics – m.antkowicz Mar 22 '16 at 11:12
  • I can not find any example of using class of AtlasTmxMapLoader. I have files "testuretest.pack" and "texuretest.png" and a map file. Do you know any article on this subject? – Forest Mar 22 '16 at 16:32