From b906c41be81fb97e3173edcfb768a776f079b1cd Mon Sep 17 00:00:00 2001 From: minjaesong Date: Wed, 15 Dec 2021 16:56:36 +0900 Subject: [PATCH] new minimap working and not working --- .../terrarum/blockstats/MinimapComposer.kt | 117 ++++++------------ .../modulebasegame/ui/UIInventoryFull.kt | 2 +- .../modulebasegame/ui/UIInventoryMinimap.kt | 84 +++++++++---- 3 files changed, 95 insertions(+), 108 deletions(-) diff --git a/src/net/torvald/terrarum/blockstats/MinimapComposer.kt b/src/net/torvald/terrarum/blockstats/MinimapComposer.kt index 6efde46c2..d2517808d 100644 --- a/src/net/torvald/terrarum/blockstats/MinimapComposer.kt +++ b/src/net/torvald/terrarum/blockstats/MinimapComposer.kt @@ -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(TILES_IN_X * TILES_IN_Y * 2) + private val updaterQueue = Queue(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) } \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryFull.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryFull.kt index 5bc4843d0..76d7bdc60 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryFull.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryFull.kt @@ -294,7 +294,7 @@ class UIInventoryFull( override fun endClosing(delta: Float) { INGAME.setTooltipMessage(null) // required! - MinimapComposer.revalidateAll() +// MinimapComposer.revalidateAll() } diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryMinimap.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryMinimap.kt index 19b5c358a..7f7b46c5a 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryMinimap.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryMinimap.kt @@ -5,12 +5,17 @@ import com.badlogic.gdx.Input import com.badlogic.gdx.graphics.* import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.glutils.FrameBuffer +import com.badlogic.gdx.utils.GdxRuntimeException import net.torvald.terrarum.* +import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE import net.torvald.terrarum.blockstats.MinimapComposer +import net.torvald.terrarum.blockstats.MinimapComposer.MINIMAP_TILE_HEIGHT +import net.torvald.terrarum.blockstats.MinimapComposer.MINIMAP_TILE_WIDTH import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVENTORY_CELLS_OFFSET_Y import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVENTORY_CELLS_UI_HEIGHT import net.torvald.terrarum.ui.Toolkit import net.torvald.terrarum.ui.UICanvas +import kotlin.math.roundToInt class UIInventoryMinimap(val full: UIInventoryFull) : UICanvas() { @@ -30,17 +35,25 @@ class UIInventoryMinimap(val full: UIInventoryFull) : UICanvas() { override var openCloseTime = 0.0f private var minimapZoom = 1f - private var minimapPanX = -MinimapComposer.totalWidth / 2f - private var minimapPanY = -MinimapComposer.totalHeight / 2f + private var minimapPanX: Float = INGAME.actorNowPlaying?.intTilewiseHitbox?.centeredX?.toFloat() ?: (INGAME.world.width / 2f) + private var minimapPanY: Float = INGAME.actorNowPlaying?.intTilewiseHitbox?.centeredY?.toFloat() ?: (INGAME.world.height / 2f) + + private var minimapTranslateX: Float = 0f + private var minimapTranslateY: Float = 0f + private val minimapFBO = FrameBuffer(Pixmap.Format.RGBA8888, MINIMAP_WIDTH.toInt(), MINIMAP_HEIGHT.toInt(), false) private val minimapCamera = OrthographicCamera(MINIMAP_WIDTH, MINIMAP_HEIGHT) private var minimapRerenderTimer = 0f - private val minimapRerenderInterval = .5f + private val minimapRerenderInterval = 5f // seconds + + private var dragStatus = 0 + + private var renderTextures = Array(MinimapComposer.pixmaps.size) { Texture(16, 16, Pixmap.Format.RGBA8888) } override fun updateUI(delta: Float) { MinimapComposer.setWorld(INGAME.world) - MinimapComposer.update() +// MinimapComposer.update() minimapRerenderTimer += Gdx.graphics.deltaTime } @@ -53,8 +66,18 @@ class UIInventoryMinimap(val full: UIInventoryFull) : UICanvas() { // if left click is down and cursor is in the map area if (Terrarum.mouseDown && Terrarum.mouseScreenY in cellOffY..cellOffY + INVENTORY_CELLS_UI_HEIGHT) { - minimapPanX += Terrarum.mouseDeltaX * 2f / minimapZoom - minimapPanY += Terrarum.mouseDeltaY * 2f / minimapZoom + val mdx = Terrarum.mouseDeltaX * 2f / minimapZoom + val mdy = Terrarum.mouseDeltaY * 2f / minimapZoom + + minimapPanX += mdx + minimapPanY += mdy + minimapTranslateX += mdx + minimapTranslateY += mdy + + dragStatus = 1 + } + else if (dragStatus == 1 && !Terrarum.mouseDown) { + dragStatus = 2 } @@ -66,8 +89,8 @@ class UIInventoryMinimap(val full: UIInventoryFull) : UICanvas() { } if (Gdx.input.isKeyPressed(Input.Keys.NUM_3)) { minimapZoom = 1f - minimapPanX = -MinimapComposer.totalWidth / 2f - minimapPanY = -MinimapComposer.totalHeight / 2f + minimapPanX = INGAME.actorNowPlaying?.intTilewiseHitbox?.centeredX?.toFloat() ?: (INGAME.world.width / 2f) + minimapPanY = INGAME.actorNowPlaying?.intTilewiseHitbox?.centeredY?.toFloat() ?: (INGAME.world.height / 2f) } @@ -86,19 +109,18 @@ class UIInventoryMinimap(val full: UIInventoryFull) : UICanvas() { // render minimap batch.end() - if (minimapRerenderTimer >= minimapRerenderInterval) { + if (dragStatus == 2 || minimapRerenderTimer >= minimapRerenderInterval) { + dragStatus = 0 minimapRerenderTimer = 0f - MinimapComposer.requestRender() + + MinimapComposer.queueRender(minimapPanX.roundToInt(), minimapPanY.roundToInt()) + + minimapTranslateX = 0f + minimapTranslateY = 0f } - MinimapComposer.renderToBackground() minimapFBO.inActionF(minimapCamera, batch) { - // whatever. - MinimapComposer.tempTex.dispose() - MinimapComposer.tempTex = Texture(MinimapComposer.minimap) - MinimapComposer.tempTex.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Nearest) - batch.inUse { // [ 1 0 0 ] [ s 0 0 ] [ s 0 0 ] @@ -107,27 +129,36 @@ class UIInventoryMinimap(val full: UIInventoryFull) : UICanvas() { // // https://www.wolframalpha.com/input/?i=%7B%7B1,0,0%7D,%7B0,1,0%7D,%7Bp_x,p_y,1%7D%7D+*+%7B%7Bs,0,0%7D,%7B0,s,0%7D,%7Bw%2F2,h%2F2,1%7D%7D - val tx = minimapPanX * minimapZoom + 0.5f * MINIMAP_WIDTH - val ty = minimapPanY * minimapZoom + 0.5f * MINIMAP_HEIGHT - // sky background batch.color = MINIMAP_SKYCOL Toolkit.fillArea(batch, 0f, 0f, MINIMAP_WIDTH, MINIMAP_HEIGHT) - // the actual image - batch.color = Color.WHITE - batch.draw(MinimapComposer.tempTex, tx, ty, MinimapComposer.totalWidth * minimapZoom, MinimapComposer.totalHeight * minimapZoom) + MinimapComposer.pixmaps.forEachIndexed { index, pixmap -> + renderTextures[index].dispose() + renderTextures[index] = Texture(pixmap) + + val ix = index % 3; val iy = index / 3 + + val ox = (ix - 1) * MINIMAP_TILE_WIDTH + val oy = (iy - 1) * MINIMAP_TILE_HEIGHT + + val tx = (minimapTranslateX - ox) * minimapZoom + 0.5f * MINIMAP_WIDTH + val ty = (minimapTranslateY - oy) * minimapZoom + 0.5f * MINIMAP_HEIGHT + + batch.color = Color.WHITE + batch.draw(renderTextures[index], tx, ty, MINIMAP_TILE_WIDTH * minimapZoom, MINIMAP_TILE_HEIGHT * minimapZoom) + } } } batch.begin() - if (debugvals) { - App.fontSmallNumbers.draw(batch, "$minimapPanX, $minimapPanY; x$minimapZoom", (width - MINIMAP_WIDTH) / 2, -10f + cellOffY) - } - val minimapDrawX = (width - MINIMAP_WIDTH) / 2 val minimapDrawY = (height - cellOffY - App.scr.tvSafeGraphicsHeight - MINIMAP_HEIGHT - 72) / 2 + cellOffY * 1f + if (debugvals) { + App.fontSmallNumbers.draw(batch, "$minimapPanX, $minimapPanY; x$minimapZoom", minimapDrawX, minimapDrawY - 16f) + } + batch.color = Color.WHITE batch.projectionMatrix = camera.combined @@ -153,5 +184,6 @@ class UIInventoryMinimap(val full: UIInventoryFull) : UICanvas() { override fun dispose() { minimapFBO.dispose() + renderTextures.forEach { try { it.dispose() } catch (e: GdxRuntimeException) {} } } } \ No newline at end of file