get player head texture wip

This commit is contained in:
minjaesong
2021-12-20 22:56:16 +09:00
parent 07345e3128
commit 099071bdd0
18 changed files with 431 additions and 40 deletions

View File

@@ -260,7 +260,7 @@ let reset = () => {
}
return Object.freeze({"n":"체시ᄂ 자ᄋ보ᄋ서ᄂ","v":"one","c":"CuriousTo\uA75Bvald","m":"rewrite",
"t":states.keylayouts.map(it => [it[0],it[1]]),
"l":"koKR",
"l":"koKRabc",
// return: [displayed output, composed output]
"accept":(headkey,shiftin,altgrin)=>{
let layer = 1*shiftin

View File

@@ -0,0 +1,282 @@
let states = {"keylayouts":[[""],[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
["0",")"],
["1","!"],
["2","@"],
["3","#"],
["4","$"],
["5","%"],
["6","^"],
["7","&"],
["8","*"],
["9","("],
["*"],
["#"],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
["\uFFB1"],
["\uFFD7"],
["\uFFBA"],
["\uFFB7"],
["\uFFA7","\uFFA8"],
["\uFFA9"],
["\uFFBE"],
["\uFFCC"],
["\uFFC4"],
["\uFFC6"],
["\uFFC2"],
["\uFFDC"],
["\uFFDA"],
["\uFFD3"],
["\uFFC3","\uFFC5"],
["\uFFC7","\uFFCB"],
["\uFFB2","\uFFB3"],
["\uFFA1","\uFFA2"],
["\uFFA4"],
["\uFFB5","\uFFB6"],
["\uFFCA"],
["\uFFBD"],
["\uFFB8","\uFFB9"],
["\uFFBC"],
["\uFFD2"],
["\uFFBB"],
[",","<"],
[".",">"],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[" "],
[undefined],
[undefined],
[undefined],
["\n"],
["\x08"],
["`","~"],
["-","_"],
["=","+"],
["[","{"],
["]","}"],
["\\","|"],
[";",":"],
["'",'"'],
["/","?"],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
["0"],
["1"],
["2"],
["3"],
["4"],
["5"],
["6"],
["7"],
["8"],
["9"],
["/"],
["*"],
["-"],
["+"],
["."],
["."],
["\n"],
["="],
["("],
[")"],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined]
],
"code":0}
let reset = () => {
states.code = 0
}
return Object.freeze({"n":"체시ᄂ 두버ᄅ시ᄀ","v":"one","c":"CuriousTo\uA75Bvald","m":"rewrite",
"t":states.keylayouts.map(it => [it[0],it[1]]),
"l":"koKRabc",
// return: [displayed output, composed output]
"accept":(headkey,shiftin,altgrin)=>{
let layer = 1*shiftin
states.code = 0
let s = states.keylayouts[headkey][layer]
return ['0', s]
},
"backspace":()=>{
reset()
return ''
},
"end":()=>{
reset()
return ''
},
"reset":()=>{ reset() },
"composing":()=>(states.code!='')
})

View File

@@ -1,6 +1,7 @@
package net.torvald.spriteanimation
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.TextureRegion
import net.torvald.spriteassembler.ADProperties
import net.torvald.spriteassembler.AssembleSheetPixmap
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
@@ -15,6 +16,8 @@ interface HasAssembledSprite {
/** ADL for glow sprite. Optional. */
var animDescGlow: ADProperties?
var spriteHeadTexture: TextureRegion?
// FIXME sometimes the animmation is invisible (row and nFrames mismatch -- row is changed to 1 but it's drawing 3rd frame?)
/**

View File

@@ -47,7 +47,7 @@ class ADProperties {
/** properties that are being used as skeletons (SKELETON_STAND) */
internal lateinit var skeletons: HashMap<String, Skeleton>; private set
/** properties that defines position of joint of the bodypart */
internal val bodyparts = HashMap<String, ADPropertyObject.Vector2i>()
internal val bodypartJoints = HashMap<String, ADPropertyObject.Vector2i>()
/** properties that are recognised as animations (ANIM_RUN, ANIM)IDLE) */
internal lateinit var animations: HashMap<String, Animation>; private set
/** an "animation frame" property (ANIM_RUN_1, ANIM_RUN_2) */
@@ -204,7 +204,7 @@ class ADProperties {
get("BODYPARTS").forEach {
try {
this.bodyparts[it.name] = (it.input as ADPropertyObject.Vector2i)
this.bodypartJoints[it.name] = (it.input as ADPropertyObject.Vector2i)
}
catch (e: NullPointerException) {
if (it.name.isBlank())
@@ -216,7 +216,7 @@ class ADProperties {
this.skeletons = skeletons
this.animations = animations
this.bodypartFiles = this.bodyparts.keys.map { toFilename(it) }
this.bodypartFiles = this.bodypartJoints.keys.map { toFilename(it) }
this.transforms = transforms
cols = maxColFinder

View File

@@ -2,16 +2,17 @@ package net.torvald.spriteassembler
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.badlogic.gdx.utils.GdxRuntimeException
import net.torvald.terrarum.linearSearch
import net.torvald.terrarum.serialise.Common
import net.torvald.terrarum.savegame.ByteArray64InputStream
import net.torvald.terrarum.savegame.ByteArray64Reader
import net.torvald.terrarum.savegame.SimpleFileSystem
import net.torvald.terrarum.serialise.Common
import java.io.FileNotFoundException
import java.io.InputStream
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
/**
* Assembles the single frame of the animation, outputs GDX Pixmap.
@@ -22,6 +23,27 @@ import kotlin.collections.HashMap
*/
object AssembleSheetPixmap {
/**
* The name of the Bodypart here may or may not be case-sensitive (depends on your actual filesystem -- NTFS, APFS, Ext4, ...)
*/
fun getAssetsDirFileGetter(properties: ADProperties): (String) -> InputStream? = { partName: String ->
val file = Gdx.files.internal("assets/${properties.toFilename(partName)}")
if (file.exists()) file.read() else null
}
/**
* The name of the Bodypart is CASE-SENSITIVE!
*/
fun getVirtualDiskFileGetter(bodypartMapping: Properties, disk: SimpleFileSystem): (String) -> InputStream? = { partName: String ->
bodypartMapping.getProperty(partName).let {
if (it != null)
ByteArray64InputStream(disk.getFile(bodypartMapping.getProperty(partName).toLong())!!.bytes)
else
null
}
}
private fun drawAndGetCanvas(properties: ADProperties, fileGetter: (String) -> InputStream?): Pixmap {
val canvas = Pixmap(properties.cols * properties.frameWidth, properties.rows * properties.frameHeight, Pixmap.Format.RGBA8888)
canvas.blending = Pixmap.Blending.SourceOver
@@ -34,25 +56,37 @@ object AssembleSheetPixmap {
return canvas
}
fun fromAssetsDir(properties: ADProperties) = drawAndGetCanvas(properties) { partName: String ->
val file = Gdx.files.internal("assets/${properties.toFilename(partName)}")
if (file.exists()) file.read() else null
}
fun fromAssetsDir(properties: ADProperties) = drawAndGetCanvas(properties, getAssetsDirFileGetter(properties))
fun fromVirtualDisk(disk: SimpleFileSystem, entrynum: Long, properties: ADProperties): Pixmap {
val bodypartMapping = Properties()
bodypartMapping.load(ByteArray64Reader(disk.getFile(entrynum)!!.bytes, Common.CHARSET))
val fileGetter = { partName: String ->
bodypartMapping.getProperty(partName).let {
if (it != null)
ByteArray64InputStream(disk.getFile(bodypartMapping.getProperty(partName).toLong())!!.bytes)
else
null
}
}
return drawAndGetCanvas(properties, getVirtualDiskFileGetter(bodypartMapping, disk))
}
return drawAndGetCanvas(properties, fileGetter)
fun getPartTex(getFile: (String) -> InputStream?, partName: String): TextureRegion? {
(getFile(partName) ?: throw FileNotFoundException("file for '$partName' is not found")).let {
val bytes = it.readAllBytes()
val pixmap = Pixmap(bytes, 0, bytes.size)
val tr = TextureRegion(Texture(pixmap))
pixmap.dispose()
return tr
}
return null
}
fun getHeadFromAssetsDir(properties: ADProperties): TextureRegion? {
// TODO assemble from HAIR_FORE (optional), HAIR (optional) then HEAD (mandatory)
return getPartTex(getAssetsDirFileGetter(properties), "HEAD")
}
fun getHeadFromVirtualDisk(disk: SimpleFileSystem, entrynum: Long, properties: ADProperties): TextureRegion? {
// TODO assemble from HAIR_FORE (optional), HAIR (optional) then HEAD (mandatory)
val bodypartMapping = Properties()
bodypartMapping.load(ByteArray64Reader(disk.getFile(entrynum)!!.bytes, Common.CHARSET))
return getPartTex(getVirtualDiskFileGetter(bodypartMapping, disk), "HEAD")
}
private fun drawThisFrame(frameName: String,
@@ -63,8 +97,8 @@ object AssembleSheetPixmap {
val theAnim = properties.getAnimByFrameName(frameName)
val skeleton = theAnim.skeleton.joints.reversed()
val transforms = properties.getTransform(frameName)
val bodypartOrigins = properties.bodyparts
val bodypartImages = properties.bodyparts.keys.map { partname ->
val bodypartOrigins = properties.bodypartJoints
val bodypartImages = properties.bodypartJoints.keys.map { partname ->
fileGetter(partname).let { file ->
if (file == null) partname to null
else {

View File

@@ -160,7 +160,7 @@ class SpriteAssemblerApp(val gdxWindow: SpriteAssemblerPreview) : JFrame() {
(panelAnimationsList.model as DefaultListModel).addElement("${it.value}")
}
// populate bodyparts view
adProperties.bodyparts.toSortedMap().forEach { part ->
adProperties.bodypartJoints.toSortedMap().forEach { part ->
(panelBodypartsList.model as DefaultListModel).addElement("${part.key}: ${part.value}")
}
// populate image file list view

View File

@@ -40,10 +40,7 @@ internal object CommandInterpreter {
var commandObj: ConsoleCommand? = null
try {
if (single_command.name.toLowerCase().startsWith("qqq")) {
commandObj = CommandDict["QuitApp"]
}
else if (commandsNoAuth.contains(single_command.name.toLowerCase())) {
if (commandsNoAuth.contains(single_command.name.toLowerCase())) {
commandObj = CommandDict[single_command.name.toLowerCase()]
}
else {

View File

@@ -0,0 +1,15 @@
package net.torvald.terrarum.console
import net.torvald.terrarum.Terrarum
/**
* Created by minjaesong on 2021-12-20.
*/
object Pause : ConsoleCommand {
override fun execute(args: Array<String>) {
Terrarum.ingame?.pause()
}
override fun printUsage() {
}
}

View File

@@ -0,0 +1,15 @@
package net.torvald.terrarum.console
import net.torvald.terrarum.Terrarum
/**
* Created by minjaesong on 2021-12-20.
*/
object Unpause : ConsoleCommand {
override fun execute(args: Array<String>) {
Terrarum.ingame?.resume()
}
override fun printUsage() {
}
}

View File

@@ -3,6 +3,7 @@ package net.torvald.terrarum.gameactors
import com.badlogic.gdx.Input
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion
import net.torvald.spriteanimation.SpriteAnimation
import net.torvald.terrarum.*
import net.torvald.terrarum.App.printdbg
@@ -1726,6 +1727,10 @@ open class ActorWithBody : Actor {
flagDespawn = true
}
open fun getSpriteHead(): TextureRegion? {
return sprite?.textureRegion?.get(0,0)
}
private fun forEachOccupyingTileNum(consumer: (ItemID?) -> Unit) {
if (world == null) return
@@ -1908,12 +1913,15 @@ inline fun drawBodyInGoodPosition(startX: Float, startY: Float, drawFun: (x: Flo
val offendingPad2 = WorldCamera.width + 1
if (WorldCamera.x >= offendingPad && startX < WorldCamera.width) {
// App.batch.color = Color.RED
drawFun(startX + INGAME.world.width * TILE_SIZEF, startY)
}
// else if (WorldCamera.x <= offendingPad2 && startX > offendingPad) {
// drawFun(startX - INGAME.world.width * TILE_SIZEF, startY)
// }
else if (WorldCamera.x <= offendingPad2 && startX > offendingPad) {
// App.batch.color = Color.BLUE
drawFun(startX - INGAME.world.width * TILE_SIZEF, startY)
}
else {
// App.batch.color = Color.WHITE
drawFun(startX , startY)
}
}

View File

@@ -64,7 +64,6 @@ class WireActor : ActorWithBody {
}
}
sprite!!.currentFrame = ret
sprite!!.flipVertical = true // turns out the sprites are rendered upside-down by default :(
}
private fun getNearbyTilesPos(x: Int, y: Int): Array<Point2i> {

View File

@@ -737,6 +737,7 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
private var worldWidth: Double = 0.0
private var oldCamX = 0
private var oldPlayerX = 0.0
/**
* Ingame (world) related updates; UI update must go to renderGame()
@@ -798,17 +799,19 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
BlockStats.update()
}
// fill up visibleActorsRenderFront for wires, if:
// 0. Camera wrapped
// 0. Camera or player x position wrapped
// 1. new world has been loaded
// 2. something is cued on the wire change queue
// 3. wire renderclass changed
if (Math.abs(WorldCamera.x - oldCamX) >= worldWidth * 0.85 ||
if (Math.abs(WorldCamera.x - oldCamX) >= worldWidth * 0.5 ||
Math.abs((actorNowPlaying?.hitbox?.canonicalX ?: 0.0) - oldPlayerX) >= worldWidth * 0.5 ||
newWorldLoadedLatch || wireChangeQueue.isNotEmpty() || selectedWireRenderClass != oldSelectedWireRenderClass) {
measureDebugTime("Ingame.FillUpWiresBuffer") {
fillUpWiresBuffer()
}
}
oldCamX = WorldCamera.x
oldPlayerX = actorNowPlaying?.hitbox?.canonicalX ?: 0.0
WORLD_UPDATE_TIMER += 1

View File

@@ -1,6 +1,7 @@
package net.torvald.terrarum.modulebasegame.gameactors
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.jme3.math.FastMath
import net.torvald.gdx.graphics.Cvec
import net.torvald.spriteanimation.HasAssembledSprite
@@ -655,6 +656,13 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L
}
}
override fun getSpriteHead(): TextureRegion? {
return if (this is IngamePlayer)
this.spriteHeadTexture
else if (this is HasAssembledSprite)
this.spriteHeadTexture
else super.getSpriteHead()
}
fun Float.abs() = FastMath.abs(this)

View File

@@ -2,6 +2,7 @@ package net.torvald.terrarum.modulebasegame.gameactors
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.TextureRegion
import net.torvald.spriteanimation.SpriteAnimation
import net.torvald.spriteassembler.ADProperties
import net.torvald.spriteassembler.AssembleSheetPixmap
@@ -29,6 +30,9 @@ class IngamePlayer : ActorHumanoid {
val uuid = UUID.randomUUID()
var worldCurrentlyPlaying: UUID = UUID(0L,0L) // only filled up on save and load; DO NOT USE THIS
var spriteHeadTexture: TextureRegion? = null
/** ADL for main sprite. Necessary. */
@Transient var animDesc: ADProperties? = null
/** ADL for glow sprite. Optional. */
@@ -79,15 +83,24 @@ class IngamePlayer : ActorHumanoid {
* ```
*/
fun reassembleSprite(sprite: SpriteAnimation?, spriteGlow: SpriteAnimation? = null) {
if (animDesc != null && sprite != null)
if (animDesc != null && sprite != null) {
_rebuild(animDesc!!, sprite)
spriteHeadTexture = AssembleSheetPixmap.getHeadFromAssetsDir(animDesc!!)
}
if (animDescGlow != null && spriteGlow != null)
_rebuild(animDescGlow!!, spriteGlow)
}
fun reassembleSprite(disk: SimpleFileSystem, sprite: SpriteAnimation?, spriteGlow: SpriteAnimation? = null) {
if (animDesc != null && sprite != null)
if (animDesc != null && sprite != null) {
_rebuild(disk, -1025L, animDesc!!, sprite)
if (disk.getEntry(-1025L) != null)
spriteHeadTexture = AssembleSheetPixmap.getHeadFromVirtualDisk(disk, -1025L, animDesc!!)
else
spriteHeadTexture = AssembleSheetPixmap.getHeadFromAssetsDir(animDesc!!)
}
if (animDescGlow != null && spriteGlow != null)
_rebuild(disk, -1026L, animDescGlow!!, spriteGlow)
}
@@ -140,5 +153,7 @@ class IngamePlayer : ActorHumanoid {
sprite.nRows = newAnimDelays.size
}
override fun getSpriteHead(): TextureRegion? {
return spriteHeadTexture
}
}

View File

@@ -7,10 +7,10 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.glutils.FrameBuffer
import com.badlogic.gdx.utils.GdxRuntimeException
import net.torvald.terrarum.*
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
import net.torvald.terrarum.blockstats.MinimapComposer
import net.torvald.terrarum.blockstats.MinimapComposer.MINIMAP_TILE_HEIGHT
import net.torvald.terrarum.blockstats.MinimapComposer.MINIMAP_TILE_WIDTH
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVENTORY_CELLS_OFFSET_Y
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVENTORY_CELLS_UI_HEIGHT
import net.torvald.terrarum.ui.Toolkit
@@ -155,6 +155,11 @@ class UIInventoryMinimap(val full: UIInventoryFull) : UICanvas() {
batch.color = Color.WHITE
batch.draw(renderTextures[index], tx, ty, MINIMAP_TILE_WIDTH * minimapZoom, MINIMAP_TILE_HEIGHT * minimapZoom)
}
((INGAME.actorContainerInactive + INGAME.actorContainerActive).filter { it is IngamePlayer } as List<IngamePlayer>).forEach {
// it.getSpriteHead()
}
}
}
batch.begin()

View File

@@ -129,6 +129,13 @@ class ConsoleWindow : UICanvas() {
}
uiItems.forEach { it.render(batch, camera) }
Terrarum.ingame?.let {
batch.color = Color.WHITE
it.actorNowPlaying?.getSpriteHead()!!.let {
batch.draw(it, drawOffX + 10f, drawOffY + height + 4f)
}
}
}
override fun inputStrobed(e: TerrarumKeyboardEvent) {
@@ -279,15 +286,15 @@ class ConsoleWindow : UICanvas() {
}
override fun endClosing(delta: Float) {
Terrarum.ingame?.setTooltipMessage(null)
println("Close -- I made the game to pause: $iMadeTheGameToPause")
if (iMadeTheGameToPause) {
Terrarum.ingame?.resume()
println("Close -- resume game")
}
iMadeTheGameToPause = false
Terrarum.ingame?.setTooltipMessage(null)
drawOffY = -height.toFloat()
openingTimeCounter = 0f
iMadeTheGameToPause = false
}
override fun dispose() {