diff --git a/assets/mods/basegame/sprites/test_sprite.properties b/assets/mods/basegame/sprites/test_sprite.properties new file mode 100644 index 000000000..b1380bc7c --- /dev/null +++ b/assets/mods/basegame/sprites/test_sprite.properties @@ -0,0 +1,35 @@ +# complete file name is: SPRITESHEET + bodypart name + EXTENSION +SPRITESHEET=mods/basegame/sprites/sprite_assembler_test_assets/test_ +EXTENSION=.tga +# defines frame size and origin point. Origin point is given as: (originx, size.y - 1) +CONFIG=SIZE 48,56;ORIGINX 29 + +# note to self: don't implement skeleton hierarchy: there's too many exceptions +# besides, you have "ALL" key. + +! a skeleton also defines what body parts (images) be used. +! you can also write multiline text using reverse solidus; this is a feature of .properties +! skeleton joints are ordered: foremost-drawn object comes first, which means lowermost object IN THIS LIST +! are painted first, and any object that comes before it will paint over it. In other words, this list is +! first reversed then being iterated. +! Joints' original point is defined in the document sprite_joints.psd. It also has visual representations. +# TODO right now accessory points are explicitly defined. Should they be injected in run-time? +SKELETON_STAND=HEADGEAR 0,32;HAIR_FORE 0,32;\ + ARM_REST_RIGHT -7,23;HAND_REST_RIGHT -6,11;HELD_ITEM -6,11;\ + HAIR 0,32;HEAD 0,32;\ + UPPER_TORSO 0,23;LOWER_TORSO 0,15;\ + FOOT_RIGHT -2,2;LEG_REST_RIGHT -2,7;\ + FOOT_LEFT 2,2;LEG_REST_LEFT 2,7;\ + ARM_REST_LEFT 5,24;HAND_REST_LEFT 6,12 + +# skeleton_stand is used for testing purpose +ANIM_RUN=DELAY 0.15;ROW 2;SKELETON SKELETON_STAND +ANIM_RUN_1=LEG_REST_RIGHT 1,1;FOOT_RIGHT 1,1;LEG_REST_LEFT -1,0;FOOT_LEFT -1,0 +ANIM_RUN_2=ALL 0,1;LEG_REST_RIGHT 0,-1;FOOT_RIGHT 0,-1;LEG_REST_LEFT 0,1;FOOT_LEFT 0,1 +ANIM_RUN_3=LEG_REST_RIGHT -1,0;FOOT_RIGHT -1,0;LEG_REST_LEFT 1,1;FOOT_LEFT 1,1 +ANIM_RUN_4=ALL 0,1;LEG_REST_RIGHT 0,1;FOOT_RIGHT 0,1;LEG_REST_LEFT 0,-1;FOOT_LEFT 0,-1 + +ANIM_IDLE=DELAY 2;ROW 1;SKELETON SKELETON_STAND +ANIM_IDLE_1= +! ANIM_IDLE_1 will not make any transformation +ANIM_IDLE_2=UPPER_TORSO 0,-1;HEAD 0,-1;HAIR 0,-1;HELD_ITEM 0,-1;ARM_REST_LEFT 0,-1;ARM_REST_RIGHT 0,-1;HAND_REST_LEFT 0,-1;HAND_REST_RIGHT 0,-1;HAIR_FORE 0,-1;HEADGEAR 0,-1 diff --git a/src/net/torvald/spriteanimation/Animatable.kt b/src/net/torvald/spriteanimation/Animatable.kt new file mode 100644 index 000000000..0335b8291 --- /dev/null +++ b/src/net/torvald/spriteanimation/Animatable.kt @@ -0,0 +1,59 @@ +package net.torvald.spriteanimation + +import com.badlogic.gdx.files.FileHandle +import com.badlogic.gdx.graphics.Texture +import net.torvald.spriteassembler.ADProperties +import net.torvald.spriteassembler.AssembleSheetPixmap +import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack + +/** + * Created by minjaesong on 2019-01-18. + */ +interface HasAssembledSprite { + + var animDesc: FileHandle + + // FIXME sometimes the animmation is invisible (row and nFrames mismatch -- row is changed to 1 but it's drawing 3rd frame?) + + fun reassembleSprite(sprite: SpriteAnimation) { + _rebuild(ADProperties(animDesc.read()), sprite) + } + + /*fun rebuild(animDesc: String, spriteAnimation: SpriteAnimation) { + _rebuild(ADProperties(StringReader(animDesc)), spriteAnimation) + } + + fun rebuild(animDesc: FileHandle, spriteAnimation: SpriteAnimation) { + _rebuild(ADProperties(animDesc.read()), spriteAnimation) + } + + fun rebuild(javaProp: Properties, spriteAnimation: SpriteAnimation) { + _rebuild(ADProperties(javaProp), spriteAnimation) + }*/ + + + private fun _rebuild(ad: ADProperties, sprite: SpriteAnimation) { + // TODO injecting held item/armour pictures? Would it be AssembleSheetPixmap's job? + + val pixmap = AssembleSheetPixmap(ad) + val texture = Texture(pixmap) + texture.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) + pixmap.dispose() + val regionPack = TextureRegionPack(texture, ad.frameWidth, ad.frameHeight) + + val newAnimDelays = FloatArray(ad.animations.size) + val newAnimFrames = IntArray(ad.animations.size) + + ad.animations.forEach { t, u -> + val index = u.row - 1 + newAnimDelays[index] = u.delay + newAnimFrames[index] = u.frames + } + + sprite.setSpriteImage(regionPack) + sprite.delays = newAnimDelays + sprite.nFrames = newAnimFrames + sprite.nRows = newAnimDelays.size + } + +} diff --git a/src/net/torvald/spriteanimation/SpriteAnimation.kt b/src/net/torvald/spriteanimation/SpriteAnimation.kt index 0c71f29fc..dcff2188e 100644 --- a/src/net/torvald/spriteanimation/SpriteAnimation.kt +++ b/src/net/torvald/spriteanimation/SpriteAnimation.kt @@ -18,10 +18,10 @@ class SpriteAnimation(val parentActor: ActorWBMovable) { var currentFrame = 0 var currentRow = 0 - var nFrames: Int = 1 - private set + var nFrames: IntArray = intArrayOf(1) + internal set var nRows: Int = 1 - private set + internal set private val currentDelay: Second get() = delays[currentRow] @@ -71,7 +71,15 @@ class SpriteAnimation(val parentActor: ActorWBMovable) { */ fun setRowsAndFrames(nRows: Int, nFrames: Int) { this.nRows = nRows - this.nFrames = nFrames + this.nFrames = IntArray(nRows) { nFrames } + } + + fun setFramesOf(row: Int, frameCount: Int) { + nFrames[row] = frameCount + } + + fun setFramesCount(framesCount: IntArray) { + nFrames = framesCount } fun update(delta: Float) { @@ -85,9 +93,9 @@ class SpriteAnimation(val parentActor: ActorWBMovable) { while (this.delta >= currentDelay) { // advance frame if (looping) { // looping, wrap around - currentFrame = (currentFrame + 1) % nFrames + currentFrame = (currentFrame + 1) % nFrames[currentRow] } - else if (currentFrame < nFrames - 1) { // not looping and haven't reached the end + else if (currentFrame < nFrames[currentRow] - 1) { // not looping and haven't reached the end currentFrame += 1 } @@ -110,7 +118,7 @@ class SpriteAnimation(val parentActor: ActorWBMovable) { * * * @param scale */ - @JvmOverloads fun render(batch: SpriteBatch, posX: Float, posY: Float, scale: Float = 1f) { + fun render(batch: SpriteBatch, posX: Float, posY: Float, scale: Float = 1f) { if (cellWidth == 0 || cellHeight == 0) { throw Error("Sprite width or height is set to zero! ($cellWidth, $cellHeight); master: $parentActor") } @@ -158,7 +166,7 @@ class SpriteAnimation(val parentActor: ActorWBMovable) { currentRow = newRow % nRows //if beyond the frame index then reset - if (currentFrame > nFrames) { + if (currentFrame > nFrames[currentRow]) { reset() } } diff --git a/src/net/torvald/spriteassembler/ADProperties.kt b/src/net/torvald/spriteassembler/ADProperties.kt index b7c06e27e..78b20a73f 100644 --- a/src/net/torvald/spriteassembler/ADProperties.kt +++ b/src/net/torvald/spriteassembler/ADProperties.kt @@ -15,6 +15,13 @@ data class Skeleton(val name: String, val joints: List) { override fun toString() = "$name=$joints" } +/** + * @param name You know it + * @param delay Delay between each frame in seconds + * @param row STARTS AT ONE! Row in the final spritesheet, also act as the animation index. + * @param frames number of frames this animation has + * @param skeleton list of joints to be transformed + */ data class Animation(val name: String, val delay: Float, val row: Int, val frames: Int, val skeleton: Skeleton) { override fun toString() = "$name delay: $delay, row: $row, frames: $frames, skeleton: ${skeleton.name}" } @@ -45,6 +52,12 @@ class ADProperties { lateinit var baseFilename: String; private set lateinit var extension: String; private set + var frameWidth: Int = -1; private set + var frameHeight: Int = -1; private set + var originX: Int = -1; private set + var originY: Int = -1; private set + val origin: ADPropertyObject.Vector2i + get() = ADPropertyObject.Vector2i(originX, originY) private val animFrameSuffixRegex = Regex("""_[0-9]+""") @@ -67,6 +80,10 @@ class ADProperties { continueLoad() } + constructor(javaProp: Properties) { + this.javaProp.putAll(javaProp.toMap()) + } + private fun continueLoad() { javaProp.keys.forEach { propName -> val propsStr = javaProp.getProperty(propName as String) @@ -76,8 +93,13 @@ class ADProperties { } // set reserved values for the animation: filename, extension - baseFilename = get("SPRITESHEET")[0].variable - extension = get("EXTENSION")[0].variable + baseFilename = get("SPRITESHEET")[0].name + extension = get("EXTENSION")[0].name + val frameSizeVec = get("CONFIG").linearSearchBy { it.name == "SIZE" }!!.input as ADPropertyObject.Vector2i + frameWidth = frameSizeVec.x + frameHeight = frameSizeVec.y + originX = (get("CONFIG").linearSearchBy { it.name == "ORIGINX" }!!.input as Float).toInt() + originY = frameHeight - 1 var maxColFinder = -1 var maxRowFinder = -1 @@ -110,7 +132,7 @@ class ADProperties { // and thus, uses whatever the "input" used by the SKELETON is a skeleton val propsHashMap = HashMap() list.forEach { - propsHashMap[it.variable.toUpperCase()] = it.input + propsHashMap[it.name.toUpperCase()] = it.input } // if it is indeed anim, populate animations list @@ -144,11 +166,11 @@ class ADProperties { val frameName = "${t}_$fc" val prop = get(frameName) - var emptyList = prop.size == 1 && prop[0].variable.isEmpty() + var emptyList = prop.size == 1 && prop[0].name.isEmpty() val transformList = if (!emptyList) { List(prop.size) { index -> - val jointNameToSearch = prop[index].variable.toUpperCase() + val jointNameToSearch = prop[index].name.toUpperCase() val joint = if (jointNameToSearch == "ALL") ALL_JOINT else @@ -196,7 +218,7 @@ class ADProperties { private fun getAnimNameFromFrame(s: String) = s.substring(0 until s.lastIndexOf('_')) private fun List.toJoints() = List(this.size) { - Joint(this[it].variable.toUpperCase(), this[it].input!! as ADPropertyObject.Vector2i) + Joint(this[it].name.toUpperCase(), this[it].input!! as ADPropertyObject.Vector2i) } } @@ -211,7 +233,7 @@ class ADProperties { class ADPropertyObject(propertyRaw: String) { /** If the input is like ```UPPER_TORSO``` (that is, not a variable-input pair), this holds the string UPPER_TORSO. */ - val variable: String + val name: String val input: Any? get() = when (type) { ADPropertyType.IVEC2 -> field!! as Vector2i @@ -226,7 +248,7 @@ class ADPropertyObject(propertyRaw: String) { val propPair = propertyRaw.split(variableInputSepRegex) if (isADvariable(propertyRaw)) { - variable = propPair[0] + name = propPair[0] val inputStr = propPair[1] if (isADivec2(inputStr)) { @@ -243,7 +265,7 @@ class ADPropertyObject(propertyRaw: String) { } } else { - variable = propertyRaw + name = propertyRaw input = null type = ADPropertyType.NAME_ONLY } @@ -287,6 +309,6 @@ class ADPropertyObject(propertyRaw: String) { } override fun toString(): String { - return "$variable ${input ?: ""}: ${type.toString().toLowerCase()}" + return "$name ${input ?: ""}: ${type.toString().toLowerCase()}" } } \ No newline at end of file diff --git a/src/net/torvald/spriteassembler/ANIMATION_DESCRIPTION_LANGUAGE.md b/src/net/torvald/spriteassembler/ANIMATION_DESCRIPTION_LANGUAGE.md index b7d3e597c..6084cc07a 100644 --- a/src/net/torvald/spriteassembler/ANIMATION_DESCRIPTION_LANGUAGE.md +++ b/src/net/torvald/spriteassembler/ANIMATION_DESCRIPTION_LANGUAGE.md @@ -86,6 +86,7 @@ These values must exist so that the file can be parsed successfully. |---|---|---| |SPRITESHEET|properties: NAME_ONLY|Base file name of the images| |EXTENSION|properties: NAME_ONLY|Extension of the base file| +|CONFIG|properties: 2 variables|Frame size and origin-x position, 0 being left| #### Animation diff --git a/src/net/torvald/spriteassembler/AssembleFrameGdx.kt b/src/net/torvald/spriteassembler/AssembleFrameGdx.kt index e140fb00b..3c7bfcc26 100644 --- a/src/net/torvald/spriteassembler/AssembleFrameGdx.kt +++ b/src/net/torvald/spriteassembler/AssembleFrameGdx.kt @@ -15,14 +15,14 @@ import java.io.File */ object AssembleSheetPixmap { - operator fun invoke(properties: ADProperties, assembleConfig: AssembleConfig = AssembleConfig()): Pixmap { - val canvas = Pixmap(properties.cols * assembleConfig.fw, properties.rows * assembleConfig.fh, Pixmap.Format.RGBA8888) + operator fun invoke(properties: ADProperties): Pixmap { + val canvas = Pixmap(properties.cols * properties.frameWidth, properties.rows * properties.frameHeight, Pixmap.Format.RGBA8888) canvas.blending = Pixmap.Blending.SourceOver // actually draw properties.transforms.forEach { t, _ -> - drawThisFrame(t, canvas, properties, assembleConfig) + drawThisFrame(t, canvas, properties) } return canvas @@ -30,8 +30,7 @@ object AssembleSheetPixmap { private fun drawThisFrame(frameName: String, canvas: Pixmap, - properties: ADProperties, - assembleConfig: AssembleConfig + properties: ADProperties ) { val theAnim = properties.getAnimByFrameName(frameName) val skeleton = theAnim.skeleton.joints.reversed() @@ -56,23 +55,23 @@ object AssembleSheetPixmap { AppLoader.printdbg(this, "Frame to draw: $frameName (R$animRow C$animFrame)") - drawFrame(animRow, animFrame, canvas, bodyparts, transformList, assembleConfig) + drawFrame(animRow, animFrame, canvas, properties, bodyparts, transformList) bodyparts.forEach { it?.dispose() } } private fun drawFrame(row: Int, column: Int, canvas: Pixmap, + props: ADProperties, bodyparts: Array, - transformList: List>, - assembleConfig: AssembleConfig + transformList: List> ) { - val tmpFrame = Pixmap(assembleConfig.fw, assembleConfig.fh, Pixmap.Format.RGBA8888) + val tmpFrame = Pixmap(props.frameWidth, props.frameHeight, Pixmap.Format.RGBA8888) bodyparts.forEachIndexed { index, image -> if (image != null) { val imgCentre = AssembleFrameBase.getCentreOf(image) - val drawPos = transformList[index].second.invertY() + assembleConfig.origin - imgCentre + val drawPos = transformList[index].second.invertY() + props.origin - imgCentre tmpFrame.drawPixmap(image, drawPos.x, drawPos.y) } @@ -80,8 +79,8 @@ object AssembleSheetPixmap { canvas.drawPixmap( tmpFrame, - (column - 1) * assembleConfig.fw, - (row - 1) * assembleConfig.fh + (column - 1) * props.frameWidth, + (row - 1) * props.frameHeight ) tmpFrame.dispose() @@ -90,13 +89,6 @@ object AssembleSheetPixmap { } -/** - * @param fw Frame Width - * @param fh Frame Height - * @param origin Int vector of origin point, (0,0) being TOP-LEFT - */ -data class AssembleConfig(val fw: Int = 48, val fh: Int = 56, val origin: ADPropertyObject.Vector2i = ADPropertyObject.Vector2i(29, fh - 1)) - object AssembleFrameBase { /** * Returns joints list with tranform applied. diff --git a/src/net/torvald/spriteassembler/SpriteAssemblerApp.kt b/src/net/torvald/spriteassembler/SpriteAssemblerApp.kt index 1513df663..2bf91a04c 100644 --- a/src/net/torvald/spriteassembler/SpriteAssemblerApp.kt +++ b/src/net/torvald/spriteassembler/SpriteAssemblerApp.kt @@ -94,7 +94,7 @@ class SpriteAssemblerApp(val gdxWindow: SpriteAssemblerPreview) : JFrame() { } - panelCode.font = Font(Font.MONOSPACED, Font.PLAIN, 11) + panelCode.font = Font(Font.MONOSPACED, Font.PLAIN, 12) panelAnimationsList.model = DefaultListModel() panelBodypartsList.model = DefaultListModel() @@ -172,6 +172,8 @@ class SpriteAssemblerApp(val gdxWindow: SpriteAssemblerPreview) : JFrame() { // populate stats (panelStatList.model as DefaultListModel).addElement("Spritesheet rows: ${adProperties.rows}") (panelStatList.model as DefaultListModel).addElement("Spritesheet columns: ${adProperties.cols}") + (panelStatList.model as DefaultListModel).addElement("Frame size: ${adProperties.frameWidth}, ${adProperties.frameHeight}") + (panelStatList.model as DefaultListModel).addElement("Origin position: ${adProperties.originX}, ${adProperties.originY}") } catch (fehler: Throwable) { displayError("ERROR_PARSE_FAIL", fehler) @@ -289,6 +291,7 @@ class SpriteAssemblerPreview: Game() { image = AssembleSheetPixmap(prop) } + // TODO rename to requestAssembly fun requestAssemblyTest(prop: ADProperties) { doAssemble = true assembleProp = prop diff --git a/src/net/torvald/spriteassembler/test_sprite.properties b/src/net/torvald/spriteassembler/test_sprite.properties index 86bf9349a..b1380bc7c 100644 --- a/src/net/torvald/spriteassembler/test_sprite.properties +++ b/src/net/torvald/spriteassembler/test_sprite.properties @@ -1,5 +1,8 @@ +# complete file name is: SPRITESHEET + bodypart name + EXTENSION SPRITESHEET=mods/basegame/sprites/sprite_assembler_test_assets/test_ EXTENSION=.tga +# defines frame size and origin point. Origin point is given as: (originx, size.y - 1) +CONFIG=SIZE 48,56;ORIGINX 29 # note to self: don't implement skeleton hierarchy: there's too many exceptions # besides, you have "ALL" key. @@ -29,5 +32,4 @@ ANIM_RUN_4=ALL 0,1;LEG_REST_RIGHT 0,1;FOOT_RIGHT 0,1;LEG_REST_LEFT 0,-1;FOOT_LEF ANIM_IDLE=DELAY 2;ROW 1;SKELETON SKELETON_STAND ANIM_IDLE_1= ! ANIM_IDLE_1 will not make any transformation -ANIM_IDLE_2=UPPER_TORSO 0,-1;HEAD 0,-1;HAIR 0,-1;HELD_ITEM 0,-1;ARM_REST_LEFT 0,-1;ARM_REST_RIGHT 0,-1;HAIR_FORE 0,-1;HEADGEAR 0,-1 -! HAND_REST is deliberately left out -- it's bit unsettling to see held item keeps moving +ANIM_IDLE_2=UPPER_TORSO 0,-1;HEAD 0,-1;HAIR 0,-1;HELD_ITEM 0,-1;ARM_REST_LEFT 0,-1;ARM_REST_RIGHT 0,-1;HAND_REST_LEFT 0,-1;HAND_REST_RIGHT 0,-1;HAIR_FORE 0,-1;HEADGEAR 0,-1 diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index bdaf02f59..2de79207c 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -86,7 +86,7 @@ object Terrarum : Screen { */ val TARGET_INTERNAL_FPS: Double = 60.0 - internal val UPDATE_CATCHUP_MAX_TRIES = 2 // this feature does more harm than good... + internal val UPDATE_CATCHUP_MAX_TRIES = 1 // this feature does more harm than good... @@ -98,9 +98,9 @@ object Terrarum : Screen { var ingame: IngameInstance? = null - private val javaHeapCircularArray = CircularArray(128) - private val nativeHeapCircularArray = CircularArray(128) - private val updateRateCircularArray = CircularArray(128) + private val javaHeapCircularArray = CircularArray(64) + private val nativeHeapCircularArray = CircularArray(64) + private val updateRateCircularArray = CircularArray(16) val memJavaHeap: Int get() { diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorHumanoid.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorHumanoid.kt index e2d0aacca..afc170f4c 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorHumanoid.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorHumanoid.kt @@ -3,6 +3,7 @@ package net.torvald.terrarum.modulebasegame.gameactors import com.badlogic.gdx.Gdx import com.badlogic.gdx.graphics.Color import com.jme3.math.FastMath +import net.torvald.spriteanimation.HasAssembledSprite import net.torvald.terrarum.* import net.torvald.terrarum.gameactors.* import net.torvald.terrarum.gameactors.faction.Faction @@ -21,6 +22,11 @@ import java.util.* * Humanoid actor class to provide same controlling function (such as work, jump) * Also applies unreal air friction for movement control * + * For some actors that "HasAssembledSprite", sprite rows must be in this specific order: + * 1. Idle + * 2. Walk + * ... + * * Created by minjaesong on 2016-10-24. */ open class ActorHumanoid( @@ -610,8 +616,11 @@ open class ActorHumanoid( // set anim frame delay // 4f of the divider is a magic number, empirically decided - sprite?.delays?.set(SPRITE_ROW_WALK, scale.sqrt().toFloat() / (4f * (controllerMoveDelta?.x ?: 0.0001).abs().toFloat())) // FIXME empirical value - spriteGlow?.delays?.set(SPRITE_ROW_WALK, scale.sqrt().toFloat() / (4f * (controllerMoveDelta?.x ?: 0.0001).abs().toFloat())) // FIXME empirical value + if (this is HasAssembledSprite) { + sprite?.delays?.set(SPRITE_ROW_WALK, scale.sqrt().toFloat() / (4f * (controllerMoveDelta?.x ?: 0.0001).abs().toFloat())) // FIXME empirical value + spriteGlow?.delays?.set(SPRITE_ROW_WALK, scale.sqrt().toFloat() / (4f * (controllerMoveDelta?.x ?: 0.0001).abs().toFloat())) // FIXME empirical value + + } // flipping the sprite if (walkHeading == LEFT) { diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/IngamePlayer.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/IngamePlayer.kt index 66ec76c9a..6a292c18a 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/IngamePlayer.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/IngamePlayer.kt @@ -1,7 +1,8 @@ package net.torvald.terrarum.modulebasegame.gameactors +import com.badlogic.gdx.files.FileHandle +import net.torvald.spriteanimation.HasAssembledSprite import net.torvald.terrarum.Terrarum -import net.torvald.terrarum.modulebasegame.gameworld.GameWorldExtension import net.torvald.terrarum.modulebasegame.gameworld.time_t @@ -11,7 +12,7 @@ import net.torvald.terrarum.modulebasegame.gameworld.time_t * Created by minjaesong on 2015-12-31. */ -class IngamePlayer(born: time_t) : ActorHumanoid(born) { +class IngamePlayer(override var animDesc: FileHandle, born: time_t) : ActorHumanoid(born), HasAssembledSprite { /** * Creates new Player instance with empty elements (sprites, actorvalue, etc.). diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilder.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilder.kt index 0d39baf05..0cc1c676f 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilder.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilder.kt @@ -1,5 +1,6 @@ package net.torvald.terrarum.modulebasegame.gameactors +import com.badlogic.gdx.Gdx import net.torvald.terrarum.Terrarum import net.torvald.terrarum.gameactors.AVKey import net.torvald.terrarum.gameactors.Actor @@ -13,7 +14,7 @@ object PlayerBuilder { operator fun invoke(): Actor { val world = (Terrarum.ingame!! as Ingame).gameworld - val p: Actor = IngamePlayer(world.time.TIME_T) + val p: Actor = IngamePlayer(Gdx.files.internal("lol"), world.time.TIME_T) InjectCreatureRaw(p.actorValue, "basegame", "CreatureHuman.json") // attach sprite diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderSigrid.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderSigrid.kt index 72fded274..8f14bd6d3 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderSigrid.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderSigrid.kt @@ -1,5 +1,6 @@ package net.torvald.terrarum.modulebasegame.gameactors +import com.badlogic.gdx.Gdx import net.torvald.terrarum.ModMgr import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.gameactors.AVKey @@ -14,7 +15,7 @@ import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack object PlayerBuilderSigrid { operator fun invoke(): IngamePlayer { - val p = IngamePlayer(-9223372036854775807L) // XD + val p = IngamePlayer(Gdx.files.internal("lol"), - 9223372036854775807L) // XD p.referenceID = 0x51621D // the only constant of this procedural universe diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderTestSubject1.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderTestSubject1.kt index 1606cf0dc..e5b624804 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderTestSubject1.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderTestSubject1.kt @@ -1,16 +1,16 @@ package net.torvald.terrarum.modulebasegame.gameactors +import net.torvald.spriteanimation.SpriteAnimation import net.torvald.terrarum.ModMgr import net.torvald.terrarum.gameactors.AVKey import net.torvald.terrarum.worlddrawer.FeaturesDrawer -import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack /** * Created by minjaesong on 2017-02-10. */ object PlayerBuilderTestSubject1 { operator fun invoke(): IngamePlayer { - val p: IngamePlayer = IngamePlayer(-589141658L) // random value thrown + val p: IngamePlayer = IngamePlayer(ModMgr.getGdxFile("basegame", "sprites/test_sprite.properties"), -589141658L) // random value thrown InjectCreatureRaw(p.actorValue, "basegame", "CreatureHuman.json") @@ -20,10 +20,12 @@ object PlayerBuilderTestSubject1 { p.actorValue[AVKey.NAME] = "Test Subject 1" - p.makeNewSprite(TextureRegionPack(ModMgr.getGdxFile("basegame", "sprites/npc_template_anim_prototype.tga"), 48, 52)) + /*p.makeNewSprite(TextureRegionPack(ModMgr.getGdxFile("basegame", "sprites/npc_template_anim_prototype.tga"), 48, 52)) p.sprite!!.delays = floatArrayOf(2f, 1f/12f) // second value does nothing -- overridden by ActorHumanoid.updateSprite(float) - p.sprite!!.setRowsAndFrames(2, 4) + p.sprite!!.setRowsAndFrames(2, 4)*/ + p.sprite = SpriteAnimation(p) + p.reassembleSprite(p.sprite!!) p.setHitboxDimension(15, p.actorValue.getAsInt(AVKey.BASEHEIGHT) ?: ActorHumanoid.BASE_HEIGHT, 21, 0) p.setPosition(3.0 * FeaturesDrawer.TILE_SIZE, 3.0 * FeaturesDrawer.TILE_SIZE) diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryEquippedView.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryEquippedView.kt index 2c571dd0a..16c869adc 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryEquippedView.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryEquippedView.kt @@ -4,10 +4,10 @@ import com.badlogic.gdx.graphics.Camera import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.g2d.SpriteBatch import net.torvald.terrarum.* -import net.torvald.terrarum.modulebasegame.gameactors.ActorInventory import net.torvald.terrarum.gameactors.ActorWBMovable import net.torvald.terrarum.itemproperties.GameItem import net.torvald.terrarum.itemproperties.ItemCodex +import net.torvald.terrarum.modulebasegame.gameactors.ActorInventory import net.torvald.terrarum.ui.UIItem /** @@ -39,8 +39,7 @@ class UIItemInventoryEquippedView( val spriteViewBackCol: Color; get() = Color(0x404040_88.toInt())//Color(0xd4d4d4_ff.toInt()) - private val itemGrid = Array( - 2 * 5, { + private val itemGrid = Array(2 * 5) { UIItemInventoryElemSimple( parentUI = parentUI, posX = this.posX + (UIItemInventoryElemSimple.height + listGap) * ((it + 4) % 2), @@ -55,7 +54,6 @@ class UIItemInventoryEquippedView( drawBackOnNull = true ) } - ) override fun update(delta: Float) { diff --git a/src/net/torvald/terrarum/tests/MakeKeylayoutFile.kt b/src/net/torvald/terrarum/tests/MakeKeylayoutFile.kt new file mode 100644 index 000000000..e498077fd --- /dev/null +++ b/src/net/torvald/terrarum/tests/MakeKeylayoutFile.kt @@ -0,0 +1,145 @@ + +import com.badlogic.gdx.* +import com.badlogic.gdx.Input.Keys.* +import com.badlogic.gdx.backends.lwjgl.LwjglApplication +import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration +import com.badlogic.gdx.graphics.g2d.BitmapFont +import com.badlogic.gdx.graphics.g2d.SpriteBatch +import net.torvald.terrarum.gdxClearAndSetBlend +import net.torvald.terrarum.inUse + +/** + * Not meant to implement IME, just to be used with Options > Config + * where it shows a "summary" diagram of a keyboard and icon for functions on its keycap + * + * If unknown key was chosen (e.g. caret used on french AZERTY), config will simply won't display it + * on the "summary". + */ +object MakeKeylayoutFile { + + fun invoke() { + val qwerty = arrayOf( // QWERTY + intArrayOf(TAB,Q,W,E,R,T,Y,U,I,O,P,LEFT_BRACKET,RIGHT_BRACKET,BACKSLASH), + intArrayOf(UNKNOWN,A,S,D,F,G,H,J,K,L,SEMICOLON,APOSTROPHE), + intArrayOf(SHIFT_LEFT,Z,X,C,V,B,N,M,COMMA,PERIOD,SLASH,SHIFT_RIGHT), + intArrayOf(SPACE) + ) + val qwerty_hhk = arrayOf( // QWERTY HHK + intArrayOf(TAB,Q,W,E,R,T,Y,U,I,O,P,LEFT_BRACKET,RIGHT_BRACKET,BACKSLASH), + intArrayOf(CONTROL_LEFT,A,S,D,F,G,H,J,K,L,SEMICOLON,APOSTROPHE), + intArrayOf(SHIFT_LEFT,Z,X,C,V,B,N,M,COMMA,PERIOD,SLASH,SHIFT_RIGHT), + intArrayOf(SPACE) + ) + val qwertz = arrayOf( // QWERTZ English + intArrayOf(TAB,Q,W,E,R,T,Z,U,I,O,P,LEFT_BRACKET,RIGHT_BRACKET,BACKSLASH), + intArrayOf(UNKNOWN,A,S,D,F,G,H,J,K,L,SEMICOLON,APOSTROPHE), + intArrayOf(SHIFT_LEFT,Y,X,C,V,B,N,M,COMMA,PERIOD,SLASH,SHIFT_RIGHT), + intArrayOf(SPACE) + ) + val azerty = arrayOf( // AZERTY Windows + intArrayOf(TAB,A,Z,E,R,T,Y,U,I,O,P,72,74,BACKSLASH), + intArrayOf(UNKNOWN,Q,S,D,F,G,H,J,K,L,M,68), + intArrayOf(SHIFT_LEFT,W,X,C,V,B,N,COMMA,PERIOD,SLASH,UNKNOWN,SHIFT_RIGHT), + intArrayOf(SPACE) + ) + val colemak = arrayOf( // Colemak + intArrayOf(TAB,Q,W,F,P,G,J,L,U,Y,SEMICOLON,LEFT_BRACKET,RIGHT_BRACKET,BACKSLASH), + intArrayOf(BACKSPACE,A,R,S,T,D,H,N,E,I,O,APOSTROPHE), + intArrayOf(SHIFT_LEFT,Z,X,C,V,B,K,M,COMMA,PERIOD,SLASH,SHIFT_RIGHT), + intArrayOf(SPACE) + ) + val dvorak = arrayOf( // Dvorak + intArrayOf(TAB,APOSTROPHE,COMMA,PERIOD,P,Y,F,G,C,R,L,SLASH,EQUALS,BACKSLASH), + intArrayOf(UNKNOWN,A,O,E,U,I,D,H,T,N,S,MINUS), + intArrayOf(SHIFT_LEFT,SEMICOLON,Q,J,K,X,B,M,W,V,Z,SHIFT_RIGHT), + intArrayOf(SPACE) + ) + val dvorak_lh = arrayOf( // Dvorak Left handed + intArrayOf(TAB,SEMICOLON,Q,B,Y,U,R,S,O,PERIOD,UNKNOWN,UNKNOWN,EQUALS,BACKSLASH), + intArrayOf(UNKNOWN,MINUS,K,C,D,T,H,E,A,Z,UNKNOWN,UNKNOWN), + intArrayOf(SHIFT_LEFT,APOSTROPHE,X,G,V,W,N,I,COMMA,UNKNOWN,UNKNOWN,SHIFT_RIGHT), + intArrayOf(SPACE) + ) + + + val keys = listOf( + qwerty, qwerty_hhk, qwertz, azerty, colemak, dvorak, dvorak_lh + ) + + keys.forEach { println(it.toConfigStr()) } + } + + private fun Array.toConfigStr() = + this.map { it.joinToString(",") }.joinToString(";") + +} + +class GetKeycode : Game() { + + private lateinit var font: BitmapFont + private lateinit var batch: SpriteBatch + + private var keyHit = "(keycode will be displayed here)" + + override fun create() { + font = BitmapFont() + batch = SpriteBatch() + + Gdx.input.inputProcessor = Con(this) + } + + override fun getScreen(): Screen { + return super.getScreen() + } + + override fun setScreen(screen: Screen?) { + super.setScreen(screen) + } + + override fun render() { + Gdx.graphics.setTitle("Get Keycode — F: ${Gdx.graphics.framesPerSecond}") + + gdxClearAndSetBlend(.1f,.1f,.1f,1f) + + batch.inUse { + font.draw(batch, "Hit a key", 10f, 20f) + font.draw(batch, keyHit, 10f, 42f) + } + } + + override fun pause() { + super.pause() + } + + override fun resume() { + super.resume() + } + + override fun resize(width: Int, height: Int) { + super.resize(width, height) + } + + override fun dispose() { + super.dispose() + } + + class Con(val host: GetKeycode): InputAdapter() { + override fun keyDown(keycode: Int): Boolean { + host.keyHit = "Key down: $keycode (${Input.Keys.toString(keycode)})" + return true + } + } +} + +fun main() {val appConfig = LwjglApplicationConfiguration() + appConfig.resizable = false + appConfig.width = 256 + appConfig.height = 64 + appConfig.foregroundFPS = 60 + appConfig.backgroundFPS = 60 + + val gdxWindow = GetKeycode() + + LwjglApplication(gdxWindow, appConfig) + MakeKeylayoutFile.invoke() +} \ No newline at end of file diff --git a/work_files/UI/options-controls.psd b/work_files/UI/options-controls.psd index 97d5d9533..155120e3d 100644 --- a/work_files/UI/options-controls.psd +++ b/work_files/UI/options-controls.psd @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:20cd4aa8404d5d433e061226cecd5b22d945db5a85d5192585a1680026fbf74c -size 13927736 +oid sha256:97bd33ff7d90c774b686dd5cca5cd3887212ae46276b793b01da6421df4a9e08 +size 14045084 diff --git a/work_files/graphics/fonts/puae000-e0ff.psd b/work_files/graphics/fonts/puae000-e0ff.psd index 87460531b..e5dcb65c2 100644 --- a/work_files/graphics/fonts/puae000-e0ff.psd +++ b/work_files/graphics/fonts/puae000-e0ff.psd @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5b63e86f14ea5d4eddd552c20526eaa245f1f6835f7e78e869ffc3b1f2185b33 -size 146336 +oid sha256:849fb23aa243ccbfc711b0344b042e9d9ac980c7a0c0be4a182902196c4b2aed +size 184676