I was strugeling this for days how to implement tilemap into libgdx and box2d with infinite/endless scheme. I can load a single map and display everything on screen. But placing 2 or more tilemap side by side got me headache. I know currently not possible to offset/add x value position of tilemap. What I do right now is use setview for camera of it's render method. This is my map helper and currently I works with 3 renderer for 3 tilemap as a test...
public class MapHelper {
private Array<OrthogonalTiledMapRenderer> renderer = new Array<OrthogonalTiledMapRenderer>();
private int number;
private float oldDistance, currentDistance;
private String layer = "world";
public MapHelper(Callback callback) {
this.callback = callback;
number = 0;
item = new ItemMap[3];
}
public void render(CamHandler cam) {
for(int r = 0; r < renderer.size; r++) {
if(item[r] != null) {
renderer.get(r).setView(cam.getCam().combined, item[r].distance, 0, item[r].getWidth(), item[r].getHeight());
renderer.get(r).render();
}
}
}
public void updateMap(CamHandler cam) {
if(mapOut(cam)) {
number++;
if(number > 2)
number = 0;
loadMap(number);
}
}
/**
* Check if camera reach the current distance, then build new map
* @param cam
* @return
*/
private boolean mapOut(CamHandler cam) {
float x = cam.getCam().position.x + cam.getCam().viewportWidth / 2;
Utils.log("pos cam x "+x+" current distance "+currentDistance);
return x >= currentDistance;
}
private void loadMap(int map) {
AssetsManager.loadMap(map);
if(item[map] != null) {
renderer.set(map, new OrthogonalTiledMapRenderer(AssetsManager.map));
item[map].set(TileHelper.getMapWidth(AssetsManager.map, layer), TileHelper.getMapHeight(AssetsManager.map, layer), currentDistance);
} else {
renderer.add(new OrthogonalTiledMapRenderer(AssetsManager.map));
item[map] = new ItemMap(TileHelper.getMapWidth(AssetsManager.map, layer), TileHelper.getMapHeight(AssetsManager.map, layer), currentDistance);
}
oldDistance = currentDistance;
currentDistance += TileHelper.getMapWidth(AssetsManager.map, layer);
callback.onLoad();
Utils.log("load new map "+map+" distance "+currentDistance);
}
public Array<OrthogonalTiledMapRenderer> getRenderer() {
return renderer;
}
public Array<Body> getBodies(World world) {
return new MapBodyBuilder().buildShapes(AssetsManager.map, world, oldDistance);
}
private ItemMap[] item;
private class ItemMap {
private float distance, mapWidth, mapHeight;
ItemMap(float w, float h, float distance) {
mapWidth = w;
mapHeight = h;
this.distance = distance;
}
private void set(float mapWidth, float mapHeight, float distance) {
this.mapWidth = mapWidth;
this.mapHeight = mapHeight;
this.distance = distance;
}
private float getWidth() {
return mapWidth * Constants.WORLD_TO_SCREEN;
}
private float getHeight() {
return mapHeight * Constants.WORLD_TO_SCREEN;
}
}
private Callback callback;
public interface Callback {
void onLoad();
}
public void startOver() {
clear();
currentDistance = number = 0;
loadMap(number);
}
private void clear() {
for (OrthogonalTiledMapRenderer render : renderer) {
render.dispose();
}
}
}
With above class, I can display and load new map on screen when camera reaching the map end. But the tile layer texture keeps wrong position. Please give me an advice.