I have a 15x15 Isometric Tilemap consisting of 128 x 64 pixel tiles. Using an ExtendViewport and OrthogonalCamera I am able to render the map. However, it does not scale properly when resizing the window as the aspect ratio of the tiles becomes distorted and occasionally the map will move over to the right side of the window. The map does look fine if I force fullscreen resolution, but not if it's manually scaled or in windowed mode. When I say that the aspect ratio becomes distorted I mean that the tiles will appear stretched or jagged resulting in poor aesthetics.
Is there a simple way to render a perfectly squared (e.g. 10x10, 15x15) sized Isometric Tilemap, display it in the centre of the screen and have it scale properly without distorting the aspect-ratio as the screen size increases?
Then there is the issue of conversion between cartesian and isometric coordinates.
http://clintbellanger.net/articles/isometric_math/ The following post explains how to convert between cartesian and isometric coordinates, but I am not able to make it work. The code below is the closest thing I've come to a working solution so far, but it becomes increasingly more off as you move towards the right of the screen, not by terribly much, but it's definitely noticeable.
public static Vector2 cartesianToIsometric(Camera camera, GameMap map, Vector3 point) {
camera.unproject(point);
float tileWidth = (float)map.getMapWidth() * unitScale(map);
float tileHeight = (float)map.getMapHeight() * unitScale(map);
point.x /= tileWidth;
point.y = (point.y - tileHeight / 2) / tileHeight + point.x;
point.x -= point.y - point.x;
return new Vector2((int)point.x, (int)point.y);
}
Here is a snippet of the relevant code from my GameRenderer Class.
public GameRenderer(GameState world) {
this.map = new Map01();
this.world = world;
this.camera = new OrthographicCamera();
this.viewport = new ExtendViewport(0, 3072, camera);
centerCamera(map);
batchRenderer = new SpriteBatch();
}
public void render() {
Gdx.gl.glClearColor(0.11f, 0.6f, 0.89f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT | (Gdx.graphics.getBufferFormat().coverageSampling?GL20.GL_COVERAGE_BUFFER_BIT_NV:0));
renderer.setView(camera);
renderer.render();
map.render();
batchRenderer.begin();
AssetLoader.font.getData().setScale(8);
AssetLoader.font.draw(batchRenderer, map.getSelectedTile().getName(), -400, 1500);
batchRenderer.end();
}
public void resize(int width, int height){
viewport.update(width, height);
renderer = new IsometricTiledMapRenderer(map.getTiledMap(), MapUtils.unitScale(map));
batchRenderer.setProjectionMatrix(camera.combined);
centerCamera(map);
}
private void centerCamera(GameMap map){
camera.position.set(MapUtils.getMapCenter(map));
}
I could almost certainly make it work with what I have, but it seems like I'm missing something painfully simple. It's probably a good idea to have a solid foundation and functional coordinate system, before I start implementing the actual gameplay.
Here is a picture of the map in question if that is of any help. Thanks in advance for any advice.