From 0288fa58d930c506b661182199f59d090431aced Mon Sep 17 00:00:00 2001 From: minjaesong Date: Thu, 13 Jul 2017 19:10:11 +0900 Subject: [PATCH] Rudimentary load screen works (only with Ingame screen) --- src/net/torvald/dataclass/HistoryArray.kt | 4 + src/net/torvald/terrarum/Ingame.kt | 85 +++++--- src/net/torvald/terrarum/LoadScreen.kt | 185 ++++++++++-------- src/net/torvald/terrarum/Terrarum.kt | 9 +- .../ThreadProcessNoiseLayers.kt | 4 + .../terrarum/worldgenerator/WorldGenerator.kt | 10 +- 6 files changed, 181 insertions(+), 116 deletions(-) diff --git a/src/net/torvald/dataclass/HistoryArray.kt b/src/net/torvald/dataclass/HistoryArray.kt index 2eb1826bd..b02a1bbfd 100644 --- a/src/net/torvald/dataclass/HistoryArray.kt +++ b/src/net/torvald/dataclass/HistoryArray.kt @@ -59,4 +59,8 @@ class HistoryArray(val size: Int) { val oldest: T? get() = this[history.size - 1] + fun clear() { + history.clear() + } + } \ No newline at end of file diff --git a/src/net/torvald/terrarum/Ingame.kt b/src/net/torvald/terrarum/Ingame.kt index ecc7d87df..69994b1bc 100644 --- a/src/net/torvald/terrarum/Ingame.kt +++ b/src/net/torvald/terrarum/Ingame.kt @@ -144,8 +144,9 @@ class Ingame(val batch: SpriteBatch) : Screen { //private val ingameDrawThread: ThreadIngameDraw // draw must be on the main thread - private var gameFullyLoaded = false - + var gameFullyLoaded = false + private set + private var postInitDone = false ////////////// @@ -196,7 +197,7 @@ class Ingame(val batch: SpriteBatch) : Screen { } override fun show() { - initViewPort(Terrarum.WIDTH, Terrarum.HEIGHT) + //initViewPort(Terrarum.WIDTH, Terrarum.HEIGHT) // gameLoadMode and gameLoadInfoPayload must be set beforehand!! @@ -225,54 +226,65 @@ class Ingame(val batch: SpriteBatch) : Screen { */ private fun enter(gameSaveData: GameSaveData) { if (gameFullyLoaded) { - Error("You are doing horribly wrong, fucknugget.") + println("[Ingame] loaded successfully.") } + else { + LoadScreen.addMessage("Loading world from save") - world = gameSaveData.world - historicalFigureIDBucket = gameSaveData.historicalFigureIDBucket - playableActorDelegate = PlayableActorDelegate(gameSaveData.realGamePlayer) - addNewActor(player!!) + + world = gameSaveData.world + historicalFigureIDBucket = gameSaveData.historicalFigureIDBucket + playableActorDelegate = PlayableActorDelegate(gameSaveData.realGamePlayer) + addNewActor(player!!) - initGame() + //initGame() - gameFullyLoaded = true + gameFullyLoaded = true + } } - /** * Init instance by creating new world */ private fun enter(worldParams: NewWorldParameters) { - - // init map as chosen size - world = GameWorld(worldParams.width, worldParams.height) - - // generate terrain for the map - WorldGenerator.attachMap(world) - WorldGenerator.SEED = worldParams.worldGenSeed - WorldGenerator.generateMap() + if (gameFullyLoaded) { + println("[Ingame] loaded successfully.") + } + else { + LoadScreen.addMessage("Creating new world") - historicalFigureIDBucket = ArrayList() + // init map as chosen size + world = GameWorld(worldParams.width, worldParams.height) + + // generate terrain for the map + WorldGenerator.attachMap(world) + WorldGenerator.SEED = worldParams.worldGenSeed + WorldGenerator.generateMap() - RoguelikeRandomiser.seed = HQRNG().nextLong() + historicalFigureIDBucket = ArrayList() - // add new player and put it to actorContainer - playableActorDelegate = PlayableActorDelegate(PlayerBuilderSigrid()) - //playableActorDelegate = PlayableActorDelegate(PlayerBuilderTestSubject1()) - addNewActor(player!!) + RoguelikeRandomiser.seed = HQRNG().nextLong() - // test actor - //addNewActor(PlayerBuilderCynthia()) + // add new player and put it to actorContainer + //playableActorDelegate = PlayableActorDelegate(PlayerBuilderSigrid()) + //playableActorDelegate = PlayableActorDelegate(PlayerBuilderTestSubject1()) + //addNewActor(player!!) + // test actor + //addNewActor(PlayerBuilderCynthia()) - initGame() + + //initGame() + + gameFullyLoaded = true + } } fun initGame() { @@ -394,6 +406,23 @@ class Ingame(val batch: SpriteBatch) : Screen { } override fun render(delta: Float) { + if (!postInitDone) { // Q&D solution for LoadScreen and Ingame, where while LoadScreen is working, Ingame now no longer has GL Context + + if (gameLoadMode == GameLoadMode.CREATE_NEW) { + playableActorDelegate = PlayableActorDelegate(PlayerBuilderSigrid()) + addNewActor(player!!) + } + + initGame() + + + postInitDone = true + } + + + + + Gdx.graphics.setTitle(GAME_NAME + " — F: ${Gdx.graphics.framesPerSecond} (${Terrarum.TARGET_INTERNAL_FPS})" + " — M: ${Terrarum.memInUse}M / ${Terrarum.memTotal}M / ${Terrarum.memXmx}M" diff --git a/src/net/torvald/terrarum/LoadScreen.kt b/src/net/torvald/terrarum/LoadScreen.kt index e808dce36..ee7083982 100644 --- a/src/net/torvald/terrarum/LoadScreen.kt +++ b/src/net/torvald/terrarum/LoadScreen.kt @@ -15,8 +15,8 @@ import net.torvald.terrarum.langpack.Lang */ object LoadScreen : ScreenAdapter() { - private lateinit var actualSceneToBeLoaded: Screen - private lateinit var sceneLoadingThread: Thread + var screenToLoad: Ingame? = null + private lateinit var screenLoadingThread: Thread private val messages = HistoryArray(20) @@ -49,9 +49,6 @@ object LoadScreen : ScreenAdapter() { var camera = OrthographicCamera(Terrarum.WIDTH.toFloat(), Terrarum.HEIGHT.toFloat()) fun initViewPort(width: Int, height: Int) { - //val width = if (width % 1 == 1) width + 1 else width - //val height = if (height % 1 == 1) height + 1 else width - // Set Y to point downwards camera.setToOrtho(true, width.toFloat(), height.toFloat()) @@ -65,6 +62,24 @@ object LoadScreen : ScreenAdapter() { override fun show() { + messages.clear() + + + if (screenToLoad == null) { + println("[LoadScreen] Screen to load is not set. Are you testing the UI?") + } + else { + val runnable = object : Runnable { + override fun run() { + screenToLoad!!.show() + } + } + screenLoadingThread = Thread(runnable, "LoadScreen GameLoader") + + screenLoadingThread.start() + } + + initViewPort(Terrarum.WIDTH, Terrarum.HEIGHT) textFbo = FrameBuffer( @@ -78,10 +93,6 @@ object LoadScreen : ScreenAdapter() { arrowObjGlideOffsetX = -arrowObjTex.width.toFloat() textOverlayTex = Texture(Gdx.files.internal("assets/graphics/test_loading_text_tint.tga")) - - - addMessage("**** This is a test ****") - addMessage("Segmentation fault") } @@ -90,97 +101,101 @@ object LoadScreen : ScreenAdapter() { private var genuineSonic = false // the "NOW LOADING..." won't appear unless the arrow first run passes it (it's totally not a GenuineIntel tho) override fun render(delta: Float) { - glideDispY = Terrarum.HEIGHT - 100f - Terrarum.fontGame.lineHeight - arrowObjGlideSize = arrowObjTex.width + 2f * Terrarum.WIDTH + // if loading is done, escape and set screen of the Game to the target + if (screenToLoad?.gameFullyLoaded ?: false) { + Terrarum.changeScreen(screenToLoad!!) + } + else { + glideDispY = Terrarum.HEIGHT - 100f - Terrarum.fontGame.lineHeight + arrowObjGlideSize = arrowObjTex.width + 2f * Terrarum.WIDTH - Gdx.gl.glClearColor(.157f, .157f, .157f, 0f) - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) - - textFbo.inAction(null, null) { - Gdx.gl.glClearColor(0f, 0f, 0f, 0f) + Gdx.gl.glClearColor(.157f, .157f, .157f, 0f) Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) - } - glideTimer += delta - if (glideTimer >= arrowObjGlideSize / arrowGlideSpeed) { - glideTimer -= arrowObjGlideSize / arrowGlideSpeed - } - arrowObjPos = glideTimer * arrowGlideSpeed + textFbo.inAction(null, null) { + Gdx.gl.glClearColor(0f, 0f, 0f, 0f) + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) + } + + glideTimer += delta + if (glideTimer >= arrowObjGlideSize / arrowGlideSpeed) { + glideTimer -= arrowObjGlideSize / arrowGlideSpeed + } + arrowObjPos = glideTimer * arrowGlideSpeed + // draw text to FBO + textFbo.inAction(camera, Terrarum.batch) { + Terrarum.batch.inUse { + blendNormal() + Terrarum.fontGame + it.color = Color.WHITE + Terrarum.fontGame.draw(it, Lang["MENU_IO_LOADING"], 0.33f, 0f) // x 0.5? I dunno but it breaks w/o it + + + blendMul() + // draw flipped + it.draw(textOverlayTex, + 0f, + Terrarum.fontGame.lineHeight, + textOverlayTex.width.toFloat(), + -Terrarum.fontGame.lineHeight + ) + } + } + - // draw text to FBO - textFbo.inAction(camera, Terrarum.batch) { Terrarum.batch.inUse { + initViewPort(Terrarum.WIDTH, Terrarum.HEIGHT) // dunno, no render without this + it.projectionMatrix = camera.combined blendNormal() - Terrarum.fontGame - it.color = Color.WHITE - Terrarum.fontGame.draw(it, Lang["MENU_IO_LOADING"], 0.5f, 0f) // x 0.5? I dunno but it breaks w/o it + // draw text FBO to screen + val textTex = textFbo.colorBufferTexture + textTex.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) - blendMul() - // draw flipped - it.draw(textOverlayTex, - 0f, - Terrarum.fontGame.lineHeight, - textOverlayTex.width.toFloat(), - -Terrarum.fontGame.lineHeight + // --> original text + if (genuineSonic) { + it.color = Color.WHITE + it.draw(textTex, textX, glideDispY - 2f) + } + + // --> ghost + it.color = getPulseEffCol() + + if (it.color.a != 0f) genuineSonic = true + + val drawWidth = getPulseEffWidthMul() * textTex.width + val drawHeight = getPulseEffWidthMul() * textTex.height + it.draw(textTex, + textX - (drawWidth - textTex.width) / 2f, + glideDispY - 2f - (drawHeight - textTex.height) / 2f, + drawWidth, + drawHeight ) + + + // draw coloured arrows + arrowColours.forEachIndexed { index, color -> + it.color = color + it.draw(arrowObjTex, arrowObjPos + arrowObjGlideOffsetX + arrowObjTex.width * index, glideDispY) + } + + + // log messages + it.color = Color.LIGHT_GRAY + for (i in 0 until messages.elemCount) { + Terrarum.fontGame.draw(it, + messages[i] ?: "", + 40f, + 80f + (messages.size - i - 1) * Terrarum.fontGame.lineHeight + ) + } } + } - - - Terrarum.batch.inUse { - initViewPort(Terrarum.WIDTH, Terrarum.HEIGHT) // dunno, no render without this - it.projectionMatrix = camera.combined - blendNormal() - - // draw text FBO to screen - val textTex = textFbo.colorBufferTexture - textTex.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) - - // --> original text - if (genuineSonic) { - it.color = Color.WHITE - it.draw(textTex, textX, glideDispY - 2f) - } - - // --> ghost - it.color = getPulseEffCol() - - if (it.color.a != 0f) genuineSonic = true - - val drawWidth = getPulseEffWidthMul() * textTex.width - val drawHeight = getPulseEffWidthMul() * textTex.height - it.draw(textTex, - textX - (drawWidth - textTex.width) / 2f, - glideDispY - 2f - (drawHeight - textTex.height) / 2f, - drawWidth, - drawHeight - ) - - - - // draw coloured arrows - arrowColours.forEachIndexed { index, color -> - it.color = color - it.draw(arrowObjTex, arrowObjPos + arrowObjGlideOffsetX + arrowObjTex.width * index, glideDispY) - } - - - // log messages - it.color = Color.LIGHT_GRAY - for (i in 0 until messages.elemCount) { - Terrarum.fontGame.draw(it, - messages[i] ?: "", - 40f, - 80f + (messages.size - i - 1) * Terrarum.fontGame.lineHeight - ) - } - } - } private fun getPulseEffCol(): Color { diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index 46cdace67..cdc0c7db9 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -355,8 +355,15 @@ object Terrarum : Game() { ingame!!.gameLoadInfoPayload = Ingame.NewWorldParameters(8192, 2048, HQRNG().nextLong()) ingame!!.gameLoadMode = Ingame.GameLoadMode.CREATE_NEW - //super.setScreen(ingame) + + LoadScreen.screenToLoad = ingame!! super.setScreen(LoadScreen) + + //super.setScreen(ingame) + } + + internal fun changeScreen(screen: Screen) { + super.setScreen(screen) } override fun render() { diff --git a/src/net/torvald/terrarum/worldgenerator/ThreadProcessNoiseLayers.kt b/src/net/torvald/terrarum/worldgenerator/ThreadProcessNoiseLayers.kt index 393d9724c..70850fdbd 100644 --- a/src/net/torvald/terrarum/worldgenerator/ThreadProcessNoiseLayers.kt +++ b/src/net/torvald/terrarum/worldgenerator/ThreadProcessNoiseLayers.kt @@ -1,5 +1,7 @@ package net.torvald.terrarum.worldgenerator +import net.torvald.terrarum.LoadScreen + /** * Created by minjaesong on 16-06-13. */ @@ -10,6 +12,8 @@ class ThreadProcessNoiseLayers(val startIndex: Int, val endIndex: Int, override fun run() { for (record in noiseRecords) { println("[mapgenerator] ${record.message}...") + LoadScreen.addMessage("${record.message}...") + for (y in startIndex..endIndex) { for (x in 0..WorldGenerator.WIDTH - 1) { // straight-line sampling diff --git a/src/net/torvald/terrarum/worldgenerator/WorldGenerator.kt b/src/net/torvald/terrarum/worldgenerator/WorldGenerator.kt index c8a18c083..dd1017e99 100644 --- a/src/net/torvald/terrarum/worldgenerator/WorldGenerator.kt +++ b/src/net/torvald/terrarum/worldgenerator/WorldGenerator.kt @@ -6,6 +6,7 @@ import net.torvald.terrarum.blockproperties.Block import com.jme3.math.FastMath import com.sudoplay.joise.Joise import com.sudoplay.joise.module.* +import net.torvald.terrarum.LoadScreen import net.torvald.terrarum.Terrarum import net.torvald.terrarum.concurrent.ThreadParallel import net.torvald.terrarum.gameactors.roundInt @@ -465,6 +466,7 @@ object WorldGenerator { // fill the area as Joise map println("[mapgenerator] Raising and eroding terrain...") + LoadScreen.addMessage("Raising and eroding terrain...") for (y in 0..(TERRAIN_UNDULATION - 1)) { for (x in 0..WIDTH) { // straight-line sampling @@ -576,6 +578,7 @@ object WorldGenerator { private fun fillMapByNoiseMap() { println("[mapgenerator] Shaping world...") + LoadScreen.addMessage("Shaping world...") // generate dirt-stone transition line // use catmull spline val dirtStoneLine = IntArray(WIDTH) @@ -750,7 +753,7 @@ object WorldGenerator { private fun processNoiseLayers(noiseRecords: Array) { if (Terrarum.MULTITHREAD) { // set up indices - for (i in 0..Terrarum.THREADS - 1) { + for (i in 0 until Terrarum.THREADS) { ThreadParallel.map( i, ThreadProcessNoiseLayers( @@ -773,6 +776,7 @@ object WorldGenerator { private fun generateFloatingIslands() { println("[mapgenerator] Placing floating islands...") + LoadScreen.addMessage("Placing floating islands...") val nIslandsMax = Math.round(world.width * 6f / 8192f) val nIslandsMin = Math.max(2, Math.round(world.width * 4f / 8192f)) @@ -804,7 +808,8 @@ object WorldGenerator { /* Flood */ private fun floodBottomLava() { - println("[mapgenerator] Flooding bottom lava...") + println("[mapgenerator] Flooding with lava...") + LoadScreen.addMessage("Flooding with lava...") for (i in HEIGHT * 14 / 15..HEIGHT - 1) { for (j in 0..WIDTH - 1) { if (world.terrainArray[i][j].toInt() == 0) { @@ -818,6 +823,7 @@ object WorldGenerator { private fun plantGrass() { println("[mapgenerator] Planting grass...") + LoadScreen.addMessage("Planting grass...") /* TODO composing dirt and stone * over certain level, use background dirt with stone 'peckles'