WIP collision solver, colour-codes in game fonts
Former-commit-id: 0bb85999176d89956398bbcc24e1b33cacd3e87c Former-commit-id: 0ef0c1ac9b88f8fe42a7439fee69a8d4792be96a
1
res/graphics/fonts/.gitattributes
vendored
@@ -1 +0,0 @@
|
||||
*.{psd,tga,ogg} filter=lfs diff=lfs merge=lfs -text
|
||||
|
Before Width: | Height: | Size: 160 B After Width: | Height: | Size: 143 B |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 1.8 KiB |
BIN
res/graphics/fonts/alphanumeric_small.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 154 B After Width: | Height: | Size: 149 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 986 B |
@@ -1,8 +1,5 @@
|
||||
"STRING_ID";"IETF language tag(s) without dash";"enUS";"frFR";"esES";"deDE";"itIT";"ptBR";"ptPT";"ruRU";"elGR";"trTR";"daDK";"noNB";"svSE";"nlNL";"plPL";"fiFI";"jaJP";"zhCN";"zhTW";"koKR";"csCZ";"huHU";"roRO";"thTH";"bgBG";"heIL";"jakanaJP";"isIC"
|
||||
|
||||
"DEV_MEMORY_SHORT_CAP";;"MEM";"MEM";;;;;;;;;;;;;;;"メモリー";;;"메모리";;;;;;;"メモリー";"MIN"
|
||||
"DEV_MEMORY_A_OF_B";;"%1$sM out of %2$sM";"%1$sM sur %2$sM";;;;;;;;;;;;;;;"%2$sM中%1$sM";;;"%2$sM 중 %1$sM";;;;;;;"%2$sM ちゅう %1$sM";"%1$sM af %2$sM"
|
||||
|
||||
"DEV_COLOUR_LEGEND_GREEN";;" GREEN";" VERT";;;;;;;;;;;;;;;"緑";;;"녹";;;;;;;" みどり";"grænn"
|
||||
"DEV_COLOUR_LEGEND_BLUE";;" BLUE";" BLEU";;;;;;;;;;;;;;;"青";;;"청";;;;;;;" あお";"blár"
|
||||
"DEV_COLOUR_LEGEND_ORANGE";;"ORANGE";"ORANGE";;;;;;;;;;;;;;;"黄";;;"황";;;;;;;"オレンジ";"rauðugulur"
|
||||
|
||||
|
@@ -59,16 +59,16 @@ class Col216 : LimitedColours {
|
||||
|
||||
private fun assertRaw(i: Int) {
|
||||
if (i >= COLOUR_RANGE_SIZE || i < 0) {
|
||||
println("i: " + i.toString())
|
||||
System.err.println("Illegal colour input: $i")
|
||||
throw IllegalArgumentException()
|
||||
}
|
||||
}
|
||||
|
||||
private fun assertRGB(r: Int, g: Int, b: Int) {
|
||||
if (r !in 0..MAX_STEP || g !in 0..MAX_STEP || b !in 0..MAX_STEP) {
|
||||
println("r: " + r.toString())
|
||||
println("g: " + g.toString())
|
||||
println("b: " + b.toString())
|
||||
System.err.println("Illegal colour input for channel r: $r")
|
||||
System.err.println("Illegal colour input for channel g: $g")
|
||||
System.err.println("Illegal colour input for channel b: $b")
|
||||
throw IllegalArgumentException()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,17 +111,17 @@ class Col4096 : LimitedColours {
|
||||
|
||||
private fun assertRaw(i: Int) {
|
||||
if (i > 0xFFFF || i < 0) {
|
||||
println("i: " + i.toString())
|
||||
System.err.println("Illegal colour input: $i")
|
||||
throw IllegalArgumentException()
|
||||
}
|
||||
}
|
||||
|
||||
private fun assertARGB(a: Int, r: Int, g: Int, b: Int) {
|
||||
if (a !in 0..16 || r !in 0..16 || g !in 0..16 || b !in 0..16) {
|
||||
println("a: " + a.toString())
|
||||
println("r: " + r.toString())
|
||||
println("g: " + g.toString())
|
||||
println("b: " + b.toString())
|
||||
System.err.println("Illegal colour input for channel a: $a")
|
||||
System.err.println("Illegal colour input for channel r: $r")
|
||||
System.err.println("Illegal colour input for channel g: $g")
|
||||
System.err.println("Illegal colour input for channel b: $b")
|
||||
throw IllegalArgumentException()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ constructor() : Font {
|
||||
|
||||
private fun isHangul(c: Char) = c.toInt() >= 0xAC00 && c.toInt() < 0xD7A4
|
||||
|
||||
private fun isAscii(c: Char) = c.toInt() > 0 && c.toInt() <= 0xFF
|
||||
private fun isAscii(c: Char) = c.toInt() > 0x20 && c.toInt() <= 0xFF
|
||||
|
||||
private fun isRunic(c: Char) = runicList.contains(c)
|
||||
|
||||
@@ -138,7 +138,9 @@ constructor() : Font {
|
||||
|
||||
}
|
||||
|
||||
if (c == SHEET_ASCII_EF || c == SHEET_EXTA_EF || c == SHEET_CYRILIC_EF)
|
||||
if (c == SHEET_COLOURCODE)
|
||||
len += 0
|
||||
else if (c == SHEET_ASCII_EF || c == SHEET_EXTA_EF || c == SHEET_CYRILIC_EF)
|
||||
len += W_LATIN_NARROW
|
||||
else if (c == SHEET_KANA || c == SHEET_HANGUL || c == SHEET_CJK_PUNCT)
|
||||
len += W_CJK
|
||||
@@ -163,12 +165,19 @@ constructor() : Font {
|
||||
GL11.glColorMask(true, true, true, true)
|
||||
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA)
|
||||
|
||||
var thisCol = color
|
||||
|
||||
// hangul fonts first
|
||||
//hangulSheet.startUse() // disabling texture binding to make the font coloured
|
||||
// JOHAB
|
||||
for (i in 0..s.length - 1) {
|
||||
val ch = s[i]
|
||||
|
||||
if (ch.isColourCode()) {
|
||||
thisCol = colourKey[ch]!!
|
||||
continue
|
||||
}
|
||||
|
||||
if (isHangul(ch)) {
|
||||
val hIndex = ch.toInt() - 0xAC00
|
||||
|
||||
@@ -204,17 +213,17 @@ constructor() : Font {
|
||||
hangulSheet.getSubImage(indexCho, choRow).draw(
|
||||
Math.round(x + getWidthSubstr(s, i + 1) - glyphW).toFloat(),
|
||||
Math.round(((H - H_HANGUL) / 2).toFloat() + y + 1f).toFloat(),
|
||||
color
|
||||
thisCol
|
||||
)
|
||||
hangulSheet.getSubImage(indexJung, jungRow).draw(
|
||||
Math.round(x + getWidthSubstr(s, i + 1) - glyphW).toFloat(),
|
||||
Math.round(((H - H_HANGUL) / 2).toFloat() + y + 1f).toFloat(),
|
||||
color
|
||||
thisCol
|
||||
)
|
||||
hangulSheet.getSubImage(indexJong, jongRow).draw(
|
||||
Math.round(x + getWidthSubstr(s, i + 1) - glyphW).toFloat(),
|
||||
Math.round(((H - H_HANGUL) / 2).toFloat() + y + 1f).toFloat(),
|
||||
color
|
||||
thisCol
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -246,6 +255,11 @@ constructor() : Font {
|
||||
for (i in 0..s.length - 1) {
|
||||
val ch = s[i]
|
||||
|
||||
if (ch.isColourCode()) {
|
||||
thisCol = colourKey[ch]!!
|
||||
continue
|
||||
}
|
||||
|
||||
if (isWenQuanYi1(ch)) {
|
||||
val glyphW = getWidth("" + ch)
|
||||
/*wenQuanYi_1.renderInUse(
|
||||
@@ -257,7 +271,7 @@ constructor() : Font {
|
||||
wenQuanYi_1.getSubImage(wenQuanYiIndexX(ch), wenQuanYi1IndexY(ch)).draw(
|
||||
Math.round(x + getWidthSubstr(s, i + 1) - glyphW).toFloat(),
|
||||
Math.round((H - H_UNIHAN) / 2 + y).toFloat(),
|
||||
color
|
||||
thisCol
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -269,6 +283,11 @@ constructor() : Font {
|
||||
for (i in 0..s.length - 1) {
|
||||
val ch = s[i]
|
||||
|
||||
if (ch.isColourCode()) {
|
||||
thisCol = colourKey[ch]!!
|
||||
continue
|
||||
}
|
||||
|
||||
if (isWenQuanYi2(ch)) {
|
||||
val glyphW = getWidth("" + ch)
|
||||
/*wenQuanYi_2.renderInUse(
|
||||
@@ -280,7 +299,7 @@ constructor() : Font {
|
||||
wenQuanYi_2.getSubImage(wenQuanYiIndexX(ch), wenQuanYi2IndexY(ch)).draw(
|
||||
Math.round(x + getWidthSubstr(s, i + 1) - glyphW).toFloat(),
|
||||
Math.round((H - H_UNIHAN) / 2 + y).toFloat(),
|
||||
color
|
||||
thisCol
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -292,6 +311,11 @@ constructor() : Font {
|
||||
for (i in 0..s.length - 1) {
|
||||
val ch = s[i]
|
||||
|
||||
if (ch.isColourCode()) {
|
||||
thisCol = colourKey[ch]!!
|
||||
continue
|
||||
}
|
||||
|
||||
if (!isHangul(ch) && !isUniHan(ch)) {
|
||||
|
||||
// if not init, endUse first
|
||||
@@ -369,7 +393,7 @@ constructor() : Font {
|
||||
else if (prevInstance == SHEET_FW_UNI) (H - H_HANGUL) / 2
|
||||
else 0).toFloat(),
|
||||
|
||||
color
|
||||
thisCol
|
||||
)
|
||||
}
|
||||
catch (e: ArrayIndexOutOfBoundsException) {
|
||||
@@ -413,6 +437,8 @@ constructor() : Font {
|
||||
return SHEET_CJK_PUNCT
|
||||
else if (isFullwidthUni(c))
|
||||
return SHEET_FW_UNI
|
||||
else if (c.isColourCode())
|
||||
return SHEET_COLOURCODE
|
||||
else
|
||||
return SHEET_ASCII_EM// fixed width punctuations
|
||||
// fixed width
|
||||
@@ -464,6 +490,8 @@ constructor() : Font {
|
||||
Terrarum.appgc.graphics.setDrawMode(Graphics.MODE_NORMAL)
|
||||
}
|
||||
|
||||
fun Char.isColourCode() = colourKey.containsKey(this)
|
||||
|
||||
companion object {
|
||||
|
||||
lateinit internal var hangulSheet: SpriteSheet
|
||||
@@ -510,6 +538,8 @@ constructor() : Font {
|
||||
internal val SHEET_WENQUANYI_1 = 13
|
||||
internal val SHEET_WENQUANYI_2 = 14
|
||||
|
||||
internal val SHEET_COLOURCODE = 255
|
||||
|
||||
lateinit internal var sheetKey: Array<SpriteSheet>
|
||||
internal val asciiEFList = arrayOf(' ', '!', '"', '\'', '(', ')', ',', '.', ':', ';', 'I', '[', ']', '`', 'f', 'i', 'j', 'l', 't', '{', '|', '}', 0xA1.toChar(), 'Ì', 'Í', 'Î', 'Ï', 'ì', 'í', 'î', 'ï', '·')
|
||||
|
||||
@@ -554,5 +584,30 @@ constructor() : Font {
|
||||
internal val runicList = arrayOf('ᚠ', 'ᚢ', 'ᚦ', 'ᚬ', 'ᚱ', 'ᚴ', 'ᚼ', 'ᚾ', 'ᛁ', 'ᛅ', 'ᛋ', 'ᛏ', 'ᛒ', 'ᛘ', 'ᛚ', 'ᛦ', 'ᛂ', '᛬', '᛫', '᛭', 'ᛮ', 'ᛯ', 'ᛰ')
|
||||
|
||||
internal var interchar = 0
|
||||
|
||||
val colourKey = hashMapOf(
|
||||
Pair(0x11.toChar(), Color(0xFFFFFF)), //w
|
||||
Pair(0x12.toChar(), Color(0xFF8080)), //r
|
||||
Pair(0x13.toChar(), Color(0x80FF80)), //g
|
||||
Pair(0x14.toChar(), Color(0x8080FF)), //b
|
||||
Pair(0x15.toChar(), Color(0xFFE080)), //y
|
||||
Pair(0x16.toChar(), Color(0x808080)) //k
|
||||
)
|
||||
val colToCode = hashMapOf(
|
||||
Pair("w", 0x11.toChar()),
|
||||
Pair("r", 0x12.toChar()),
|
||||
Pair("g", 0x13.toChar()),
|
||||
Pair("b", 0x14.toChar()),
|
||||
Pair("y", 0x15.toChar()),
|
||||
Pair("k", 0x16.toChar())
|
||||
)
|
||||
val codeToCol = hashMapOf(
|
||||
Pair("w", colourKey[0x11.toChar()]),
|
||||
Pair("r", colourKey[0x12.toChar()]),
|
||||
Pair("g", colourKey[0x13.toChar()]),
|
||||
Pair("b", colourKey[0x14.toChar()]),
|
||||
Pair("y", colourKey[0x15.toChar()]),
|
||||
Pair("k", colourKey[0x16.toChar()])
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ constructor() : GameFontBase() {
|
||||
GameFontBase.wenQuanYi_2 = SpriteSheet(
|
||||
"./res/graphics/fonts/wenquanyi_11pt_part2.png", 16, 18, 2)
|
||||
|
||||
val shk = arrayOf<SpriteSheet>(
|
||||
val shk = arrayOf(
|
||||
GameFontBase.asciiSheet,
|
||||
GameFontBase.asciiSheetEF,
|
||||
GameFontBase.hangulSheet,
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
package net.torvald.imagefont
|
||||
|
||||
import org.newdawn.slick.Color
|
||||
import org.newdawn.slick.Font
|
||||
import org.newdawn.slick.SpriteSheet
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 16-04-15.
|
||||
*/
|
||||
class SmallNumbers : Font {
|
||||
|
||||
internal val fontSheet: SpriteSheet
|
||||
|
||||
internal val W = 8
|
||||
internal val H = 8
|
||||
|
||||
private val chars = arrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-')
|
||||
|
||||
init {
|
||||
fontSheet = SpriteSheet("./res/graphics/fonts/numeric_small.png", W, H)
|
||||
}
|
||||
|
||||
override fun getHeight(str: String): Int = H
|
||||
|
||||
override fun getWidth(str: String): Int = str.length * W
|
||||
|
||||
override fun getLineHeight(): Int = H
|
||||
|
||||
override fun drawString(x: Float, y: Float, text: String) = drawString(x, y, text, Color.white)
|
||||
|
||||
override fun drawString(x: Float, y: Float, text: String, col: Color) {
|
||||
for (i in 0..text.length - 1) {
|
||||
val index = charToSpriteNum(text.codePointAt(i))
|
||||
if (index != null) {
|
||||
fontSheet.getSubImage(index, 0).draw(
|
||||
x + i * W, y, col
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun drawString(x: Float, y: Float, text: String, col: Color, startIndex: Int, endIndex: Int) {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
private fun charToSpriteNum(ch: Int): Int? =
|
||||
if (ch in '0'.toInt()..'9'.toInt()) ch - '0'.toInt()
|
||||
else if (ch == '-'.toInt()) 10
|
||||
else null
|
||||
}
|
||||
78
src/net/torvald/imagefont/TinyAlphNum.kt
Normal file
@@ -0,0 +1,78 @@
|
||||
package net.torvald.imagefont
|
||||
|
||||
import org.newdawn.slick.Color
|
||||
import org.newdawn.slick.Font
|
||||
import org.newdawn.slick.SpriteSheet
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 16-04-15.
|
||||
*/
|
||||
class TinyAlphNum : Font {
|
||||
|
||||
internal val fontSheet: SpriteSheet
|
||||
|
||||
internal val W = 8
|
||||
internal val H = 8
|
||||
|
||||
private val chars = arrayOf(
|
||||
'0','1','2','3','4','5','6','7',
|
||||
'8','9','[','#','@',':','>','?',
|
||||
' ','A','B','C','D','E','F','G',
|
||||
'H','I','&','.',']','(','<','\\',
|
||||
'^','J','K','L','M','N','O','P',
|
||||
'Q','R','-','¤','*',')',';','\'',
|
||||
'+','/','S','T','U','V','W','X',
|
||||
'Y','Z','_',',','%','=','"','!'
|
||||
)
|
||||
private val mappingTable = HashMap<Int, Int>()
|
||||
|
||||
init {
|
||||
fontSheet = SpriteSheet("./res/graphics/fonts/alphanumeric_small.png", W, H)
|
||||
chars.forEachIndexed { i, c -> mappingTable[c.toInt()] = i }
|
||||
}
|
||||
|
||||
override fun getHeight(str: String): Int = H
|
||||
|
||||
override fun getWidth(str: String): Int {
|
||||
var ret = 0
|
||||
for (i in 0..str.length - 1) {
|
||||
val c = str.codePointAt(i).toChar()
|
||||
if (!c.isColourCode())
|
||||
ret += W
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
override fun getLineHeight(): Int = H
|
||||
|
||||
override fun drawString(x: Float, y: Float, text: String) = drawString(x, y, text, Color.white)
|
||||
|
||||
override fun drawString(x: Float, y: Float, text: String, col: Color) {
|
||||
var thisCol = col
|
||||
var textPosOffset = 0
|
||||
for (i in 0..text.length - 1) {
|
||||
val index = charToSpriteNum(text.toUpperCase().codePointAt(i))
|
||||
val ch = text[i]
|
||||
|
||||
if (ch.isColourCode()) {
|
||||
thisCol = GameFontBase.colourKey[ch]!!
|
||||
continue
|
||||
}
|
||||
if (index != null) {
|
||||
fontSheet.getSubImage(index % 8, index / 8).draw(
|
||||
x + textPosOffset, y, thisCol
|
||||
)
|
||||
}
|
||||
textPosOffset += W
|
||||
}
|
||||
}
|
||||
|
||||
override fun drawString(x: Float, y: Float, text: String, col: Color, startIndex: Int, endIndex: Int) {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
private fun charToSpriteNum(ch: Int): Int? = mappingTable[ch]
|
||||
|
||||
fun Char.isColourCode() = GameFontBase.colourKey.containsKey(this)
|
||||
}
|
||||
@@ -34,11 +34,17 @@ import java.util.*
|
||||
*/
|
||||
class Game @Throws(SlickException::class)
|
||||
constructor() : BasicGameState() {
|
||||
private val ACTOR_UPDATE_RANGE = 4096
|
||||
|
||||
internal var game_mode = 0
|
||||
|
||||
lateinit var map: GameMap
|
||||
|
||||
val actorContainer = LinkedList<Actor>()
|
||||
/**
|
||||
* Linked list of Actors that is sorted by Actors' referenceID
|
||||
*/
|
||||
val actorContainer = ArrayList<Actor>(128)
|
||||
val actorcontainerInactive = ArrayList<Actor>(128)
|
||||
val uiContainer = LinkedList<UIHandler>()
|
||||
|
||||
lateinit var consoleHandler: UIHandler
|
||||
@@ -128,7 +134,6 @@ constructor() : BasicGameState() {
|
||||
update_delta = delta
|
||||
setAppTitle()
|
||||
|
||||
// GL at after_sunrise-noon_before_sunset
|
||||
map.updateWorldTime(delta)
|
||||
map.globalLight = globalLightByTime
|
||||
|
||||
@@ -139,12 +144,19 @@ constructor() : BasicGameState() {
|
||||
MapDrawer.update(gc, delta)
|
||||
MapCamera.update(gc, delta)
|
||||
|
||||
actorContainer.forEach { actor -> actor.update(gc, delta) }
|
||||
actorContainer.forEach { actor ->
|
||||
if (actor is Visible) {
|
||||
actorContainer.forEach { actor -> // update actors
|
||||
if (actor !is Visible
|
||||
|| actor is Visible && distToActorSqr(actor, player) < ACTOR_UPDATE_RANGE.sqr())
|
||||
// update if the does not have specific position. (visible)
|
||||
// if the actor has position (visible), update only if it is within the range
|
||||
actor.update(gc, delta)
|
||||
}
|
||||
actorContainer.forEach { actor -> // update sprite(s)
|
||||
if (actor is Visible &&
|
||||
distToActorSqr(actor, player) <= (Terrarum.WIDTH.plus(actor.hitbox.width.div(2)).sqr() +
|
||||
Terrarum.HEIGHT.plus(actor.hitbox.height.div(2)).sqr())
|
||||
) { // if visible and within screen
|
||||
actor.updateBodySprite(gc, delta)
|
||||
}
|
||||
if (actor is Glowing) {
|
||||
actor.updateGlowSprite(gc, delta)
|
||||
}
|
||||
}
|
||||
@@ -186,7 +198,14 @@ constructor() : BasicGameState() {
|
||||
MapCamera.renderBehind(gc, g)
|
||||
|
||||
// draw actors
|
||||
actorContainer.forEach { actor -> if (actor is Visible) actor.drawBody(gc, g) }
|
||||
actorContainer.forEach { actor ->
|
||||
if (actor is Visible &&
|
||||
distToActorSqr(actor, player) <= (Terrarum.WIDTH.plus(actor.hitbox.width.div(2)).sqr() +
|
||||
Terrarum.HEIGHT.plus(actor.hitbox.height.div(2)).sqr())
|
||||
) { // if visible and within screen
|
||||
actor.drawBody(gc, g)
|
||||
}
|
||||
}
|
||||
player.drawBody(gc, g)
|
||||
|
||||
LightmapRenderer.renderLightMap()
|
||||
@@ -204,12 +223,19 @@ constructor() : BasicGameState() {
|
||||
setBlendNormal()
|
||||
|
||||
// draw actor glows
|
||||
actorContainer.forEach { actor -> if (actor is Glowing) actor.drawGlow(gc, g) }
|
||||
actorContainer.forEach { actor ->
|
||||
if (actor is Visible &&
|
||||
distToActorSqr(actor, player) <= (Terrarum.WIDTH.plus(actor.hitbox.width.div(2)).sqr() +
|
||||
Terrarum.HEIGHT.plus(actor.hitbox.height.div(2)).sqr())
|
||||
) {
|
||||
actor.drawGlow(gc, g)
|
||||
}
|
||||
}
|
||||
player.drawGlow(gc, g)
|
||||
|
||||
// draw reference ID if debugWindow is open
|
||||
if (debugWindow.isVisible) {
|
||||
actorContainer.forEach { actor ->
|
||||
if (debugWindow.visible) {
|
||||
actorContainer.forEachIndexed { i, actor ->
|
||||
if (actor is Visible) {
|
||||
g.color = Color.white
|
||||
g.font = Terrarum.smallNumbers
|
||||
@@ -218,6 +244,12 @@ constructor() : BasicGameState() {
|
||||
actor.hitbox.posX,
|
||||
actor.hitbox.pointedY + 4
|
||||
)
|
||||
g.color = Color(0x80FF80)
|
||||
g.drawString(
|
||||
i.toString(),
|
||||
actor.hitbox.posX,
|
||||
actor.hitbox.pointedY + 12
|
||||
)
|
||||
g.font = Terrarum.gameFont
|
||||
}
|
||||
}
|
||||
@@ -304,40 +336,67 @@ constructor() : BasicGameState() {
|
||||
(this and 0xff00).ushr(8).shl(10) or
|
||||
(this and 0xff0000).ushr(16).shl(20)
|
||||
|
||||
fun Float.sqr() = this * this
|
||||
fun Int.sqr() = this * this
|
||||
private fun distToActorSqr(a: Visible, p: Player) =
|
||||
(a.hitbox.centeredX - p.hitbox.centeredX).sqr() + (a.hitbox.centeredY - p.hitbox.centeredY).sqr()
|
||||
/**
|
||||
* actorContainer extensions
|
||||
*/
|
||||
fun hasActor(ID: Int): Boolean {
|
||||
for (actor in actorContainer) {
|
||||
if (actor.referenceID == ID) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
fun hasActor(ID: Int): Boolean =
|
||||
if (actorContainer.size == 0)
|
||||
false
|
||||
else
|
||||
actorContainer.binarySearch(ID) >= 0
|
||||
|
||||
/**
|
||||
* Remove actor and sort the list
|
||||
*/
|
||||
fun removeActor(ID: Int) {
|
||||
for (actor in actorContainer) {
|
||||
if (actor.referenceID == ID)
|
||||
if (actor.referenceID == ID) {
|
||||
actorContainer.remove(actor)
|
||||
actorContainer.sort()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add actor and sort the list
|
||||
*/
|
||||
fun addActor(other: Actor): Boolean {
|
||||
if (hasActor(other.referenceID)) return false
|
||||
actorContainer.add(other)
|
||||
actorContainer.sort()
|
||||
return true
|
||||
}
|
||||
|
||||
fun getActor(ID: Int): Actor {
|
||||
for (actor in actorContainer) {
|
||||
if (actor.referenceID == ID)
|
||||
return actor
|
||||
}
|
||||
throw NullPointerException("Actor with ID $ID does not exist.")
|
||||
if (actorContainer.size == 0) throw IllegalArgumentException("Actor with ID $ID does not exist.")
|
||||
|
||||
val index = actorContainer.binarySearch(ID)
|
||||
if (index < 0)
|
||||
throw IllegalArgumentException("Actor with ID $ID does not exist.")
|
||||
else
|
||||
return actorContainer[index]
|
||||
}
|
||||
|
||||
fun addUI(other: UIHandler): Boolean {
|
||||
if (uiContainer.contains(other)) return false
|
||||
uiContainer.add(other)
|
||||
return true
|
||||
private fun ArrayList<Actor>.binarySearch(ID: Int): Int {
|
||||
var low = 0
|
||||
var high = actorContainer.size - 1
|
||||
|
||||
while (low <= high) {
|
||||
val mid = (low + high).ushr(1) // safe from overflows
|
||||
val midVal = get(mid)
|
||||
|
||||
if (ID > midVal.referenceID)
|
||||
low = mid + 1
|
||||
else if (ID < midVal.referenceID)
|
||||
high = mid - 1
|
||||
else
|
||||
return mid // key found
|
||||
}
|
||||
return -(low + 1) // key not found
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package net.torvald.terrarum
|
||||
import net.torvald.imagefont.GameFontWhite
|
||||
import net.torvald.JsonFetcher
|
||||
import net.torvald.JsonWriter
|
||||
import net.torvald.imagefont.SmallNumbers
|
||||
import net.torvald.imagefont.TinyAlphNum
|
||||
import org.lwjgl.input.Controllers
|
||||
import org.lwjgl.opengl.GL11
|
||||
import org.newdawn.slick.*
|
||||
@@ -47,7 +47,7 @@ constructor(gamename: String) : StateBasedGame(gamename) {
|
||||
@Throws(SlickException::class)
|
||||
override fun initStatesList(gc: GameContainer) {
|
||||
gameFont = GameFontWhite()
|
||||
smallNumbers = SmallNumbers()
|
||||
smallNumbers = TinyAlphNum()
|
||||
|
||||
hasController = gc.input.controllerCount > 0
|
||||
if (hasController) {
|
||||
|
||||
@@ -9,6 +9,8 @@ import org.apache.commons.codec.digest.DigestUtils
|
||||
*/
|
||||
class Authenticator : ConsoleCommand {
|
||||
|
||||
private var a = false
|
||||
|
||||
override fun execute(args: Array<String>) {
|
||||
if (args.size == 2) {
|
||||
val pwd = args[1]
|
||||
@@ -38,9 +40,4 @@ class Authenticator : ConsoleCommand {
|
||||
override fun printUsage() {
|
||||
CommandInterpreter.echoUnknownCmd("auth")
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private var a = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,9 +48,9 @@ object CommandInterpreter {
|
||||
}
|
||||
}
|
||||
catch (e: Exception) {
|
||||
println("[CommandInterpreter] :")
|
||||
System.err.print("[CommandInterpreter] ")
|
||||
e.printStackTrace()
|
||||
Echo().execute(Lang.get("ERROR_GENERIC_TEXT"))
|
||||
Echo().error(Lang["ERROR_GENERIC_TEXT"])
|
||||
}
|
||||
|
||||
}
|
||||
@@ -92,8 +92,8 @@ object CommandInterpreter {
|
||||
val sb = StringBuilder()
|
||||
val formatter = Formatter(sb)
|
||||
|
||||
Echo().execute(
|
||||
formatter.format(Lang.get("DEV_MESSAGE_CONSOLE_COMMAND_UNKNOWN"), cmdname).toString())
|
||||
Echo().error(
|
||||
formatter.format(Lang["DEV_MESSAGE_CONSOLE_COMMAND_UNKNOWN"], cmdname).toString())
|
||||
}
|
||||
|
||||
private class CommandInput(o: Array<Any>) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.torvald.terrarum.console
|
||||
|
||||
import net.torvald.imagefont.GameFontBase
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.ui.ConsoleWindow
|
||||
|
||||
@@ -20,6 +21,10 @@ internal class Echo : ConsoleCommand {
|
||||
(Terrarum.game.consoleHandler.UI as ConsoleWindow).sendMessage(single_line)
|
||||
}
|
||||
|
||||
fun error(single_line: String) {
|
||||
(Terrarum.game.consoleHandler.UI as ConsoleWindow).sendMessage("${GameFontBase.colToCode["r"]}$single_line")
|
||||
}
|
||||
|
||||
override fun printUsage() {
|
||||
|
||||
}
|
||||
|
||||
@@ -17,37 +17,73 @@ class GetAV : ConsoleCommand {
|
||||
val av = Terrarum.game.player.actorValue
|
||||
val keyset = av.keySet
|
||||
|
||||
echo.execute("== ActorValue list for player ==")
|
||||
keyset.forEach { elem -> echo.execute("$elem = ${av[elem as String]}") }
|
||||
|
||||
}
|
||||
else if (args.size != 3 && args.size != 2) {
|
||||
printUsage()
|
||||
}
|
||||
else if (args.size == 2) {
|
||||
echo.execute("player." + args[1] + " = "
|
||||
+ Terrarum.game.player.actorValue[args[1]]
|
||||
+ " ("
|
||||
+ Terrarum.game.player.actorValue[args[1]]!!.javaClass.simpleName
|
||||
+ ")")
|
||||
// check if args[1] is number or not
|
||||
if (!args[1].isNum()) { // args[1] is ActorValue name
|
||||
echo.execute("player.${args[1]} = "
|
||||
+ Terrarum.game.player.actorValue[args[1]]
|
||||
+ " ("
|
||||
+ Terrarum.game.player.actorValue[args[1]]!!.javaClass.simpleName
|
||||
+ ")"
|
||||
)
|
||||
}
|
||||
else { // args[1] is actor ID
|
||||
val av = Terrarum.game.getActor(args[1].toInt()).actorValue
|
||||
val keyset = av.keySet
|
||||
|
||||
echo.execute("== ActorValue list for ${args[1].toInt()} ==")
|
||||
if (keyset.size == 0)
|
||||
echo.execute("(nothing)")
|
||||
else
|
||||
keyset.forEach { elem -> echo.execute("$elem = ${av[elem as String]}") }
|
||||
}
|
||||
}
|
||||
else if (args.size == 3) {
|
||||
|
||||
val id = args[1].toInt()
|
||||
val av = args[2]
|
||||
echo.execute("$id.$av = " +
|
||||
Terrarum.game.getActor(id).actorValue[av] +
|
||||
" (" +
|
||||
Terrarum.game.getActor(id).actorValue[av]!!.javaClass.simpleName +
|
||||
")"
|
||||
)
|
||||
}
|
||||
}
|
||||
catch (e: NullPointerException) {
|
||||
if (args.size == 2) {
|
||||
echo.execute(args[1] + ": actor value does not exist.")
|
||||
echo.error(args[1] + ": actor value does not exist.")
|
||||
}
|
||||
else if (args.size == 3) {
|
||||
echo.execute(args[2] + ": actor value does not exist.")
|
||||
echo.error(args[2] + ": actor value does not exist.")
|
||||
}
|
||||
else {
|
||||
throw NullPointerException()
|
||||
}
|
||||
}
|
||||
catch (e1: IllegalArgumentException) {
|
||||
if (args.size == 3) {
|
||||
echo.error(args[1] + ": no actor with this ID.")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun String.isNum(): Boolean {
|
||||
try {
|
||||
this.toInt()
|
||||
return true
|
||||
}
|
||||
catch (e: NumberFormatException) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
override fun printUsage() {
|
||||
val echo = Echo()
|
||||
echo.execute("Get desired actor value of specific target.")
|
||||
|
||||
@@ -19,43 +19,81 @@ internal class SetAV : ConsoleCommand {
|
||||
}
|
||||
|
||||
override fun execute(args: Array<String>) {
|
||||
val echo = Echo()
|
||||
|
||||
// setav <id or "player"> <av> <val>
|
||||
if (args.size != 4 && args.size != 3) {
|
||||
printUsage()
|
||||
}
|
||||
else if (args.size == 3) {
|
||||
fun parseAVInput(arg: String): Any {
|
||||
val `val`: Any
|
||||
|
||||
try {
|
||||
`val` = Integer(args[2]) // try for integer
|
||||
`val` = Integer(arg) // try for integer
|
||||
}
|
||||
catch (e: NumberFormatException) {
|
||||
|
||||
try {
|
||||
`val` = args[2].toFloat() // try for float
|
||||
`val` = arg.toFloat() // try for float
|
||||
}
|
||||
catch (ee: NumberFormatException) {
|
||||
if (args[2].equals("__true", ignoreCase = true)) {
|
||||
if (arg.equals("__true", ignoreCase = true)) {
|
||||
`val` = true
|
||||
}
|
||||
else if (args[2].equals("__false", ignoreCase = true)) {
|
||||
else if (arg.equals("__false", ignoreCase = true)) {
|
||||
`val` = false
|
||||
}
|
||||
else {
|
||||
`val` = args[2] // string if not number
|
||||
`val` = arg // string if not number
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return `val`
|
||||
}
|
||||
|
||||
val echo = Echo()
|
||||
|
||||
// setav <id, or blank for player> <av> <val>
|
||||
if (args.size != 4 && args.size != 3) {
|
||||
printUsage()
|
||||
}
|
||||
else if (args.size == 3) {
|
||||
val `val` = parseAVInput(args[2])
|
||||
|
||||
// check if av is number
|
||||
if (args[1].isNum()) {
|
||||
echo.error("Illegal ActorValue “${args[1]}”: ActorValue cannot be a number.")
|
||||
return
|
||||
}
|
||||
|
||||
Terrarum.game.player.actorValue[args[1]] = `val`
|
||||
echo.execute("Set " + args[1] + " to " + `val`)
|
||||
echo.execute("Set ${args[1]} to $`val`")
|
||||
}
|
||||
else if (args.size == 4) {
|
||||
try {
|
||||
val id = args[1].toInt()
|
||||
val `val` = parseAVInput(args[3])
|
||||
|
||||
// check if av is number
|
||||
if (args[2].isNum()) {
|
||||
echo.error("Illegal ActorValue “${args[2]}”: ActorValue cannot be a number.")
|
||||
return
|
||||
}
|
||||
|
||||
Terrarum.game.getActor(id).actorValue[args[2]] = `val`
|
||||
echo.execute("Set ${args[2]} of $id to $`val`")
|
||||
}
|
||||
catch (e: IllegalArgumentException) {
|
||||
if (args.size == 4)
|
||||
echo.error(args[1] + ": no actor with this ID.")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun String.isNum(): Boolean {
|
||||
try {
|
||||
this.toInt()
|
||||
return true
|
||||
}
|
||||
catch (e: NumberFormatException) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,15 +5,20 @@ import org.newdawn.slick.GameContainer
|
||||
/**
|
||||
* Created by minjaesong on 16-03-14.
|
||||
*/
|
||||
interface Actor {
|
||||
abstract class Actor : Comparable<Actor> {
|
||||
|
||||
fun update(gc: GameContainer, delta_t: Int)
|
||||
abstract fun update(gc: GameContainer, delta_t: Int)
|
||||
|
||||
/**
|
||||
* Valid RefID is equal to or greater than 32768.
|
||||
* @return Reference ID. (32768-0xFFFF_FFFF)
|
||||
*/
|
||||
var referenceID: Int
|
||||
abstract var referenceID: Int
|
||||
|
||||
var actorValue: ActorValue
|
||||
abstract var actorValue: ActorValue
|
||||
|
||||
override fun equals(other: Any?) = referenceID == (other as Actor).referenceID
|
||||
override fun hashCode() = referenceID
|
||||
override fun toString() = "ActorID: ${hashCode()}"
|
||||
override fun compareTo(other: Actor): Int = this.referenceID - other.referenceID
|
||||
}
|
||||
@@ -16,7 +16,7 @@ import org.newdawn.slick.Graphics
|
||||
*
|
||||
* Created by minjaesong on 16-03-14.
|
||||
*/
|
||||
open class ActorWithBody constructor() : Actor, Visible, Glowing {
|
||||
open class ActorWithBody constructor() : Actor(), Visible {
|
||||
|
||||
override var actorValue: ActorValue = ActorValue()
|
||||
|
||||
@@ -26,15 +26,13 @@ open class ActorWithBody constructor() : Actor, Visible, Glowing {
|
||||
var baseHitboxH: Int = 0
|
||||
|
||||
/**
|
||||
* Velocity for newtonian sim.
|
||||
* Fluctuation in, otherwise still, velocity is equal to acceleration.
|
||||
|
||||
* Velocity vector (broken down by axes) for newtonian sim.
|
||||
* Acceleration: used in code like:
|
||||
* veloY += 3.0
|
||||
* +3.0 is acceleration. You __accumulate__ acceleration to the velocity.
|
||||
*/
|
||||
@Volatile var veloX: Float = 0.toFloat()
|
||||
@Volatile var veloY: Float = 0.toFloat()
|
||||
var veloX: Float = 0.toFloat()
|
||||
var veloY: Float = 0.toFloat()
|
||||
@Transient private val VELO_HARD_LIMIT = 10000f
|
||||
|
||||
var grounded = false
|
||||
@@ -61,16 +59,17 @@ open class ActorWithBody constructor() : Actor, Visible, Glowing {
|
||||
@Transient val nextHitbox = Hitbox(0f,0f,0f,0f)
|
||||
|
||||
/**
|
||||
* Physical properties
|
||||
* Physical properties.
|
||||
* Values derived from ActorValue must be @Transient.
|
||||
*/
|
||||
@Volatile @Transient var scale = 1f
|
||||
@Volatile @Transient var mass = 2f
|
||||
@Transient var scale = 1f
|
||||
@Transient var mass = 2f
|
||||
@Transient private val MASS_LOWEST = 2f
|
||||
/** Valid range: [0, 1] */
|
||||
var elasticity = 0f
|
||||
set(value) {
|
||||
if (value < 0)
|
||||
throw IllegalArgumentException("[ActorWithBody] $value: valid elasticity value is [0, 1].")
|
||||
throw IllegalArgumentException("[ActorWithBody] Invalid elasticity value: $value; valid elasticity value is [0, 1].")
|
||||
else if (value > 1) {
|
||||
println("[ActorWithBody] Elasticity were capped to 1.")
|
||||
field = ELASTICITY_MAX
|
||||
@@ -89,11 +88,11 @@ open class ActorWithBody constructor() : Actor, Visible, Glowing {
|
||||
*/
|
||||
@Transient private val METER = 24f
|
||||
/**
|
||||
* [m / s^2] * SI_TO_GAME_ACC -> [px / IFrame^2]
|
||||
* [m / s^2] * SI_TO_GAME_ACC -> [px / InternalFrame^2]
|
||||
*/
|
||||
@Transient private val SI_TO_GAME_ACC = METER / FastMath.sqr(Terrarum.TARGET_FPS.toFloat())
|
||||
/**
|
||||
* [m / s] * SI_TO_GAME_VEL -> [px / IFrame]
|
||||
* [m / s] * SI_TO_GAME_VEL -> [px / InternalFrame]
|
||||
*/
|
||||
@Transient private val SI_TO_GAME_VEL = METER / Terrarum.TARGET_FPS
|
||||
|
||||
@@ -131,6 +130,8 @@ open class ActorWithBody constructor() : Actor, Visible, Glowing {
|
||||
|
||||
@Transient private val MASS_DEFAULT = 60f
|
||||
|
||||
internal val physSleep: Boolean
|
||||
get() = veloX.abs() < 0.5 && veloY.abs() < 0.5
|
||||
|
||||
private var posAdjustX = 0
|
||||
private var posAdjustY = 0
|
||||
|
||||
104
src/net/torvald/terrarum/gameactors/CollisionSolver.kt
Normal file
@@ -0,0 +1,104 @@
|
||||
package net.torvald.terrarum.gameactors
|
||||
|
||||
import com.jme3.math.FastMath
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 16-04-22.
|
||||
*/
|
||||
object CollisionSolver {
|
||||
|
||||
private const val STARTPOINT = 1
|
||||
private const val ENDPOINT = 2
|
||||
|
||||
private const val COLL_LIST_SIZE = 256
|
||||
private const val COLL_CANDIDATES_SIZE = 128
|
||||
private const val COLL_FINAL_CANDIDATES_SIZE = 16
|
||||
|
||||
private val collListX = ArrayList<CollisionMarkings>(COLL_LIST_SIZE)
|
||||
private val collListY = ArrayList<CollisionMarkings>(COLL_LIST_SIZE)
|
||||
|
||||
private val collCandidateX = ArrayList<Pair<ActorWithBody, ActorWithBody>>(COLL_CANDIDATES_SIZE)
|
||||
private val collCandidateY = ArrayList<Pair<ActorWithBody, ActorWithBody>>(COLL_CANDIDATES_SIZE)
|
||||
private val collCandidates = ArrayList<Pair<ActorWithBody, ActorWithBody>>(COLL_FINAL_CANDIDATES_SIZE)
|
||||
|
||||
/**
|
||||
* @link https://www.toptal.com/game/video-game-physics-part-ii-collision-detection-for-solid-objects
|
||||
*/
|
||||
fun process() {
|
||||
// mark list x
|
||||
Terrarum.game.actorContainer.forEach { it ->
|
||||
if (it is ActorWithBody) {
|
||||
collListX.add(CollisionMarkings(it.hitbox.hitboxStart.x, STARTPOINT, it.referenceID))
|
||||
collListX.add(CollisionMarkings(it.hitbox.hitboxEnd.x, ENDPOINT, it.referenceID))
|
||||
}
|
||||
}
|
||||
|
||||
// sort list x (will use Timsort with Java SE >= 8, Mergesort otherwise)
|
||||
collListX.sortBy { it.pos }
|
||||
|
||||
// set candidateX
|
||||
|
||||
// mark list y
|
||||
Terrarum.game.actorContainer.forEach { it ->
|
||||
if (it is ActorWithBody) {
|
||||
collListY.add(CollisionMarkings(it.hitbox.hitboxStart.y, STARTPOINT, it.referenceID))
|
||||
collListY.add(CollisionMarkings(it.hitbox.hitboxEnd.y, ENDPOINT, it.referenceID))
|
||||
}
|
||||
}
|
||||
|
||||
// sort list y
|
||||
collListY.sortBy { it.pos }
|
||||
|
||||
// set candidateY
|
||||
|
||||
// look for overlaps in candidate X/Y and put them into collCandidates
|
||||
|
||||
// solve collision for actors in collCandidates
|
||||
}
|
||||
|
||||
private fun solveCollision(a: ActorWithBody, b: ActorWithBody) {
|
||||
|
||||
}
|
||||
|
||||
private infix fun ActorWithBody.isCollidingWith(other: ActorWithBody): Boolean {
|
||||
val ax = this.hitbox.centeredX
|
||||
val ay = this.hitbox.centeredY
|
||||
val bx = other.hitbox.centeredX
|
||||
val by = other.hitbox.centeredY
|
||||
|
||||
// will refer 'actor_dist_t' as 't' afterward
|
||||
val actor_dist_t_sqr = ((ay - by).sqr() + (ax - bx).sqr()) // no sqrt; 'power' is slower than 'times'
|
||||
val dist_x = (ax - bx).abs() // 'tx'
|
||||
val dist_y = (ay - by).abs() // 'ty'
|
||||
val tangent = dist_y / dist_x
|
||||
|
||||
var t_ax: Float; var t_ay: Float
|
||||
if (dist_x > dist_y) {
|
||||
t_ax = this.hitbox.width / 2
|
||||
t_ay = t_ax * tangent
|
||||
}
|
||||
else {
|
||||
t_ay = this.hitbox.height / 2
|
||||
t_ax = t_ay * tangent
|
||||
}
|
||||
|
||||
return (t_ax.sqr() + t_ay.sqr()) < actor_dist_t_sqr
|
||||
}
|
||||
|
||||
fun Float.abs() = if (this < 0) -this else this
|
||||
fun Float.sqr() = this * this
|
||||
|
||||
data class CollisionMarkings(
|
||||
val pos: Float,
|
||||
val kind: Int,
|
||||
val actorID: Int
|
||||
)
|
||||
|
||||
/**
|
||||
* === Some useful physics knowledge ===
|
||||
*
|
||||
* * Momentum = mass × Velocity
|
||||
*/
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package net.torvald.terrarum.gameactors
|
||||
|
||||
import org.newdawn.slick.GameContainer
|
||||
import org.newdawn.slick.Graphics
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 16-03-14.
|
||||
*/
|
||||
interface Glowing {
|
||||
fun drawGlow(gc: GameContainer, g: Graphics)
|
||||
|
||||
fun updateGlowSprite(gc: GameContainer, delta: Int)
|
||||
}
|
||||
@@ -15,7 +15,7 @@ class PhysTestBall : ActorWithBody {
|
||||
constructor(): super() {
|
||||
setHitboxDimension(16, 16, 0, 0)
|
||||
isVisible = true
|
||||
mass = 10f
|
||||
actorValue[AVKey.BASEMASS] = 10f
|
||||
|
||||
color = RoguelikeRandomiser.composeColourFrom(RoguelikeRandomiser.POTION_PRIMARY_COLSET)
|
||||
}
|
||||
@@ -23,9 +23,9 @@ class PhysTestBall : ActorWithBody {
|
||||
override fun drawBody(gc: GameContainer, g: Graphics) {
|
||||
g.color = color
|
||||
g.fillOval(
|
||||
hitbox!!.posX,
|
||||
hitbox!!.posY,
|
||||
hitbox!!.width,
|
||||
hitbox!!.height)
|
||||
hitbox.posX,
|
||||
hitbox.posY,
|
||||
hitbox.width,
|
||||
hitbox.height)
|
||||
}
|
||||
}
|
||||
@@ -12,4 +12,8 @@ interface Visible {
|
||||
fun drawBody(gc: GameContainer, g: Graphics)
|
||||
|
||||
fun updateBodySprite(gc: GameContainer, delta: Int)
|
||||
|
||||
fun drawGlow(gc: GameContainer, g: Graphics)
|
||||
|
||||
fun updateGlowSprite(gc: GameContainer, delta: Int)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.torvald.terrarum.ui
|
||||
|
||||
import com.jme3.math.FastMath
|
||||
import net.torvald.imagefont.GameFontBase
|
||||
import net.torvald.terrarum.gamemap.PairedMapLayer
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.mapdrawer.LightmapRenderer
|
||||
@@ -18,7 +19,7 @@ import java.util.*
|
||||
/**
|
||||
* Created by minjaesong on 16-03-14.
|
||||
*/
|
||||
class BasicDebugInfoWindow : UICanvas {
|
||||
class BasicDebugInfoWindow:UICanvas {
|
||||
|
||||
override var width: Int = Terrarum.WIDTH
|
||||
override var height: Int = Terrarum.HEIGHT
|
||||
@@ -59,30 +60,35 @@ class BasicDebugInfoWindow : UICanvas {
|
||||
val mouseTileX = ((MapCamera.cameraX + gc.input.mouseX / Terrarum.game.screenZoom) / MapDrawer.TILE_SIZE).toInt()
|
||||
val mouseTileY = ((MapCamera.cameraY + gc.input.mouseY / Terrarum.game.screenZoom) / MapDrawer.TILE_SIZE).toInt()
|
||||
|
||||
g.color = Color.white
|
||||
g.font = Terrarum.smallNumbers
|
||||
g.color = GameFontBase.codeToCol["y"]
|
||||
|
||||
val hitbox = player.hitbox
|
||||
val nextHitbox = player.nextHitbox
|
||||
|
||||
printLine(g, 1, "posX: "
|
||||
val ccG = "${GameFontBase.colToCode["g"]}"
|
||||
|
||||
printLine(g, 1, "posX "
|
||||
+ ccG
|
||||
+ "${hitbox.pointedX.toString()}"
|
||||
+ " ("
|
||||
+ "${(hitbox.pointedX / MapDrawer.TILE_SIZE).toInt().toString()}"
|
||||
+ ")")
|
||||
printLine(g, 2, "posY: "
|
||||
printLine(g, 2, "posY "
|
||||
+ ccG
|
||||
+ hitbox.pointedY.toString()
|
||||
+ " ("
|
||||
+ (hitbox.pointedY / MapDrawer.TILE_SIZE).toInt().toString()
|
||||
+ ")")
|
||||
|
||||
printLine(g, 3, "veloX reported: ${player.veloX}")
|
||||
printLine(g, 4, "veloY reported: ${player.veloY}")
|
||||
printLine(g, 3, "veloX reported $ccG${player.veloX}")
|
||||
printLine(g, 4, "veloY reported $ccG${player.veloY}")
|
||||
|
||||
printLineColumn(g, 2, 3, "veloX measured: ${xdelta}")
|
||||
printLineColumn(g, 2, 4, "veloY measured: ${ydelta}")
|
||||
printLineColumn(g, 2, 3, "veloX measured $ccG${xdelta}")
|
||||
printLineColumn(g, 2, 4, "veloY measured $ccG${ydelta}")
|
||||
|
||||
printLine(g, 5, "grounded : ${player.grounded}")
|
||||
printLine(g, 6, "noClip : ${player.noClip}")
|
||||
printLine(g, 5, "grounded $ccG${player.grounded}")
|
||||
printLine(g, 6, "noClip $ccG${player.noClip}")
|
||||
|
||||
val lightVal: String
|
||||
var mtX = mouseTileX.toString()
|
||||
@@ -100,7 +106,7 @@ class BasicDebugInfoWindow : UICanvas {
|
||||
rawB.toString() + ")"
|
||||
|
||||
|
||||
printLine(g, 7, "light at cursor : " + lightVal)
|
||||
printLine(g, 7, "light@cursor $ccG$lightVal")
|
||||
|
||||
val tileNo: String
|
||||
val tileNumRaw = Terrarum.game.map.getTileFromTerrain(mouseTileX, mouseTileY) ?: -1
|
||||
@@ -108,33 +114,22 @@ class BasicDebugInfoWindow : UICanvas {
|
||||
val tiledmg = tileNumRaw % PairedMapLayer.RANGE
|
||||
tileNo = if (tileNumRaw == -1) "—" else "$tilenum:$tiledmg"
|
||||
|
||||
printLine(g, 8, "tile at cursor : $tileNo ($mtX, $mtY)")
|
||||
printLine(g, 8, "tile@cursor $ccG$tileNo ($mtX, $mtY)")
|
||||
|
||||
/**
|
||||
* Second column
|
||||
*/
|
||||
|
||||
printLineColumn(g, 2, 1, "${Lang["MENU_OPTIONS_VSYNC"]} : " + Terrarum.appgc.isVSyncRequested)
|
||||
printLineColumn(g, 2, 2, "Env colour temp : " + MapDrawer.getColTemp())
|
||||
printLineColumn(g, 2, 5, "Time : ${Terrarum.game.map.worldTime.elapsedSeconds()}" +
|
||||
printLineColumn(g, 2, 1, "VSync $ccG" + Terrarum.appgc.isVSyncRequested)
|
||||
printLineColumn(g, 2, 2, "Env colour temp $ccG" + MapDrawer.getColTemp())
|
||||
printLineColumn(g, 2, 5, "Time $ccG${Terrarum.game.map.worldTime.elapsedSeconds()}" +
|
||||
" (${Terrarum.game.map.worldTime.getFormattedTime()})")
|
||||
printLineColumn(g, 2, 6, "Mass : ${player.mass}")
|
||||
printLineColumn(g, 2, 6, "Mass $ccG${player.mass}")
|
||||
|
||||
/**
|
||||
* On screen
|
||||
*/
|
||||
|
||||
// Memory allocation
|
||||
val memInUse = Terrarum.game.memInUse
|
||||
val totalVMMem = Terrarum.game.totalVMMem
|
||||
|
||||
g.color = Color(0xFF7F00)
|
||||
g.drawString(
|
||||
Lang["DEV_MEMORY_SHORT_CAP"]
|
||||
+ " : "
|
||||
+ formatter.format(
|
||||
Lang["DEV_MEMORY_A_OF_B"], memInUse, totalVMMem), (Terrarum.WIDTH - 200).toFloat(), line(1).toFloat())
|
||||
|
||||
// Hitbox
|
||||
val zoom = Terrarum.game.screenZoom
|
||||
g.color = Color(0x007f00)
|
||||
@@ -148,12 +143,12 @@ class BasicDebugInfoWindow : UICanvas {
|
||||
, (hitbox.pointedY - 1) * zoom - MapCamera.cameraY * zoom
|
||||
, 3f, 3f)
|
||||
g.drawString(
|
||||
Lang["DEV_COLOUR_LEGEND_GREEN"] + " : hitbox", (Terrarum.WIDTH - 200).toFloat()
|
||||
, line(2).toFloat())
|
||||
"hitbox", (Terrarum.WIDTH - 15 * 8 - 2).toFloat().toFloat()
|
||||
, line(1))
|
||||
|
||||
// Next hitbox
|
||||
g.color = Color.blue
|
||||
g.drawRect(nextHitbox!!.hitboxStart.x * zoom - MapCamera.cameraX * zoom
|
||||
g.drawRect(nextHitbox.hitboxStart.x * zoom - MapCamera.cameraX * zoom
|
||||
, nextHitbox.hitboxStart.y * zoom - MapCamera.cameraY * zoom
|
||||
, nextHitbox.width * zoom
|
||||
, nextHitbox.height * zoom)
|
||||
@@ -163,21 +158,41 @@ class BasicDebugInfoWindow : UICanvas {
|
||||
, (nextHitbox.pointedY - 1) * zoom - MapCamera.cameraY * zoom
|
||||
, 3f, 3f)
|
||||
g.drawString(
|
||||
Lang["DEV_COLOUR_LEGEND_BLUE"] + " : nextHitbox", (Terrarum.WIDTH - 200).toFloat()
|
||||
, line(3).toFloat())
|
||||
"nextHitbox", (Terrarum.WIDTH - 15 * 8 - 2).toFloat().toFloat()
|
||||
, line(2))
|
||||
|
||||
drawHistogram(g, LightmapRenderer.histogram,
|
||||
Terrarum.WIDTH - histogramW - 30,
|
||||
Terrarum.HEIGHT - histogramH - 30
|
||||
)
|
||||
|
||||
g.color = GameFontBase.codeToCol["y"]
|
||||
g.drawString("MEM ", (Terrarum.WIDTH - 15 * 8 - 2).toFloat(), 2f)
|
||||
//g.drawString("FPS ", (Terrarum.WIDTH - 6 * 8 - 2).toFloat(), 10f)
|
||||
g.drawString("Actors total ", 2f, Terrarum.HEIGHT - 10f)
|
||||
g.drawString("Active ", (2 + 17*8).toFloat(), Terrarum.HEIGHT - 10f)
|
||||
|
||||
g.color = GameFontBase.codeToCol["g"]
|
||||
g.drawString("${Terrarum.game.memInUse}M",
|
||||
(Terrarum.WIDTH - 11 * 8 - 2).toFloat(), 2f)
|
||||
g.drawString("/${Terrarum.game.totalVMMem}M",
|
||||
(Terrarum.WIDTH - 6 * 8 - 2).toFloat(), 2f)
|
||||
//g.drawString("${Terrarum.appgc.fps}",
|
||||
// (Terrarum.WIDTH - 2 * 8 - 2).toFloat(), 10f)
|
||||
g.drawString("${Terrarum.game.actorContainer.size + Terrarum.game.actorcontainerInactive.size}",
|
||||
(2 + 13*8).toFloat(), Terrarum.HEIGHT - 10f
|
||||
)
|
||||
g.drawString(Terrarum.game.actorContainer.size.toString(),
|
||||
(2 + 24*8).toFloat(), Terrarum.HEIGHT - 10f
|
||||
)
|
||||
}
|
||||
|
||||
private fun printLine(g: Graphics, l: Int, s: String) {
|
||||
g.drawString(s, 20f, line(l).toFloat())
|
||||
g.drawString(s, 10f, line(l).toFloat())
|
||||
}
|
||||
|
||||
private fun printLineColumn(g: Graphics, col: Int, row: Int, s: String) {
|
||||
g.drawString(s, (20 + column(col)).toFloat(), line(row).toFloat())
|
||||
g.drawString(s, (10 + column(col)).toFloat(), line(row).toFloat())
|
||||
}
|
||||
|
||||
val histogramW = 256
|
||||
@@ -196,6 +211,10 @@ class BasicDebugInfoWindow : UICanvas {
|
||||
|
||||
g.color = uiColour
|
||||
g.fillRect(x.toFloat(), y.toFloat(), w.plus(1).toFloat(), h.toFloat())
|
||||
g.color = Color.gray
|
||||
g.drawString("0", x.toFloat(), y.toFloat() + h + 2)
|
||||
g.drawString("255", x.toFloat() + w + 1 - 8*3, y.toFloat() + h + 2)
|
||||
g.drawString("Histogramme", x + w / 2 - 5.5f * 8, y.toFloat() + h + 2)
|
||||
|
||||
setBlendScreen()
|
||||
for (c in 0..2) {
|
||||
@@ -219,9 +238,9 @@ class BasicDebugInfoWindow : UICanvas {
|
||||
setBlendNormal()
|
||||
}
|
||||
|
||||
private fun line(i: Int): Int = i * 20
|
||||
private fun line(i: Int): Float = i * 10f
|
||||
|
||||
private fun column(i: Int): Int = 250 * (i - 1)
|
||||
private fun column(i: Int): Float = 250f * (i - 1)
|
||||
|
||||
override fun doOpening(gc: GameContainer, delta: Int) {
|
||||
|
||||
|
||||
@@ -33,7 +33,10 @@ constructor(val UI: UICanvas) {
|
||||
private var opening = false
|
||||
private var closing = false
|
||||
private var opened = false // fully opened
|
||||
private var visible = false
|
||||
private var _visible = false
|
||||
val visible: Boolean
|
||||
get() = if (alwaysVisible) true
|
||||
else _visible
|
||||
|
||||
var openCloseCounter = 0
|
||||
|
||||
@@ -48,12 +51,12 @@ constructor(val UI: UICanvas) {
|
||||
|
||||
|
||||
fun update(gc: GameContainer, delta: Int) {
|
||||
if (visible || alwaysVisible) {
|
||||
if (_visible || alwaysVisible) {
|
||||
UI.update(gc, delta)
|
||||
}
|
||||
|
||||
if (opening) {
|
||||
visible = true
|
||||
_visible = true
|
||||
openCloseCounter += delta
|
||||
|
||||
// println("UI ${UI.javaClass.simpleName} (open)")
|
||||
@@ -84,14 +87,14 @@ constructor(val UI: UICanvas) {
|
||||
UI.endClosing(gc, delta)
|
||||
closing = false
|
||||
opened = false
|
||||
visible = false
|
||||
_visible = false
|
||||
openCloseCounter = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun render(gc: GameContainer, gameGraphicInstance: Graphics) {
|
||||
if (visible || alwaysVisible) {
|
||||
if (_visible || alwaysVisible) {
|
||||
UIGraphicInstance.clear()
|
||||
UIGraphicInstance.font = Terrarum.gameFont
|
||||
|
||||
@@ -113,22 +116,12 @@ constructor(val UI: UICanvas) {
|
||||
if (alwaysVisible) {
|
||||
throw RuntimeException("[UIHandler] Tried to 'set visibility of' constant UI")
|
||||
}
|
||||
visible = b
|
||||
_visible = b
|
||||
}
|
||||
|
||||
val isVisible: Boolean
|
||||
get() {
|
||||
if (alwaysVisible) {
|
||||
return true
|
||||
}
|
||||
else {
|
||||
return visible
|
||||
}
|
||||
}
|
||||
|
||||
fun setAsAlwaysVisible() {
|
||||
alwaysVisible = true
|
||||
visible = true
|
||||
_visible = true
|
||||
opened = true
|
||||
opening = false
|
||||
closing = false
|
||||
@@ -155,7 +148,7 @@ constructor(val UI: UICanvas) {
|
||||
if (alwaysVisible) {
|
||||
throw RuntimeException("[UIHandler] Tried to 'toggle opening of' constant UI")
|
||||
}
|
||||
if (visible) {
|
||||
if (_visible) {
|
||||
if (!closing) {
|
||||
setAsClosing()
|
||||
}
|
||||
@@ -168,61 +161,61 @@ constructor(val UI: UICanvas) {
|
||||
}
|
||||
|
||||
fun processInput(input: Input) {
|
||||
if (visible) {
|
||||
if (_visible) {
|
||||
UI.processInput(input)
|
||||
}
|
||||
}
|
||||
|
||||
fun keyPressed(key: Int, c: Char) {
|
||||
if (visible && UI is UITypable) {
|
||||
if (_visible && UI is UITypable) {
|
||||
UI.keyPressed(key, c)
|
||||
}
|
||||
}
|
||||
|
||||
fun keyReleased(key: Int, c: Char) {
|
||||
if (visible && UI is UITypable) {
|
||||
if (_visible && UI is UITypable) {
|
||||
UI.keyReleased(key, c)
|
||||
}
|
||||
}
|
||||
|
||||
fun mouseMoved(oldx: Int, oldy: Int, newx: Int, newy: Int) {
|
||||
if (visible && UI is UIClickable) {
|
||||
if (_visible && UI is UIClickable) {
|
||||
UI.mouseMoved(oldx, oldy, newx, newy)
|
||||
}
|
||||
}
|
||||
|
||||
fun mouseDragged(oldx: Int, oldy: Int, newx: Int, newy: Int) {
|
||||
if (visible && UI is UIClickable) {
|
||||
if (_visible && UI is UIClickable) {
|
||||
UI.mouseDragged(oldx, oldy, newx, newy)
|
||||
}
|
||||
}
|
||||
|
||||
fun mousePressed(button: Int, x: Int, y: Int) {
|
||||
if (visible && UI is UIClickable) {
|
||||
if (_visible && UI is UIClickable) {
|
||||
UI.mousePressed(button, x, y)
|
||||
}
|
||||
}
|
||||
|
||||
fun mouseReleased(button: Int, x: Int, y: Int) {
|
||||
if (visible && UI is UIClickable) {
|
||||
if (_visible && UI is UIClickable) {
|
||||
UI.mouseReleased(button, x, y)
|
||||
}
|
||||
}
|
||||
|
||||
fun mouseWheelMoved(change: Int) {
|
||||
if (visible && UI is UIClickable) {
|
||||
if (_visible && UI is UIClickable) {
|
||||
UI.mouseWheelMoved(change)
|
||||
}
|
||||
}
|
||||
|
||||
fun controllerButtonPressed(controller: Int, button: Int) {
|
||||
if (visible && UI is UIClickable) {
|
||||
if (_visible && UI is UIClickable) {
|
||||
UI.controllerButtonPressed(controller, button)
|
||||
}
|
||||
}
|
||||
|
||||
fun controllerButtonReleased(controller: Int, button: Int) {
|
||||
if (visible && UI is UIClickable) {
|
||||
if (_visible && UI is UIClickable) {
|
||||
UI.controllerButtonReleased(controller, button)
|
||||
}
|
||||
}
|
||||
@@ -233,6 +226,6 @@ constructor(val UI: UICanvas) {
|
||||
if (alwaysVisible) {
|
||||
return false
|
||||
}
|
||||
return visible && !opening
|
||||
return _visible && !opening
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 638 B |
|
Before Width: | Height: | Size: 663 B |