Skip to content

Commit

Permalink
Fixes #238: Support tilemap rotated/reflected tiles (#249)
Browse files Browse the repository at this point in the history
  • Loading branch information
soywiz authored Jul 6, 2020
1 parent 40fd6a4 commit 7c99782
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 7 deletions.
63 changes: 58 additions & 5 deletions korge/src/commonMain/kotlin/com/soywiz/korge/view/tiles/TileMap.kt
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,13 @@ open class TileMap(val intMap: IntArray2, val tileset: TileSet) : View() {

if (rx < 0 || rx >= intMap.width) continue
if (ry < 0 || ry >= intMap.height) continue
val tex = tileset[intMap[rx, ry]] ?: continue
val cell = intMap[rx, ry]
val cellData = cell.extract(0, 28)
val flipX = cell.extract(31)
val flipY = cell.extract(30)
val rotate = cell.extract(29)

val tex = tileset[cellData] ?: continue

val info = verticesPerTex.getOrPut(tex.bmp) {
infosPool.alloc().also { info ->
Expand Down Expand Up @@ -137,10 +143,22 @@ open class TileMap(val intMap: IntArray2, val tileset: TileSet) : View() {
val p3X = p0X + dVX
val p3Y = p0Y + dVY

info.vertices.quadV(info.vcount++, p0X, p0Y, tex.tl_x, tex.tl_y, colMul, colAdd)
info.vertices.quadV(info.vcount++, p1X, p1Y, tex.tr_x, tex.tr_y, colMul, colAdd)
info.vertices.quadV(info.vcount++, p2X, p2Y, tex.br_x, tex.br_y, colMul, colAdd)
info.vertices.quadV(info.vcount++, p3X, p3Y, tex.bl_x, tex.bl_y, colMul, colAdd)
tempX[0] = tex.tl_x
tempX[1] = tex.tr_x
tempX[2] = tex.br_x
tempX[3] = tex.bl_x

tempY[0] = tex.tl_y
tempY[1] = tex.tr_y
tempY[2] = tex.br_y
tempY[3] = tex.bl_y

computeIndices(flipX = flipX, flipY = flipY, rotate = rotate, indices = indices)

info.vertices.quadV(info.vcount++, p0X, p0Y, tempX[indices[0]], tempY[indices[0]], colMul, colAdd)
info.vertices.quadV(info.vcount++, p1X, p1Y, tempX[indices[1]], tempY[indices[1]], colMul, colAdd)
info.vertices.quadV(info.vcount++, p2X, p2Y, tempX[indices[2]], tempY[indices[2]], colMul, colAdd)
info.vertices.quadV(info.vcount++, p3X, p3Y, tempX[indices[3]], tempY[indices[3]], colMul, colAdd)
}

info.icount += 6
Expand All @@ -150,6 +168,10 @@ open class TileMap(val intMap: IntArray2, val tileset: TileSet) : View() {
renderTilesCounter?.increment(count)
}

private val indices = IntArray(4)
private val tempX = FloatArray(4)
private val tempY = FloatArray(4)

// @TOOD: Use a TextureVertexBuffer or something
@KorgeInternal
private class Info(var tex: Bitmap, var vertices: TexturedVertexArray) {
Expand All @@ -161,6 +183,37 @@ open class TileMap(val intMap: IntArray2, val tileset: TileSet) : View() {
private val infos = arrayListOf<Info>()
companion object {
private val dummyTexturedVertexArray = TexturedVertexArray(0, IntArray(0))

fun computeIndices(flipX: Boolean, flipY: Boolean, rotate: Boolean, indices: IntArray = IntArray(4)): IntArray {
indices[0] = 0 // TL
indices[1] = 1 // TR
indices[2] = 2 // BR
indices[3] = 3 // BL

if (rotate) {
indices.swap(TR, BL)
}
if (flipY) {
indices.swap(TL, BL)
indices.swap(TR, BR)
}
if (flipX) {
indices.swap(TL, TR)
indices.swap(BL, BR)
}
return indices
}

private fun IntArray.swap(a: Int, b: Int): IntArray = this.apply {
val t = this[a]
this[a] = this[b]
this[b] = t
}

private const val TL = 0
private const val TR = 1
private const val BR = 2
private const val BL = 3
}
private val infosPool = Pool { Info(Bitmaps.transparent.bmp, dummyTexturedVertexArray) }

Expand Down
14 changes: 12 additions & 2 deletions korge/src/commonTest/kotlin/com/soywiz/korge/tiled/TiledMapTest.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package com.soywiz.korge.tiled

import com.soywiz.korge.*
import com.soywiz.kmem.*
import com.soywiz.korge.internal.*
import com.soywiz.korge.tests.*
import com.soywiz.korge.util.*
import com.soywiz.korge.view.tiles.*
import com.soywiz.korim.bitmap.*
import com.soywiz.korim.color.*
Expand Down Expand Up @@ -78,4 +77,15 @@ class TiledMapTest : ViewsForTesting() {
tileMap.intMap[1, 0] = 1
tileMap.render(views.renderContext)
}

@Test
fun testTileMapFlipRotateIndices() {
assertEquals(
"0123, 0321, 3210, 1230, 1032, 3012, 2301, 2103",
(0 until 8).joinToString(", ") {
TileMap.computeIndices(flipX = it.extract(2), flipY = it.extract(1), rotate = it.extract(0))
.joinToString("")
}
)
}
}

0 comments on commit 7c99782

Please sign in to comment.