new minimap working and not working

This commit is contained in:
minjaesong
2021-12-15 16:56:36 +09:00
parent 0027b747b4
commit b906c41be8
3 changed files with 95 additions and 108 deletions

View File

@@ -2,16 +2,20 @@ package net.torvald.terrarum.blockstats
import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.glutils.FrameBuffer
import com.badlogic.gdx.utils.Disposable
import com.badlogic.gdx.utils.GdxRuntimeException
import com.badlogic.gdx.utils.Queue
import net.torvald.terrarum.App
import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.modulebasegame.ui.UIInventoryMinimap.Companion.MINIMAP_HEIGHT
import net.torvald.terrarum.modulebasegame.ui.UIInventoryMinimap.Companion.MINIMAP_WIDTH
object MinimapComposer : Disposable {
// strategy: mosaic the textures, maximum texture size is 4 096.
val MINIMAP_TILE_WIDTH = MINIMAP_WIDTH.toInt() + 16
val MINIMAP_TILE_HEIGHT = MINIMAP_HEIGHT.toInt() + 16
private var world: GameWorld = GameWorld.makeNullWorld()
@@ -32,53 +36,40 @@ object MinimapComposer : Disposable {
}
}
var tempTex = Texture(1,1,Pixmap.Format.RGBA8888)
// total size of the minimap. Remember: textures can be mosaic-ed to display full map.
var totalWidth = 0
var totalHeight = 0
val pixmaps = Array(9) { Pixmap(MINIMAP_TILE_WIDTH, MINIMAP_TILE_HEIGHT, Pixmap.Format.RGBA8888) }
/** World coord for top-left side of the tileslot. ALWAYS multiple of LIVETILE_SIZE */
var topLeftCoordX = 0
/** World coord for top-left side of the tileslot. ALWAYS multiple of LIVETILE_SIZE */
var topLeftCoordY = 0
const val LIVETILE_SIZE = 64
const val DISPLAY_CANVAS_WIDTH = 2048 // must be divisible by LIVETILE_SIZE
const val DISPLAY_CANVAS_HEIGHT = 1024 // must be divisible by LIVETILE_SIZE
val minimap = Pixmap(DISPLAY_CANVAS_WIDTH, DISPLAY_CANVAS_HEIGHT, Pixmap.Format.RGBA8888)
const val TILES_IN_X = DISPLAY_CANVAS_WIDTH / LIVETILE_SIZE
const val TILES_IN_Y = DISPLAY_CANVAS_HEIGHT / LIVETILE_SIZE
// numbers inside of it will change a lot
private val tilemap = Array(TILES_IN_Y) { y -> IntArray(TILES_IN_X) { x -> y * TILES_IN_X + x } }
// pixmaps inside of this will never be redefined
private val liveTiles = Array(TILES_IN_X * TILES_IN_Y) { Pixmap(LIVETILE_SIZE, LIVETILE_SIZE, Pixmap.Format.RGBA8888) }
// indices are exacly the same as liveTiles
private val liveTilesMeta = Array(TILES_IN_X * TILES_IN_Y) { LiveTileMeta(revalidate = true) }
private val updaterQueue = Queue<Runnable>(TILES_IN_X * TILES_IN_Y * 2)
private val updaterQueue = Queue<Runnable>(pixmaps.size)
private var currentThreads = Array(maxOf(1, App.THREAD_COUNT.times(2).div(3))) {
Thread()
}
init {
totalWidth = minimap.width
totalHeight = minimap.height
App.disposables.add(this)
}
fun update() {
/**
* @param x player-centric
* @param y player-centric
*/
fun queueRender(x: Int, y: Int) {
val tlx = x - (MINIMAP_TILE_WIDTH / 2)
val tly = y - (MINIMAP_TILE_HEIGHT / 2)
// printdbg(this, "queue render - c($x,$y), tl($tlx,$tlx)")
// make the queueing work
// enqueue first
for (y in tilemap.indices) {
for (x in tilemap[0].indices) {
if (liveTilesMeta[tilemap[y][x]].revalidate) {
liveTilesMeta[tilemap[y][x]].revalidate = false
updaterQueue.addLast(createUpdater(x, y))
printdbg(this, "Queueing tilemap update ($x,$y); queue size now: ${updaterQueue.size}")
}
}
pixmaps.forEachIndexed { i, pixmap ->
val tx = tlx + (MINIMAP_TILE_WIDTH * ((i % 3) - 1))
val ty = tly + (MINIMAP_TILE_HEIGHT * ((i / 3) - 1))
updaterQueue.addLast(createUpdater(tx, ty, pixmap))
printdbg(this, "Queueing tilemap update ($tx,$ty); queue size now: ${updaterQueue.size}")
}
// consume the queue
for (k in currentThreads.indices) {
if (currentThreads[k].state == Thread.State.TERMINATED && !updaterQueue.isEmpty) {
@@ -89,48 +80,18 @@ object MinimapComposer : Disposable {
currentThreads[k].start()
}
}
// assign tiles to the tilemap
// TODO
}
fun revalidateAll() {
liveTilesMeta.forEach { it.revalidate = true }
}
private var rerender = true
/**
* When to call:
* - every 5 seconds or so
* - every .5 seconds for 10 seconds after the tilemap changed
*/
fun requestRender() {
printdbg(this, "Rerender requested")
rerender = true
}
fun renderToBackground() {
if (rerender) {
for (y in 0 until TILES_IN_Y) {
for (x in 0 until TILES_IN_X) {
minimap.drawPixmap(liveTiles[tilemap[y][x]], x * LIVETILE_SIZE, y * LIVETILE_SIZE)
}
}
rerender = false
}
}
private val HQRNG = net.torvald.random.HQRNG()
private fun createUpdater(tileSlotIndexX: Int, tileSlotIndexY: Int) = Runnable {
val pixmap = liveTiles[tilemap[tileSlotIndexY][tileSlotIndexX]]
val topLeftX = topLeftCoordX + LIVETILE_SIZE * tileSlotIndexX
val topLeftY = topLeftCoordY + LIVETILE_SIZE * tileSlotIndexY
for (y in topLeftY until topLeftY + LIVETILE_SIZE) {
for (x in if (tileSlotIndexY >= TILES_IN_X / 2) (topLeftX + LIVETILE_SIZE - 1) downTo topLeftX else topLeftX until topLeftX + LIVETILE_SIZE) {
/**
* @param tx top-left
* @param ty top-left
* @param pixmap pixmap to draw pixels on
*/
private fun createUpdater(tx: Int, ty: Int, pixmap: Pixmap) = Runnable {
for (y in ty until ty + MINIMAP_TILE_HEIGHT) {
for (x in tx until tx + MINIMAP_TILE_WIDTH) {
val tileTerr = world.getTileFromTerrain(x, y)
val wallTerr = world.getTileFromWall(x, y)
val colTerr = App.tileMaker.terrainTileColourMap.get(tileTerr)!!.toGdxColor()
@@ -141,19 +102,13 @@ object MinimapComposer : Disposable {
pixmap.blending = Pixmap.Blending.None
pixmap.setColor(outCol)
//pixmap.setColor(Color.CORAL)
pixmap.drawPixel(x - topLeftX, y - topLeftY)
pixmap.drawPixel(x, y)
}
}
}
override fun dispose() {
liveTiles.forEach { it.dispose() }
minimap.dispose()
try {
tempTex.dispose()
}
catch (e: GdxRuntimeException) {}
pixmaps.forEach { it.dispose() }
}
private data class LiveTileMeta(var revalidate: Boolean)
}