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.
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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.
Original file line number Diff line number Diff line change
@@ -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.