disposable UI; loading screen mockup (i heard like loading screen -- sonic 06)

This commit is contained in:
minjaesong
2017-07-13 17:53:40 +09:00
parent fb899dae2d
commit 2a5cb3ee38
33 changed files with 253 additions and 33 deletions

Binary file not shown.

View File

@@ -15,6 +15,8 @@ class CircularArray<T>(val size: Int) {
var tail: Int = 0
var head: Int = 0
val lastIndex = size - 1
val elemCount: Int
get() = if (tail >= head) tail - head else size

View File

@@ -1,16 +1,20 @@
package net.torvald.dataclass
import java.util.*
import java.util.function.Consumer
/**
* Simple ArrayList wrapper that acts as history keeper. You can append any data but cannot delete.
*
* Created by minjaesong on 16-07-13.
*/
class HistoryArray<T>(val historyMax: Int) {
class HistoryArray<T>(val size: Int) {
val history = ArrayList<T?>(Math.min(historyMax, 256)) // 256: arbitrary set upper bound
val history = ArrayList<T?>(Math.min(size, 256)) // 256: arbitrary set upper bound
val lastIndex = size - 1
val elemCount: Int
get() = history.size
fun add(value: T) {
if (history.size == 0) {
@@ -20,11 +24,11 @@ class HistoryArray<T>(val historyMax: Int) {
// push existing values to an index
else {
for (i in history.size - 1 downTo 0) {
// if history.size is smaller than historyMax, make room by appending
if (i == history.size - 1 && i < historyMax - 1)
// if history.size is smaller than 'size', make room by appending
if (i == history.size - 1 && i < size - 1)
history.add(history[i])
// actually move if we have some room
else if (i < historyMax - 1)
else if (i < size - 1)
history[i + 1] = history[i]
}
}

View File

@@ -180,4 +180,7 @@ class SpriteAnimation(val parentActor: ActorWithPhysics) {
flipVertical = vertical
}
fun dispose() {
textureRegion.dispose()
}
}

View File

@@ -1530,6 +1530,14 @@ class Ingame(val batch: SpriteBatch) : Screen {
worldBlendFrameBuffer.dispose()
lightmapFboA.dispose()
lightmapFboB.dispose()
actorsRenderBehind.forEach { it.dispose() }
actorsRenderMiddle.forEach { it.dispose() }
actorsRenderMidTop.forEach { it.dispose() }
actorsRenderFront.forEach { it.dispose() }
uiAliases.forEach { it.dispose() }
uiAlasesPausing.forEach { it.dispose() }
}

View File

@@ -3,10 +3,13 @@ package net.torvald.terrarum
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.Screen
import com.badlogic.gdx.ScreenAdapter
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.GL20
import com.badlogic.gdx.graphics.OrthographicCamera
import com.badlogic.gdx.graphics.*
import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.badlogic.gdx.graphics.glutils.FrameBuffer
import com.jme3.math.FastMath
import net.torvald.dataclass.CircularArray
import net.torvald.dataclass.HistoryArray
import net.torvald.terrarum.gameactors.floor
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
@@ -21,7 +24,7 @@ object LoadScreen : ScreenAdapter() {
private val messages = HistoryArray<String>(20)
fun setMessage(msg: String) {
fun addMessage(msg: String) {
messages.add(msg)
}
@@ -30,17 +33,21 @@ object LoadScreen : ScreenAdapter() {
private var arrowObjPos = 0f // 0 means at starting position, regardless of screen position
private var arrowObjGlideOffsetX = 0f
private var arrowObjGlideSize = 0f
private var arrowGlideSpeed = Terrarum.WIDTH * 1.2f // pixels per sec
private lateinit var arrowObjTex: TextureRegionPack
private val arrowGlideSpeed: Float; get() = Terrarum.WIDTH * 1.5f // pixels per sec
private lateinit var arrowObjTex: Texture
private var glideTimer = 0f
private var glideDispY = 0f
private var arrowColours = arrayOf(
Color(0xff847fff.toInt()),
Color(0xffc87fff.toInt()),
Color(0xbffff2ff.toInt()),
Color(0x7fcaffff)
Color(0xff4c4cff.toInt()),
Color(0xffd24cff.toInt()),
Color(0x4cb5ffff.toInt())
)
private lateinit var textOverlayTex: Texture
private lateinit var textFbo: FrameBuffer
private val ghostMaxZoom = 1.3f
private val ghostAlphaMax = 1f
var camera = OrthographicCamera(Terrarum.WIDTH.toFloat(), Terrarum.HEIGHT.toFloat())
@@ -63,20 +70,39 @@ object LoadScreen : ScreenAdapter() {
override fun show() {
initViewPort(Terrarum.WIDTH, Terrarum.HEIGHT)
arrowObjTex = TextureRegionPack(Gdx.files.internal("assets/graphics/test_loading_arrow_atlas.tga"), 22, 17)
arrowObjGlideOffsetX = -arrowObjTex.texture.width.toFloat()
arrowObjGlideSize = arrowObjTex.texture.width + 1.5f * Terrarum.WIDTH
glideDispY = Terrarum.HEIGHT - 140f
textFbo = FrameBuffer(
Pixmap.Format.RGBA4444,
Terrarum.fontGame.getWidth(Lang["MENU_IO_LOADING"]),
Terrarum.fontGame.lineHeight.toInt(),
true
)
arrowObjTex = Texture(Gdx.files.internal("assets/graphics/test_loading_arrow_atlas.tga"))
arrowObjGlideOffsetX = -arrowObjTex.width.toFloat()
textOverlayTex = Texture(Gdx.files.internal("assets/graphics/test_loading_text_tint.tga"))
addMessage("**** This is a test ****")
addMessage("Segmentation fault")
}
private val textColour = Color(0xeeeeeeff.toInt())
val textX: Float; get() = (Terrarum.WIDTH * 0.75f).floor()
override fun render(delta: Float) {
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.glClear(GL20.GL_COLOR_BUFFER_BIT)
}
glideTimer += delta
if (glideTimer >= arrowObjGlideSize / arrowGlideSpeed) {
@@ -85,25 +111,105 @@ object LoadScreen : ScreenAdapter() {
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.5f, 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
)
}
}
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.Nearest, Texture.TextureFilter.Nearest)
// --> original text
it.color = Color.WHITE
it.draw(textTex, textX, glideDispY - 2f)
// --> ghost
it.color = getPulseEffCol()
val drawWidth = getPulseEffWidthMul() * textTex.width
it.draw(textTex,
textX - (drawWidth - textTex.width) / 2f,
glideDispY - 2f,
drawWidth,
textTex.height.toFloat()
)
it.color = textColour
val textWidth = Terrarum.fontGame.getWidth(Lang["MENU_IO_LOADING"])
Terrarum.fontGame.draw(it, Lang["MENU_IO_LOADING"], (Terrarum.WIDTH - 2.5f * textWidth).round(), glideDispY - 2f)
// draw coloured arrows
arrowColours.forEachIndexed { index, color ->
it.color = color
it.draw(arrowObjTex.get(index, 0), arrowObjPos + arrowObjGlideOffsetX + 22 * index, glideDispY)
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 {
if (arrowObjPos + arrowObjTex.width * 3f < textX)
return Color(1f, 1f, 1f, 0f)
else {
// ref point: top-left of arrow drawn to the screen, 0 being start of the RAIL
val scaleStart = textX - arrowObjTex.width * 3f
val scaleEnd = arrowObjGlideSize - arrowObjTex.width * 3f
val scale = (arrowObjPos - scaleStart) / (scaleEnd - scaleStart)
val alpha = FastMath.interpolateLinear(scale, ghostAlphaMax, 0f)
return Color(1f, 1f, 1f, alpha)
}
}
private fun getPulseEffWidthMul(): Float {
if (arrowObjPos + arrowObjTex.width * 3f < textX)
return 1f
else {
// ref point: top-left of arrow drawn to the screen, 0 being start of the RAIL
val scaleStart = textX - arrowObjTex.width * 3f
val scaleEnd = arrowObjGlideSize - arrowObjTex.width * 3f
val scale = (arrowObjPos - scaleStart) / (scaleEnd - scaleStart)
return FastMath.interpolateLinear(scale, 1f, ghostMaxZoom)
}
}
override fun dispose() {
arrowObjTex.dispose()
textFbo.dispose()
textOverlayTex.dispose()
}
override fun hide() {

View File

@@ -19,7 +19,11 @@ import net.torvald.random.HQRNG
import net.torvald.terrarum.Terrarum.RENDER_FPS
import net.torvald.terrarum.gamecontroller.GameController
import net.torvald.terrarum.imagefont.TinyAlphNum
import net.torvald.terrarum.imagefont.Watch7SegMain
import net.torvald.terrarum.imagefont.WatchDotAlph
import net.torvald.terrarum.itemproperties.ItemCodex
import net.torvald.terrarum.ui.ItemSlotImageBuilder
import net.torvald.terrarum.ui.MessageWindow
import net.torvald.terrarum.utils.JsonFetcher
import net.torvald.terrarum.utils.JsonWriter
import net.torvald.terrarumsansbitmap.gdx.GameFontBase
@@ -372,6 +376,15 @@ object Terrarum : Game() {
super.screen.dispose()
fontGame.dispose()
fontSmallNumbers.dispose()
ItemSlotImageBuilder.dispose()
WatchDotAlph.dispose()
Watch7SegMain.dispose()
WatchDotAlph.dispose()
MessageWindow.SEGMENT_BLACK.dispose()
MessageWindow.SEGMENT_WHITE.dispose()
//dispose any other resources used in this level
}

View File

@@ -195,4 +195,8 @@ class UIItemInventoryElem(
override fun scrolled(amount: Int): Boolean {
return false
}
override fun dispose() {
itemImage?.texture?.dispose()
}
}

View File

@@ -1,7 +1,6 @@
package net.torvald.terrarum.gameactors
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.glutils.ShapeRenderer
/**
* Actor with visible body
@@ -13,4 +12,6 @@ abstract class ActorWithBody(renderOrder: RenderOrder) : Actor(renderOrder) {
abstract fun drawBody(batch: SpriteBatch)
abstract fun drawGlow(batch: SpriteBatch)
open var tooltipText: String? = null // null: display nothing
abstract fun dispose()
}

View File

@@ -1451,6 +1451,11 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
this + 2 * Math.PI
else
this
override fun dispose() {
sprite?.dispose()
spriteGlow?.dispose()
}
}
inline fun Int.sqr(): Int = this * this

View File

@@ -40,4 +40,8 @@ object Watch7SegMain : BitmapFont() {
override fun getLineHeight() = H.toFloat()
override fun getCapHeight() = getLineHeight()
override fun getXHeight() = getLineHeight()
override fun dispose() {
fontSheet.dispose()
}
}

View File

@@ -39,4 +39,8 @@ object WatchDotAlph : BitmapFont() {
override fun getLineHeight() = H.toFloat()
override fun getCapHeight() = getLineHeight()
override fun getXHeight() = getLineHeight()
override fun dispose() {
fontSheet.dispose()
}
}

View File

@@ -286,4 +286,7 @@ class BasicDebugInfoWindow : UICanvas {
override fun endClosing(delta: Float) {
}
override fun dispose() {
}
}

View File

@@ -212,4 +212,7 @@ class ConsoleWindow : UICanvas, KeyControlled {
override fun processInput(delta: Float) {
}
override fun dispose() {
}
}

View File

@@ -99,4 +99,9 @@ object ItemSlotImageBuilder {
private data class ImageDesc(val color: Color, val number: Int, val isLarge: Boolean)
fun dispose() {
slotImage.dispose()
slotLarge.dispose()
}
}

View File

@@ -66,12 +66,16 @@ class MessageWindow(override var width: Int, isBlackVariant: Boolean) : UICanvas
override fun endClosing(delta: Float) {
}
override fun dispose() {
}
companion object {
// private int messagesShowingIndex = 0;
val MESSAGES_DISPLAY = 2
val OPEN_CLOSE_TIME = 0.16f
// will be disposed by Terrarum (application main instance)
val SEGMENT_BLACK = TextureRegionPack("assets/graphics/gui/message_black.tga", 8, 56)
val SEGMENT_WHITE = TextureRegionPack("assets/graphics/gui/message_white.tga", 8, 56)
}

View File

@@ -68,4 +68,7 @@ class Notification : UICanvas {
handler!!.opacity = 0f
handler!!.setAsOpen()
}
override fun dispose() {
}
}

View File

@@ -31,4 +31,7 @@ class NullUI : UICanvas {
override fun endClosing(delta: Float) {
}
override fun dispose() {
}
}

View File

@@ -131,4 +131,8 @@ class UIBasicNotifier(private val player: ActorHumanoid?) : UICanvas {
override fun endClosing(delta: Float) {
}
override fun dispose() {
atlas.dispose()
}
}

View File

@@ -67,6 +67,8 @@ interface UICanvas {
*/
fun endClosing(delta: Float)
fun dispose()
companion object {
const val OPENCLOSE_GENERIC = 0.2f

View File

@@ -287,4 +287,8 @@ class UIHandler(val UI: UICanvas,
}
return isVisible && !isOpening
}
fun dispose() {
UI.dispose()
}
}

View File

@@ -355,5 +355,8 @@ class UIInventory(
return false
}
override fun dispose() {
catButtons.dispose()
items.forEach { it.dispose() }
}
}

View File

@@ -41,5 +41,6 @@ abstract class UIItem(var parentUI: UICanvas) { // do not replace parentUI to UI
abstract fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean
abstract fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean
abstract fun scrolled(amount: Int): Boolean
abstract fun dispose()
}

View File

@@ -69,4 +69,8 @@ class UIItemImageGallery(
override fun scrolled(amount: Int): Boolean {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun dispose() {
imageList.forEach { it.dispose() }
}
}

View File

@@ -107,4 +107,7 @@ class UIItemTextButton(
override fun scrolled(amount: Int): Boolean {
return false
}
override fun dispose() {
}
}

View File

@@ -194,4 +194,8 @@ class UIItemTextButtonList(
override fun scrolled(amount: Int): Boolean {
return false
}
override fun dispose() {
iconSpriteSheet?.dispose()
}
}

View File

@@ -118,4 +118,7 @@ class UIPieMenu : UICanvas {
UICanvas.endClosingFade(handler)
handler!!.scale = 1f
}
override fun dispose() {
}
}

View File

@@ -112,6 +112,9 @@ class UIQuickBar : UICanvas, MouseControlled {
return true
}
override fun dispose() {
}
companion object {
val finalOpacity = 0.8f

View File

@@ -121,4 +121,9 @@ class UITierOneWatch(private val player: ActorHumanoid?) : UICanvas {
override fun endClosing(delta: Float) {
}
override fun dispose() {
atlas.dispose()
moonDial.dispose()
}
}

View File

@@ -123,6 +123,9 @@ class UIVitalMetre(
override fun endClosing(delta: Float) {
UICanvas.endClosingFade(handler)
}
override fun dispose() {
}
}
fun Float.abs() = FastMath.abs(this)

View File

@@ -94,4 +94,7 @@ class UITextTerminal(val terminal: Terminal) : UICanvas, KeyControlled, MouseCon
*/
override fun endClosing(delta: Float) {
}
override fun dispose() {
}
}

Binary file not shown.