mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
on-the-fly sprite assembly WIP
This commit is contained in:
35
assets/mods/basegame/sprites/test_sprite.properties
Normal file
35
assets/mods/basegame/sprites/test_sprite.properties
Normal file
@@ -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
|
||||||
59
src/net/torvald/spriteanimation/Animatable.kt
Normal file
59
src/net/torvald/spriteanimation/Animatable.kt
Normal file
@@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -18,10 +18,10 @@ class SpriteAnimation(val parentActor: ActorWBMovable) {
|
|||||||
var currentFrame = 0
|
var currentFrame = 0
|
||||||
var currentRow = 0
|
var currentRow = 0
|
||||||
|
|
||||||
var nFrames: Int = 1
|
var nFrames: IntArray = intArrayOf(1)
|
||||||
private set
|
internal set
|
||||||
var nRows: Int = 1
|
var nRows: Int = 1
|
||||||
private set
|
internal set
|
||||||
|
|
||||||
private val currentDelay: Second
|
private val currentDelay: Second
|
||||||
get() = delays[currentRow]
|
get() = delays[currentRow]
|
||||||
@@ -71,7 +71,15 @@ class SpriteAnimation(val parentActor: ActorWBMovable) {
|
|||||||
*/
|
*/
|
||||||
fun setRowsAndFrames(nRows: Int, nFrames: Int) {
|
fun setRowsAndFrames(nRows: Int, nFrames: Int) {
|
||||||
this.nRows = nRows
|
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) {
|
fun update(delta: Float) {
|
||||||
@@ -85,9 +93,9 @@ class SpriteAnimation(val parentActor: ActorWBMovable) {
|
|||||||
while (this.delta >= currentDelay) {
|
while (this.delta >= currentDelay) {
|
||||||
// advance frame
|
// advance frame
|
||||||
if (looping) { // looping, wrap around
|
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
|
currentFrame += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,7 +118,7 @@ class SpriteAnimation(val parentActor: ActorWBMovable) {
|
|||||||
* *
|
* *
|
||||||
* @param scale
|
* @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) {
|
if (cellWidth == 0 || cellHeight == 0) {
|
||||||
throw Error("Sprite width or height is set to zero! ($cellWidth, $cellHeight); master: $parentActor")
|
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
|
currentRow = newRow % nRows
|
||||||
|
|
||||||
//if beyond the frame index then reset
|
//if beyond the frame index then reset
|
||||||
if (currentFrame > nFrames) {
|
if (currentFrame > nFrames[currentRow]) {
|
||||||
reset()
|
reset()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,13 @@ data class Skeleton(val name: String, val joints: List<Joint>) {
|
|||||||
override fun toString() = "$name=$joints"
|
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) {
|
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}"
|
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 baseFilename: String; private set
|
||||||
lateinit var extension: 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]+""")
|
private val animFrameSuffixRegex = Regex("""_[0-9]+""")
|
||||||
|
|
||||||
@@ -67,6 +80,10 @@ class ADProperties {
|
|||||||
continueLoad()
|
continueLoad()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constructor(javaProp: Properties) {
|
||||||
|
this.javaProp.putAll(javaProp.toMap())
|
||||||
|
}
|
||||||
|
|
||||||
private fun continueLoad() {
|
private fun continueLoad() {
|
||||||
javaProp.keys.forEach { propName ->
|
javaProp.keys.forEach { propName ->
|
||||||
val propsStr = javaProp.getProperty(propName as String)
|
val propsStr = javaProp.getProperty(propName as String)
|
||||||
@@ -76,8 +93,13 @@ class ADProperties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set reserved values for the animation: filename, extension
|
// set reserved values for the animation: filename, extension
|
||||||
baseFilename = get("SPRITESHEET")[0].variable
|
baseFilename = get("SPRITESHEET")[0].name
|
||||||
extension = get("EXTENSION")[0].variable
|
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 maxColFinder = -1
|
||||||
var maxRowFinder = -1
|
var maxRowFinder = -1
|
||||||
@@ -110,7 +132,7 @@ class ADProperties {
|
|||||||
// and thus, uses whatever the "input" used by the SKELETON is a skeleton
|
// and thus, uses whatever the "input" used by the SKELETON is a skeleton
|
||||||
val propsHashMap = HashMap<String, Any?>()
|
val propsHashMap = HashMap<String, Any?>()
|
||||||
list.forEach {
|
list.forEach {
|
||||||
propsHashMap[it.variable.toUpperCase()] = it.input
|
propsHashMap[it.name.toUpperCase()] = it.input
|
||||||
}
|
}
|
||||||
|
|
||||||
// if it is indeed anim, populate animations list
|
// if it is indeed anim, populate animations list
|
||||||
@@ -144,11 +166,11 @@ class ADProperties {
|
|||||||
val frameName = "${t}_$fc"
|
val frameName = "${t}_$fc"
|
||||||
val prop = get(frameName)
|
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) {
|
val transformList = if (!emptyList) {
|
||||||
List(prop.size) { index ->
|
List(prop.size) { index ->
|
||||||
val jointNameToSearch = prop[index].variable.toUpperCase()
|
val jointNameToSearch = prop[index].name.toUpperCase()
|
||||||
val joint = if (jointNameToSearch == "ALL")
|
val joint = if (jointNameToSearch == "ALL")
|
||||||
ALL_JOINT
|
ALL_JOINT
|
||||||
else
|
else
|
||||||
@@ -196,7 +218,7 @@ class ADProperties {
|
|||||||
private fun getAnimNameFromFrame(s: String) = s.substring(0 until s.lastIndexOf('_'))
|
private fun getAnimNameFromFrame(s: String) = s.substring(0 until s.lastIndexOf('_'))
|
||||||
|
|
||||||
private fun List<ADPropertyObject>.toJoints() = List(this.size) {
|
private fun List<ADPropertyObject>.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) {
|
class ADPropertyObject(propertyRaw: String) {
|
||||||
|
|
||||||
/** If the input is like ```UPPER_TORSO``` (that is, not a variable-input pair), this holds the string UPPER_TORSO. */
|
/** 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?
|
val input: Any?
|
||||||
get() = when (type) {
|
get() = when (type) {
|
||||||
ADPropertyType.IVEC2 -> field!! as Vector2i
|
ADPropertyType.IVEC2 -> field!! as Vector2i
|
||||||
@@ -226,7 +248,7 @@ class ADPropertyObject(propertyRaw: String) {
|
|||||||
val propPair = propertyRaw.split(variableInputSepRegex)
|
val propPair = propertyRaw.split(variableInputSepRegex)
|
||||||
|
|
||||||
if (isADvariable(propertyRaw)) {
|
if (isADvariable(propertyRaw)) {
|
||||||
variable = propPair[0]
|
name = propPair[0]
|
||||||
val inputStr = propPair[1]
|
val inputStr = propPair[1]
|
||||||
|
|
||||||
if (isADivec2(inputStr)) {
|
if (isADivec2(inputStr)) {
|
||||||
@@ -243,7 +265,7 @@ class ADPropertyObject(propertyRaw: String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
variable = propertyRaw
|
name = propertyRaw
|
||||||
input = null
|
input = null
|
||||||
type = ADPropertyType.NAME_ONLY
|
type = ADPropertyType.NAME_ONLY
|
||||||
}
|
}
|
||||||
@@ -287,6 +309,6 @@ class ADPropertyObject(propertyRaw: String) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "$variable ${input ?: ""}: ${type.toString().toLowerCase()}"
|
return "$name ${input ?: ""}: ${type.toString().toLowerCase()}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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|
|
|SPRITESHEET|properties: NAME_ONLY|Base file name of the images|
|
||||||
|EXTENSION|properties: NAME_ONLY|Extension of the base file|
|
|EXTENSION|properties: NAME_ONLY|Extension of the base file|
|
||||||
|
|CONFIG|properties: 2 variables|Frame size and origin-x position, 0 being left|
|
||||||
|
|
||||||
#### Animation
|
#### Animation
|
||||||
|
|
||||||
|
|||||||
@@ -15,14 +15,14 @@ import java.io.File
|
|||||||
*/
|
*/
|
||||||
object AssembleSheetPixmap {
|
object AssembleSheetPixmap {
|
||||||
|
|
||||||
operator fun invoke(properties: ADProperties, assembleConfig: AssembleConfig = AssembleConfig()): Pixmap {
|
operator fun invoke(properties: ADProperties): Pixmap {
|
||||||
val canvas = Pixmap(properties.cols * assembleConfig.fw, properties.rows * assembleConfig.fh, Pixmap.Format.RGBA8888)
|
val canvas = Pixmap(properties.cols * properties.frameWidth, properties.rows * properties.frameHeight, Pixmap.Format.RGBA8888)
|
||||||
canvas.blending = Pixmap.Blending.SourceOver
|
canvas.blending = Pixmap.Blending.SourceOver
|
||||||
|
|
||||||
|
|
||||||
// actually draw
|
// actually draw
|
||||||
properties.transforms.forEach { t, _ ->
|
properties.transforms.forEach { t, _ ->
|
||||||
drawThisFrame(t, canvas, properties, assembleConfig)
|
drawThisFrame(t, canvas, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
return canvas
|
return canvas
|
||||||
@@ -30,8 +30,7 @@ object AssembleSheetPixmap {
|
|||||||
|
|
||||||
private fun drawThisFrame(frameName: String,
|
private fun drawThisFrame(frameName: String,
|
||||||
canvas: Pixmap,
|
canvas: Pixmap,
|
||||||
properties: ADProperties,
|
properties: ADProperties
|
||||||
assembleConfig: AssembleConfig
|
|
||||||
) {
|
) {
|
||||||
val theAnim = properties.getAnimByFrameName(frameName)
|
val theAnim = properties.getAnimByFrameName(frameName)
|
||||||
val skeleton = theAnim.skeleton.joints.reversed()
|
val skeleton = theAnim.skeleton.joints.reversed()
|
||||||
@@ -56,23 +55,23 @@ object AssembleSheetPixmap {
|
|||||||
|
|
||||||
AppLoader.printdbg(this, "Frame to draw: $frameName (R$animRow C$animFrame)")
|
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() }
|
bodyparts.forEach { it?.dispose() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun drawFrame(row: Int, column: Int,
|
private fun drawFrame(row: Int, column: Int,
|
||||||
canvas: Pixmap,
|
canvas: Pixmap,
|
||||||
|
props: ADProperties,
|
||||||
bodyparts: Array<Pixmap?>,
|
bodyparts: Array<Pixmap?>,
|
||||||
transformList: List<Pair<String, ADPropertyObject.Vector2i>>,
|
transformList: List<Pair<String, ADPropertyObject.Vector2i>>
|
||||||
assembleConfig: AssembleConfig
|
|
||||||
) {
|
) {
|
||||||
val tmpFrame = Pixmap(assembleConfig.fw, assembleConfig.fh, Pixmap.Format.RGBA8888)
|
val tmpFrame = Pixmap(props.frameWidth, props.frameHeight, Pixmap.Format.RGBA8888)
|
||||||
|
|
||||||
bodyparts.forEachIndexed { index, image ->
|
bodyparts.forEachIndexed { index, image ->
|
||||||
if (image != null) {
|
if (image != null) {
|
||||||
val imgCentre = AssembleFrameBase.getCentreOf(image)
|
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)
|
tmpFrame.drawPixmap(image, drawPos.x, drawPos.y)
|
||||||
}
|
}
|
||||||
@@ -80,8 +79,8 @@ object AssembleSheetPixmap {
|
|||||||
|
|
||||||
canvas.drawPixmap(
|
canvas.drawPixmap(
|
||||||
tmpFrame,
|
tmpFrame,
|
||||||
(column - 1) * assembleConfig.fw,
|
(column - 1) * props.frameWidth,
|
||||||
(row - 1) * assembleConfig.fh
|
(row - 1) * props.frameHeight
|
||||||
)
|
)
|
||||||
|
|
||||||
tmpFrame.dispose()
|
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 {
|
object AssembleFrameBase {
|
||||||
/**
|
/**
|
||||||
* Returns joints list with tranform applied.
|
* Returns joints list with tranform applied.
|
||||||
|
|||||||
@@ -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()
|
panelAnimationsList.model = DefaultListModel()
|
||||||
panelBodypartsList.model = DefaultListModel()
|
panelBodypartsList.model = DefaultListModel()
|
||||||
@@ -172,6 +172,8 @@ class SpriteAssemblerApp(val gdxWindow: SpriteAssemblerPreview) : JFrame() {
|
|||||||
// populate stats
|
// populate stats
|
||||||
(panelStatList.model as DefaultListModel).addElement("Spritesheet rows: ${adProperties.rows}")
|
(panelStatList.model as DefaultListModel).addElement("Spritesheet rows: ${adProperties.rows}")
|
||||||
(panelStatList.model as DefaultListModel).addElement("Spritesheet columns: ${adProperties.cols}")
|
(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) {
|
catch (fehler: Throwable) {
|
||||||
displayError("ERROR_PARSE_FAIL", fehler)
|
displayError("ERROR_PARSE_FAIL", fehler)
|
||||||
@@ -289,6 +291,7 @@ class SpriteAssemblerPreview: Game() {
|
|||||||
image = AssembleSheetPixmap(prop)
|
image = AssembleSheetPixmap(prop)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO rename to requestAssembly
|
||||||
fun requestAssemblyTest(prop: ADProperties) {
|
fun requestAssemblyTest(prop: ADProperties) {
|
||||||
doAssemble = true
|
doAssemble = true
|
||||||
assembleProp = prop
|
assembleProp = prop
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
|
# complete file name is: SPRITESHEET + bodypart name + EXTENSION
|
||||||
SPRITESHEET=mods/basegame/sprites/sprite_assembler_test_assets/test_
|
SPRITESHEET=mods/basegame/sprites/sprite_assembler_test_assets/test_
|
||||||
EXTENSION=.tga
|
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
|
# note to self: don't implement skeleton hierarchy: there's too many exceptions
|
||||||
# besides, you have "ALL" key.
|
# 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=DELAY 2;ROW 1;SKELETON SKELETON_STAND
|
||||||
ANIM_IDLE_1=
|
ANIM_IDLE_1=
|
||||||
! ANIM_IDLE_1 will not make any transformation
|
! 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
|
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
|
||||||
! HAND_REST is deliberately left out -- it's bit unsettling to see held item keeps moving
|
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ object Terrarum : Screen {
|
|||||||
*/
|
*/
|
||||||
val TARGET_INTERNAL_FPS: Double = 60.0
|
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
|
var ingame: IngameInstance? = null
|
||||||
|
|
||||||
private val javaHeapCircularArray = CircularArray<Int>(128)
|
private val javaHeapCircularArray = CircularArray<Int>(64)
|
||||||
private val nativeHeapCircularArray = CircularArray<Int>(128)
|
private val nativeHeapCircularArray = CircularArray<Int>(64)
|
||||||
private val updateRateCircularArray = CircularArray<Double>(128)
|
private val updateRateCircularArray = CircularArray<Double>(16)
|
||||||
|
|
||||||
val memJavaHeap: Int
|
val memJavaHeap: Int
|
||||||
get() {
|
get() {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package net.torvald.terrarum.modulebasegame.gameactors
|
|||||||
import com.badlogic.gdx.Gdx
|
import com.badlogic.gdx.Gdx
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
|
import net.torvald.spriteanimation.HasAssembledSprite
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
import net.torvald.terrarum.gameactors.*
|
import net.torvald.terrarum.gameactors.*
|
||||||
import net.torvald.terrarum.gameactors.faction.Faction
|
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)
|
* Humanoid actor class to provide same controlling function (such as work, jump)
|
||||||
* Also applies unreal air friction for movement control
|
* 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.
|
* Created by minjaesong on 2016-10-24.
|
||||||
*/
|
*/
|
||||||
open class ActorHumanoid(
|
open class ActorHumanoid(
|
||||||
@@ -610,8 +616,11 @@ open class ActorHumanoid(
|
|||||||
|
|
||||||
// set anim frame delay
|
// set anim frame delay
|
||||||
// 4f of the divider is a magic number, empirically decided
|
// 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
|
if (this is HasAssembledSprite) {
|
||||||
spriteGlow?.delays?.set(SPRITE_ROW_WALK, scale.sqrt().toFloat() / (4f * (controllerMoveDelta?.x ?: 0.0001).abs().toFloat())) // FIXME empirical value
|
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
|
// flipping the sprite
|
||||||
if (walkHeading == LEFT) {
|
if (walkHeading == LEFT) {
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
package net.torvald.terrarum.modulebasegame.gameactors
|
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.Terrarum
|
||||||
import net.torvald.terrarum.modulebasegame.gameworld.GameWorldExtension
|
|
||||||
import net.torvald.terrarum.modulebasegame.gameworld.time_t
|
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.
|
* 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.).
|
* Creates new Player instance with empty elements (sprites, actorvalue, etc.).
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package net.torvald.terrarum.modulebasegame.gameactors
|
package net.torvald.terrarum.modulebasegame.gameactors
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx
|
||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
import net.torvald.terrarum.gameactors.AVKey
|
import net.torvald.terrarum.gameactors.AVKey
|
||||||
import net.torvald.terrarum.gameactors.Actor
|
import net.torvald.terrarum.gameactors.Actor
|
||||||
@@ -13,7 +14,7 @@ object PlayerBuilder {
|
|||||||
operator fun invoke(): Actor {
|
operator fun invoke(): Actor {
|
||||||
val world = (Terrarum.ingame!! as Ingame).gameworld
|
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")
|
InjectCreatureRaw(p.actorValue, "basegame", "CreatureHuman.json")
|
||||||
|
|
||||||
// attach sprite
|
// attach sprite
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package net.torvald.terrarum.modulebasegame.gameactors
|
package net.torvald.terrarum.modulebasegame.gameactors
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx
|
||||||
import net.torvald.terrarum.ModMgr
|
import net.torvald.terrarum.ModMgr
|
||||||
import net.torvald.terrarum.blockproperties.Block
|
import net.torvald.terrarum.blockproperties.Block
|
||||||
import net.torvald.terrarum.gameactors.AVKey
|
import net.torvald.terrarum.gameactors.AVKey
|
||||||
@@ -14,7 +15,7 @@ import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
|||||||
object PlayerBuilderSigrid {
|
object PlayerBuilderSigrid {
|
||||||
|
|
||||||
operator fun invoke(): IngamePlayer {
|
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
|
p.referenceID = 0x51621D // the only constant of this procedural universe
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
package net.torvald.terrarum.modulebasegame.gameactors
|
package net.torvald.terrarum.modulebasegame.gameactors
|
||||||
|
|
||||||
|
import net.torvald.spriteanimation.SpriteAnimation
|
||||||
import net.torvald.terrarum.ModMgr
|
import net.torvald.terrarum.ModMgr
|
||||||
import net.torvald.terrarum.gameactors.AVKey
|
import net.torvald.terrarum.gameactors.AVKey
|
||||||
import net.torvald.terrarum.worlddrawer.FeaturesDrawer
|
import net.torvald.terrarum.worlddrawer.FeaturesDrawer
|
||||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2017-02-10.
|
* Created by minjaesong on 2017-02-10.
|
||||||
*/
|
*/
|
||||||
object PlayerBuilderTestSubject1 {
|
object PlayerBuilderTestSubject1 {
|
||||||
operator fun invoke(): IngamePlayer {
|
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")
|
InjectCreatureRaw(p.actorValue, "basegame", "CreatureHuman.json")
|
||||||
|
|
||||||
|
|
||||||
@@ -20,10 +20,12 @@ object PlayerBuilderTestSubject1 {
|
|||||||
p.actorValue[AVKey.NAME] = "Test Subject 1"
|
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!!.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.setHitboxDimension(15, p.actorValue.getAsInt(AVKey.BASEHEIGHT) ?: ActorHumanoid.BASE_HEIGHT, 21, 0)
|
||||||
|
|
||||||
p.setPosition(3.0 * FeaturesDrawer.TILE_SIZE, 3.0 * FeaturesDrawer.TILE_SIZE)
|
p.setPosition(3.0 * FeaturesDrawer.TILE_SIZE, 3.0 * FeaturesDrawer.TILE_SIZE)
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import com.badlogic.gdx.graphics.Camera
|
|||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.ActorInventory
|
|
||||||
import net.torvald.terrarum.gameactors.ActorWBMovable
|
import net.torvald.terrarum.gameactors.ActorWBMovable
|
||||||
import net.torvald.terrarum.itemproperties.GameItem
|
import net.torvald.terrarum.itemproperties.GameItem
|
||||||
import net.torvald.terrarum.itemproperties.ItemCodex
|
import net.torvald.terrarum.itemproperties.ItemCodex
|
||||||
|
import net.torvald.terrarum.modulebasegame.gameactors.ActorInventory
|
||||||
import net.torvald.terrarum.ui.UIItem
|
import net.torvald.terrarum.ui.UIItem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,8 +39,7 @@ class UIItemInventoryEquippedView(
|
|||||||
|
|
||||||
val spriteViewBackCol: Color; get() = Color(0x404040_88.toInt())//Color(0xd4d4d4_ff.toInt())
|
val spriteViewBackCol: Color; get() = Color(0x404040_88.toInt())//Color(0xd4d4d4_ff.toInt())
|
||||||
|
|
||||||
private val itemGrid = Array<UIItemInventoryCellBase>(
|
private val itemGrid = Array<UIItemInventoryCellBase>(2 * 5) {
|
||||||
2 * 5, {
|
|
||||||
UIItemInventoryElemSimple(
|
UIItemInventoryElemSimple(
|
||||||
parentUI = parentUI,
|
parentUI = parentUI,
|
||||||
posX = this.posX + (UIItemInventoryElemSimple.height + listGap) * ((it + 4) % 2),
|
posX = this.posX + (UIItemInventoryElemSimple.height + listGap) * ((it + 4) % 2),
|
||||||
@@ -55,7 +54,6 @@ class UIItemInventoryEquippedView(
|
|||||||
drawBackOnNull = true
|
drawBackOnNull = true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
override fun update(delta: Float) {
|
override fun update(delta: Float) {
|
||||||
|
|||||||
145
src/net/torvald/terrarum/tests/MakeKeylayoutFile.kt
Normal file
145
src/net/torvald/terrarum/tests/MakeKeylayoutFile.kt
Normal file
@@ -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<IntArray>.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()
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user