Skip to content
This repository has been archived by the owner on Jul 8, 2022. It is now read-only.

Fix problem with tiles near viewport edge sometimes not being drawn w… #639

Merged
merged 4 commits into from
May 16, 2022
Merged

Conversation

americanjeff
Copy link
Contributor

…hen tilemap container is rotated (e.g. camera angle change)

…hen tilemap container is rotated (e.g. camera angle change)
@soywiz
Copy link
Contributor

soywiz commented May 11, 2022

@americanjeff thanks for the PR! In which cases does this PR fixes the issue? Is it a small rotation? A full 180º rotation, or other cases?

@americanjeff
Copy link
Contributor Author

I only tested manually with a little demo I wrote but it seems to happen at a variety of angles https://youtube.com/shorts/3aVCVrIKlLE

Here's a little demo I wrote to test it

import com.soywiz.korge.*
import com.soywiz.korge.input.onScroll
import com.soywiz.korge.view.*
import com.soywiz.korge.view.camera.cameraContainer
import com.soywiz.korge.view.tiles.TileSet
import com.soywiz.korge.view.tiles.tileMap
import com.soywiz.korim.bitmap.Bitmap32
import com.soywiz.korim.color.*
import com.soywiz.korma.geom.*
import com.soywiz.korma.geom.Point.Companion.Zero
import kotlin.random.Random
import kotlin.math.*

suspend fun main() = Korge(width = 1024, height = 1024, bgcolor = Colors["#2b2b2b"]) {
	val tileSize = 200
	val tileSet = makeSimpleTileSet(tileSize)
	val mapSize = 100
	val donutMap = makeDonutMap(mapSize, tileSet)

	val cameraContainer = cameraContainer(width, height) {
		tileMap(donutMap, tileSet).centerOn(this)
	}
	cameraContainer.cameraY = -9000.0
	val statusOverlay = text("")

	var zoom = 0.0
	onScroll {
		println("onscroll: ${it.scrollDeltaYPixels}")
		zoom -= (it.scrollDeltaYPixels / 240)
		cameraContainer.cameraZoom = 2.0.pow(zoom)
	}

	var wasDown = false
	val downVals = object {
		var mouse: Point = Point()
		var camAngle: Angle = 0.degrees
		var camPos: Point = Point()
	}

	addUpdater {
		val mouseButtons = input.mouseButtons
		val isDown = (mouseButtons and 5) != 0
		if (isDown) {
			if (!wasDown) {
				wasDown = true
				downVals.mouse.copyFrom(input.mouse)
				downVals.camAngle = cameraContainer.cameraAngle
				downVals.camPos = Point(cameraContainer.cameraX, cameraContainer.cameraY)
			} else {
				val rightMouse = (mouseButtons and 4) != 0
				if (rightMouse) {
					val downAngle = Zero.angleTo(downVals.mouse)
					val mouseAngle = Zero.angleTo(input.mouse)
					val newAngle = downVals.camAngle - (downAngle - mouseAngle)
					val dy = downVals.mouse.y - input.mouse.y
					cameraContainer.cameraAngle = newAngle //downVals.camAngle - dy.degrees
				} else { // leftMouse
					val newCamPos =
						cameraContainer.content.globalToLocal(downVals.mouse) - cameraContainer.content.globalToLocal(input.mouse) + downVals.camPos
					cameraContainer.cameraX = newCamPos.x
					cameraContainer.cameraY = newCamPos.y
				}
			}
		}
		statusOverlay.text =  "zoom: $zoom\nangle: ${cameraContainer.cameraAngle}\npos: ${cameraContainer.cameraX}, ${cameraContainer.cameraY}"
		wasDown = isDown
	}
}

private fun makeDonutMap(
	mapWidth: Int,
	tileSet: TileSet
): Bitmap32 {
	val rand = Random(3)
	val mapValues2 = Bitmap32(mapWidth, mapWidth)
	val center = Point(mapWidth / 2, mapWidth / 2)
	for (x in 0 until mapWidth) for (y in 0 until mapWidth) {
		val p = Point(x, y)
		val dist = (p - center).length
		val onDisc = dist < mapWidth / 2
		val tooClose = dist < (mapWidth / 2) * 0.7
		mapValues2.intData[x * mapWidth + y] =
			if (onDisc && !tooClose) 1 + rand.nextInt(tileSet.texturesMap.size - 1) else 0
	}
	return mapValues2
}

private fun makeSimpleTileSet(tileWidth: Int): TileSet {
	val tileBitmaps =
		listOf(Colors.TRANSPARENT_BLACK, Colors.GREEN, Colors.ORANGE, Colors.GREENYELLOW, Colors.YELLOW).map { c ->
			Bitmap32(tileWidth, tileWidth).also {
				it.fill(c)
				for (i in (tileWidth / 5) until (tileWidth * 4 / 5)) {
					it[i, tileWidth / 2] = Colors.TRANSPARENT_BLACK
					it[tileWidth / 2, i] = Colors.TRANSPARENT_BLACK
				}
			}
		}
	return TileSet.fromBitmaps(tileWidth, tileWidth, tileBitmaps)
}

@soywiz soywiz merged commit 8638d92 into korlibs-archive:main May 16, 2022
@soywiz
Copy link
Contributor

soywiz commented May 16, 2022

Awesome. Thank you very much!

I have added your sample here: aab6102
It is possible to run it locally with ./gradlew :korge-sandbox:runJvm (and uncommenting the line in the main.kt in the case another sample is loaded)

soywiz added a commit that referenced this pull request May 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants