mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 20:31:51 +09:00
disposable UI; loading screen mockup (i heard like loading screen -- sonic 06)
This commit is contained in:
Binary file not shown.
BIN
assets/graphics/test_loading_text_tint.tga
LFS
Normal file
BIN
assets/graphics/test_loading_text_tint.tga
LFS
Normal file
Binary file not shown.
@@ -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
|
||||
|
||||
|
||||
@@ -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]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,4 +180,7 @@ class SpriteAnimation(val parentActor: ActorWithPhysics) {
|
||||
flipVertical = vertical
|
||||
}
|
||||
|
||||
fun dispose() {
|
||||
textureRegion.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -195,4 +195,8 @@ class UIItemInventoryElem(
|
||||
override fun scrolled(amount: Int): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
itemImage?.texture?.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -286,4 +286,7 @@ class BasicDebugInfoWindow : UICanvas {
|
||||
|
||||
override fun endClosing(delta: Float) {
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
}
|
||||
}
|
||||
@@ -212,4 +212,7 @@ class ConsoleWindow : UICanvas, KeyControlled {
|
||||
|
||||
override fun processInput(delta: Float) {
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -68,4 +68,7 @@ class Notification : UICanvas {
|
||||
handler!!.opacity = 0f
|
||||
handler!!.setAsOpen()
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,4 +31,7 @@ class NullUI : UICanvas {
|
||||
|
||||
override fun endClosing(delta: Float) {
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
}
|
||||
}
|
||||
@@ -131,4 +131,8 @@ class UIBasicNotifier(private val player: ActorHumanoid?) : UICanvas {
|
||||
|
||||
override fun endClosing(delta: Float) {
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
atlas.dispose()
|
||||
}
|
||||
}
|
||||
@@ -67,6 +67,8 @@ interface UICanvas {
|
||||
*/
|
||||
fun endClosing(delta: Float)
|
||||
|
||||
fun dispose()
|
||||
|
||||
companion object {
|
||||
const val OPENCLOSE_GENERIC = 0.2f
|
||||
|
||||
|
||||
@@ -287,4 +287,8 @@ class UIHandler(val UI: UICanvas,
|
||||
}
|
||||
return isVisible && !isOpening
|
||||
}
|
||||
|
||||
fun dispose() {
|
||||
UI.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,5 +355,8 @@ class UIInventory(
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
override fun dispose() {
|
||||
catButtons.dispose()
|
||||
items.forEach { it.dispose() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
}
|
||||
|
||||
@@ -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() }
|
||||
}
|
||||
}
|
||||
@@ -107,4 +107,7 @@ class UIItemTextButton(
|
||||
override fun scrolled(amount: Int): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,4 +194,8 @@ class UIItemTextButtonList(
|
||||
override fun scrolled(amount: Int): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
iconSpriteSheet?.dispose()
|
||||
}
|
||||
}
|
||||
@@ -118,4 +118,7 @@ class UIPieMenu : UICanvas {
|
||||
UICanvas.endClosingFade(handler)
|
||||
handler!!.scale = 1f
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
}
|
||||
}
|
||||
@@ -112,6 +112,9 @@ class UIQuickBar : UICanvas, MouseControlled {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
val finalOpacity = 0.8f
|
||||
|
||||
@@ -121,4 +121,9 @@ class UITierOneWatch(private val player: ActorHumanoid?) : UICanvas {
|
||||
|
||||
override fun endClosing(delta: Float) {
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
atlas.dispose()
|
||||
moonDial.dispose()
|
||||
}
|
||||
}
|
||||
@@ -123,6 +123,9 @@ class UIVitalMetre(
|
||||
override fun endClosing(delta: Float) {
|
||||
UICanvas.endClosingFade(handler)
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
}
|
||||
}
|
||||
|
||||
fun Float.abs() = FastMath.abs(this)
|
||||
|
||||
@@ -94,4 +94,7 @@ class UITextTerminal(val terminal: Terminal) : UICanvas, KeyControlled, MouseCon
|
||||
*/
|
||||
override fun endClosing(delta: Float) {
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Reference in New Issue
Block a user