Skip to content

Commit

Permalink
feat: completed basic isometric support for .tmx, closes #1151
Browse files Browse the repository at this point in the history
  • Loading branch information
AlmasB committed Mar 28, 2023
1 parent 74cfdb5 commit 182d9e3
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 7 deletions.
Expand Up @@ -305,15 +305,24 @@ class TilesetLoader(private val map: TiledMap, private val mapURL: URL) {
return ImageView(bufferBottom)
}

/**
* Loads the layer using an isometric projection:
* buffer x = (x-y) * map.tilewidth / 2
* buffer y = (x+y) * map.tileheight / 2
*
* in the first case above, we use (maxY - y) instead of just y because we flip the y axis,
* where maxY = layer.height - 1
*/
fun loadViewIsometric(layerName: String): Node {
log.warning("Isometric maps are not fully implemented: https://github.com/AlmasB/FXGL/issues/1151")
log.debug("Loading isometric view for layer $layerName")

val layer = map.getLayerByName(layerName)

// from the formula above, we calculate maximal dimensions of the buffer
// +1 to handle rounding errors due to integer division
val buffer = WritableImage(
layer.width * map.tilewidth,
layer.height * map.tileheight
(layer.width + layer.height) * (map.tilewidth / 2 + 1),
(layer.width + layer.height) * (map.tileheight / 2 + 1)
)

log.debug("Created buffer with size ${buffer.width}x${buffer.height}")
Expand Down Expand Up @@ -364,10 +373,24 @@ class TilesetLoader(private val map: TiledMap, private val mapURL: URL) {
srcy = 0
}

buffer.pixelWriter.setPixels(x * map.tilewidth, y * map.tileheight,
w, h, sourceImage.pixelReader,
srcx,
srcy)
val bufferX = (x + map.height-1 - y) * map.tilewidth / 2
val bufferY = (x + y) * map.tileheight / 2

// pixelWriter.setPixels replaces pixels, does not blend them
// in order to take into account transparency, we have to draw pixels 1 by 1
for (dy in 0 until h) {
for (dx in 0 until w) {
val c = sourceImage.pixelReader.getColor(srcx + dx, srcy + dy)

if (c != Color.TRANSPARENT) {
buffer.pixelWriter.setColor(
bufferX + dx,
bufferY + dy,
c
)
}
}
}
}

return ImageView(buffer)
Expand Down
Expand Up @@ -189,6 +189,15 @@ class TMXLevelLoaderTest {
assertThat(view.image.pixelReader.getColor(31,16), `is`((Color.TRANSPARENT)))
}

@Test
fun `Load isometric tmx level`() {
val world = GameWorld()

val level = TMXLevelLoader().load(javaClass.getResource("iso/simple.tmx"), world)

assertThat(level.entities.size, `is`(2))
}

@ParameterizedTest
@CsvSource("sewers_v1_1_2.tmx", "sewers_v1_2_3.tmx", "sewers_v1_9_0.tmx")
fun parse(mapName: String) {
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.9" tiledversion="1.9.0" orientation="isometric" renderorder="right-down" width="25" height="16" tilewidth="128" tileheight="64" infinite="0" nextlayerid="3" nextobjectid="1">
<tileset firstgid="1" name="tile1" tilewidth="133" tileheight="83" tilecount="1" columns="1">
<image source="tile1.png" trans="ffffff" width="133" height="83"/>
</tileset>
<tileset firstgid="2" name="barrel" tilewidth="133" tileheight="83" tilecount="1" columns="1">
<image source="barrel.png" trans="ffffff" width="133" height="83"/>
</tileset>
<layer id="1" name="floor" width="25" height="16">
<data encoding="csv">
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,
1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,
1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,
1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,
1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,
1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,
1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,
1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,
1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,
1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,
1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
</data>
</layer>
<layer id="2" name="decor" width="25" height="16">
<data encoding="csv">
0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
</data>
</layer>
</map>
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 182d9e3

Please sign in to comment.