discarding the idea of baking assembledsprite onto a spritesheet; revert to the commit right before this to completely scrap the efforts

This commit is contained in:
minjaesong
2022-03-23 17:43:56 +09:00
parent ab73511042
commit 765ece0635
21 changed files with 360 additions and 108 deletions

View File

@@ -48,8 +48,9 @@ class FixtureHomeComputer : FixtureBase {
density = 1400.0
setHitboxDimension(TerrarumAppConfiguration.TILE_SIZE, TerrarumAppConfiguration.TILE_SIZE, 0, -1)
makeNewSprite(FixtureBase.getSpritesheet("dwarventech", "sprites/fixtures/desktop_computer.tga", TILE_SIZE, TILE_SIZE))
sprite!!.setRowsAndFrames(1, 1)
makeNewSprite(FixtureBase.getSpritesheet("dwarventech", "sprites/fixtures/desktop_computer.tga", TILE_SIZE, TILE_SIZE)).let {
it.setRowsAndFrames(1,1)
}
actorValue[AVKey.BASEMASS] = 20.0

View File

@@ -0,0 +1,162 @@
package net.torvald.spriteanimation
import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.badlogic.gdx.utils.GdxRuntimeException
import com.jme3.math.FastMath
import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.Second
import net.torvald.terrarum.gameactors.ActorWithBody
import net.torvald.terrarum.printStackTrace
import net.torvald.terrarum.savegame.ByteArray64Reader
import net.torvald.terrarum.savegame.EntryID
import net.torvald.terrarum.savegame.SimpleFileSystem
import net.torvald.terrarum.serialise.Common
import net.torvald.terrarum.spriteassembler.ADProperties
import net.torvald.terrarum.spriteassembler.AssembleFrameBase
import net.torvald.terrarum.spriteassembler.AssembleSheetPixmap
import java.io.InputStream
import java.util.*
import kotlin.collections.HashMap
/**
* This class should not be serialised; save its Animation Description Language instead.
*
* Created by minjaesong on 2022-03-23.
*/
class AssembledSpriteAnimation(
@Transient val adp: ADProperties,
parentActor: ActorWithBody,
@Transient val disk: SimpleFileSystem?, // specify if the resources for the animation is contained in the disk archive
@Transient val bodypartToFileMap: EntryID? // which file in the disk contains bodypart-to-fileid mapping for this particular instance of sprite animation
) : SpriteAnimation(parentActor) {
constructor(adp: ADProperties, parentActor: ActorWithBody) : this(adp, parentActor, null, null)
var currentFrame = 0 // while this number is zero-based, the frame number on the ADP is one-based
var currentAnimation = "" // e.g. ANIM_IDLE ANIM_RUN (no frame numbers!)
set(value) {
field = value
currentFrame = 0
}
// @Transient var init = false
override val currentDelay: Second
get() = (if (overrideDelay > 0f) overrideDelay else adp.animations[currentAnimation]?.delay ?: 1f).coerceAtLeast(1f / 16f)
var overrideDelay = 0f // set to 0f to not use this field
@Transient private val res = HashMap<String, TextureRegion?>()
init {
// init = true
val fileGetter = if (disk != null) {
val bodypartMapping = Properties()
bodypartMapping.load(ByteArray64Reader(disk.getFile(bodypartToFileMap!!)!!.bytes, Common.CHARSET))
AssembleSheetPixmap.getVirtualDiskFileGetter(bodypartMapping, disk)
}
else AssembleSheetPixmap.getAssetsDirFileGetter(adp)
adp.bodyparts.forEach { res[it] = getPartTexture(fileGetter, it) }
}
private var delta = 0f
override fun update(delta: Float) {
this.delta += delta
//println("delta accumulation: $delta, currentDelay: $currentDelay")
//check if it's time to advance the frame
while (this.delta >= currentDelay) {
// advance frame
currentFrame = (currentFrame + 1) % (adp.animations[currentAnimation]?.frames ?: 2)
// discount counter
this.delta -= currentDelay
}
}
override fun render(batch: SpriteBatch, posX: Float, posY: Float, scale: Float) {
if (parentActor.isVisible) {
val tx = (parentActor.hitboxTranslateX) * scale
val txF = (parentActor.hitboxTranslateX + parentActor.baseHitboxW) * scale
val ty = (parentActor.hitboxTranslateY + (adp.frameHeight - parentActor.baseHitboxH)) * scale
val tyF = (parentActor.hitboxTranslateY + parentActor.baseHitboxH) * scale
adp.animations[currentAnimation]!!.let { theAnim ->
val skeleton = theAnim.skeleton.joints.reversed()
val transforms = adp.getTransform("${currentAnimation}_${1+currentFrame}")
val bodypartOrigins = adp.bodypartJoints
AssembleFrameBase.makeTransformList(skeleton, transforms).forEach { (name, bodypartPos) ->
if (false) { // inject item's image
}
else {
res[name]?.let { image ->
val imgCentre = bodypartOrigins[name]!!.invertX()
val drawPos = adp.origin + bodypartPos + imgCentre
if (flipHorizontal && flipVertical) {
batch.draw(image,
FastMath.floor(posX).toFloat() + txF + drawPos.x,
FastMath.floor(posY).toFloat() + tyF + drawPos.y,
-FastMath.floor(adp.frameWidth * scale).toFloat(),
-FastMath.floor(adp.frameHeight * scale).toFloat()
)
}
else if (flipHorizontal && !flipVertical) {
batch.draw(image,
FastMath.floor(posX).toFloat() + txF + drawPos.x,
FastMath.floor(posY).toFloat() - ty + drawPos.y,
-FastMath.floor(adp.frameWidth * scale).toFloat(),
FastMath.floor(adp.frameHeight * scale).toFloat()
)
}
else if (!flipHorizontal && flipVertical) {
batch.draw(image,
FastMath.floor(posX).toFloat() - tx + drawPos.x,
FastMath.floor(posY).toFloat() + tyF + drawPos.y,
FastMath.floor(adp.frameWidth * scale).toFloat(),
-FastMath.floor(adp.frameHeight * scale).toFloat()
)
}
else {
batch.draw(image,
FastMath.floor(posX).toFloat() - tx + drawPos.x,
FastMath.floor(posY).toFloat() - ty + drawPos.y,
FastMath.floor(adp.frameWidth * scale).toFloat(),
FastMath.floor(adp.frameHeight * scale).toFloat()
)
}
}
}
}
}
}
}
override fun dispose() {
res.values.forEach { try { it?.texture?.dispose() } catch (_: GdxRuntimeException) {} }
}
companion object {
private fun getPartTexture(getFile: (String) -> InputStream?, partName: String): TextureRegion? {
getFile(partName)?.let {
val bytes = it.readAllBytes()
return TextureRegion(Texture(Pixmap(bytes, 0, bytes.size)))
}
return null
}
}
}

View File

@@ -32,12 +32,12 @@ interface HasAssembledSprite {
* reassembleSprite(this.sprite, this.spriteGlow)
* ```
*/
fun reassembleSprite(sprite: SpriteAnimation?, spriteGlow: SpriteAnimation? = null, item: GameItem?) {
/*fun reassembleSprite(sprite: SpriteAnimation?, spriteGlow: SpriteAnimation? = null, item: GameItem?) {
if (animDesc != null && sprite != null)
_rebuild(animDesc!!, sprite, null)
if (animDescGlow != null && spriteGlow != null)
_rebuild(animDescGlow!!, spriteGlow, null)
}
}*/
/*fun reassembleSprite(disk: SimpleFileSystem, sprite: SpriteAnimation?, anim: ADProperties?, spriteGlow: SpriteAnimation? = null, animGlow: ADProperties? = null) {
if (anim != null && sprite != null)
@@ -46,7 +46,7 @@ interface HasAssembledSprite {
_rebuild(disk, animGlow, spriteGlow)
}*/
private fun _rebuild(ad: ADProperties, sprite: SpriteAnimation, item: GameItem?) {
/*private fun _rebuild(ad: ADProperties, sprite: SpriteAnimation, item: GameItem?) {
// TODO injecting held item/armour pictures? Would it be AssembleSheetPixmap's job?
val pixmap = AssembleSheetPixmap.fromAssetsDir(ad, item)
@@ -70,7 +70,7 @@ interface HasAssembledSprite {
sprite.nRows = newAnimDelays.size
}
/*private fun _rebuild(disk: SimpleFileSystem, ad: ADProperties, sprite: SpriteAnimation) {
private fun _rebuild(disk: SimpleFileSystem, ad: ADProperties, sprite: SpriteAnimation) {
// TODO injecting held item/armour pictures? Would it be AssembleSheetPixmap's job?
val pixmap = if (disk.getEntry(-1025) != null) AssembleSheetPixmap.fromVirtualDisk(disk, ad) else AssembleSheetPixmap.fromAssetsDir(ad)

View File

@@ -1,10 +1,5 @@
/* Original code author: Sean Laurvick
* This code is based on the original author's code written in Lua.
*/
package net.torvald.spriteanimation
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.utils.Disposable
import com.jme3.math.FastMath
@@ -14,8 +9,31 @@ import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
/**
* This class should not be serialised; save its Animation Description Language instead.
*
* Created by minjaesong on 2022-03-23.
*/
class SpriteAnimation(@Transient val parentActor: ActorWithBody) : Disposable {
abstract class SpriteAnimation(@Transient val parentActor: ActorWithBody) : Disposable {
protected abstract val currentDelay: Second
abstract fun update(delta: Float)
abstract fun render(batch: SpriteBatch, posX: Float, posY: Float, scale: Float = 1f)
var flipHorizontal = false
var flipVertical = false
open fun flip(horizontal: Boolean, vertical: Boolean) {
flipHorizontal = horizontal
flipVertical = vertical
}
}
/* Original code author: Sean Laurvick
* This code is based on the original author's code written in Lua.
*/
/**
* This class should not be serialised; save its Animation Description Language instead.
*/
class SheetSpriteAnimation(parentActor: ActorWithBody) : SpriteAnimation(parentActor) {
internal lateinit var textureRegion: TextureRegionPack; private set
@@ -27,7 +45,7 @@ class SpriteAnimation(@Transient val parentActor: ActorWithBody) : Disposable {
var nRows: Int = 1
internal set
private val currentDelay: Second
override val currentDelay: Second
get() = delays[currentRow].coerceAtLeast(1f / 16f) // animation delay cannot be too short
/**
@@ -46,8 +64,7 @@ class SpriteAnimation(@Transient val parentActor: ActorWithBody) : Disposable {
var looping = true
private var animationRunning = true
var flipHorizontal = false
var flipVertical = false
private val visible: Boolean
get() = parentActor.isVisible
@@ -57,8 +74,6 @@ class SpriteAnimation(@Transient val parentActor: ActorWithBody) : Disposable {
var cellWidth: Int = 0
var cellHeight: Int = 0
var colorFilter = Color.WHITE
fun setSpriteImage(regionPack: TextureRegionPack) {
textureRegion = regionPack
@@ -86,7 +101,7 @@ class SpriteAnimation(@Transient val parentActor: ActorWithBody) : Disposable {
nFrames = framesCount
}
fun update(delta: Float) {
override fun update(delta: Float) {
if (animationRunning) {
//skip this if animation is stopped
this.delta += delta
@@ -122,7 +137,7 @@ class SpriteAnimation(@Transient val parentActor: ActorWithBody) : Disposable {
* *
* @param scale
*/
fun render(batch: SpriteBatch, posX: Float, posY: Float, scale: Float = 1f) {
override fun render(batch: SpriteBatch, posX: Float, posY: Float, scale: Float) {
assert(cellWidth > 0 || cellHeight > 0) {
"Sprite width or height is set to zero! ($cellWidth, $cellHeight); master: $parentActor"
}
@@ -206,11 +221,6 @@ class SpriteAnimation(@Transient val parentActor: ActorWithBody) : Disposable {
currentFrame = selectFrame
}
fun flip(horizontal: Boolean, vertical: Boolean) {
flipHorizontal = horizontal
flipVertical = vertical
}
override fun dispose() {
textureRegion.dispose()
}

View File

@@ -4,6 +4,7 @@ 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.SheetSpriteAnimation
import net.torvald.spriteanimation.SpriteAnimation
import net.torvald.terrarum.*
import net.torvald.terrarum.App.printdbg
@@ -355,14 +356,18 @@ open class ActorWithBody : Actor {
// some initialiser goes here...
}
fun makeNewSprite(textureRegionPack: TextureRegionPack) {
sprite = SpriteAnimation(this)
sprite!!.setSpriteImage(textureRegionPack)
fun makeNewSprite(textureRegionPack: TextureRegionPack): SheetSpriteAnimation {
sprite = SheetSpriteAnimation(this).also {
it.setSpriteImage(textureRegionPack)
}
return sprite as SheetSpriteAnimation
}
fun makeNewSpriteGlow(textureRegionPack: TextureRegionPack) {
spriteGlow = SpriteAnimation(this)
spriteGlow!!.setSpriteImage(textureRegionPack)
fun makeNewSpriteGlow(textureRegionPack: TextureRegionPack): SheetSpriteAnimation {
spriteGlow = SheetSpriteAnimation(this).also {
it.setSpriteImage(textureRegionPack)
}
return spriteGlow as SheetSpriteAnimation
}
/**
@@ -1741,7 +1746,8 @@ open class ActorWithBody : Actor {
}
open fun getSpriteHead(): TextureRegion? {
return sprite?.textureRegion?.get(0,0)
return CommonResourcePool.getAsTextureRegion("placeholder_16")
//return sprite?.textureRegion?.get(0,0)
}

View File

@@ -1,6 +1,7 @@
package net.torvald.terrarum.gameactors
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.spriteanimation.SheetSpriteAnimation
import net.torvald.terrarum.*
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
import net.torvald.terrarum.gameitems.ItemID
@@ -42,11 +43,12 @@ class WireActor : ActorWithBody {
if (wireID != itemID) {
if (sprite == null) {
makeNewSprite(CommonResourcePool.getAsTextureRegionPack(itemID))
sprite!!.delays = floatArrayOf(1f,1f)
sprite!!.setRowsAndFrames(2, 16)
makeNewSprite(CommonResourcePool.getAsTextureRegionPack(itemID)).let {
it.delays = floatArrayOf(1f,1f)
it.setRowsAndFrames(2, 16)
}
}
else sprite!!.setSpriteImage(CommonResourcePool.getAsTextureRegionPack(itemID))
else (sprite as SheetSpriteAnimation).setSpriteImage(CommonResourcePool.getAsTextureRegionPack(itemID))
wireID = itemID
}
@@ -54,7 +56,7 @@ class WireActor : ActorWithBody {
this.worldY = worldY
setPosition((worldX + 0.5) * TILE_SIZE, (worldY + 1.0) * TILE_SIZE - 1.0) // what the fuck?
sprite!!.currentRow = 0
(sprite as SheetSpriteAnimation).currentRow = 0
val nearbyTiles = getNearbyTilesPos(worldX, worldY).map { world!!.getAllWiresFrom(it.x, it.y) }
var ret = 0
@@ -63,7 +65,7 @@ class WireActor : ActorWithBody {
ret = ret or (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
}
}
sprite!!.currentFrame = ret
(sprite as SheetSpriteAnimation).currentFrame = ret
}
private fun getNearbyTilesPos(x: Int, y: Int): Array<Point2i> {
@@ -88,10 +90,10 @@ class WireActor : ActorWithBody {
val itemID = rootID + it
row = row or ((world?.getWireEmitStateOf(worldX, worldY, itemID)?.isNotZero == true).toInt() shl index)
}
sprite?.currentRow = row
(sprite as SheetSpriteAnimation).currentRow = row
}
else {
sprite?.currentRow = (world?.getWireEmitStateOf(worldX, worldY, wireID)?.isNotZero == true).toInt()
(sprite as SheetSpriteAnimation).currentRow = (world?.getWireEmitStateOf(worldX, worldY, wireID)?.isNotZero == true).toInt()
}
BlendMode.resolve(drawMode, batch)

View File

@@ -375,6 +375,8 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
// don't put it on the postInit() or render(); postInitForNewGame calls this function on the savegamewriter's callback
makeSavegameBackupCopy(getWorldSaveFiledesc(worldSavefileName))
makeSavegameBackupCopy(getPlayerSaveFiledesc(playerSavefileName))
printdbg(this, "postInitForLoadFromSave exit")
}
private val autosaveOnErrorAction = { e: Throwable -> uiAutosaveNotifier.setAsError() }
@@ -703,7 +705,6 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
gameFullyLoaded = true
}
ingameController.update()
@@ -725,8 +726,6 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
}
setDebugTime("Ingame.UpdateCounter", i)
/** RENDER CODE GOES HERE */
measureDebugTime("Ingame.Render") { renderGame() }
@@ -768,7 +767,6 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
////////////////////////////
FeaturesDrawer.update(delta)
///////////////////////////
// actor-related updates //
///////////////////////////
@@ -822,6 +820,7 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
WORLD_UPDATE_TIMER += 1
}
if (!paused || newWorldLoadedLatch) {
// completely consume block change queues because why not
terrainChangeQueue.clear()
@@ -831,7 +830,6 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
oldSelectedWireRenderClass = selectedWireRenderClass
}
////////////////////////
// ui-related updates //
////////////////////////
@@ -1105,7 +1103,7 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
// rebuild the disk skimmers
INGAME.actorContainerActive.filterIsInstance<IngamePlayer>().forEach {
printdbg(this, "Game Save callback -- rebuilding the disk skimmer for IngamePlayer ${it.actorValue.getAsString(AVKey.NAME)}")
it.rebuildingDiskSkimmer?.rebuild()
// it.rebuildingDiskSkimmer?.rebuild()
}
// return to normal state

View File

@@ -4,7 +4,9 @@ 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.AssembledSpriteAnimation
import net.torvald.spriteanimation.HasAssembledSprite
import net.torvald.spriteanimation.SheetSpriteAnimation
import net.torvald.terrarum.*
import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED
@@ -722,8 +724,14 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L
if (walledBottom && controllerV?.x != 0.0) {
//switch row
sprite?.switchRow(SPRITE_ROW_WALK)
spriteGlow?.switchRow(SPRITE_ROW_WALK)
if (this is HasAssembledSprite) {
(sprite as? AssembledSpriteAnimation)?.currentAnimation = "ANIM_RUN"
(spriteGlow as? AssembledSpriteAnimation)?.currentAnimation = "ANIM_RUN"
}
else {
(sprite as? SheetSpriteAnimation)?.switchRow(SPRITE_ROW_WALK)
(spriteGlow as? SheetSpriteAnimation)?.switchRow(SPRITE_ROW_WALK)
}
// set anim frame delay
if (this is HasAssembledSprite) {
@@ -736,8 +744,8 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L
val finalDelay = baseDelay * (scaleCompensation / moveSpeedMult)
sprite?.delays?.set(SPRITE_ROW_WALK, finalDelay)
spriteGlow?.delays?.set(SPRITE_ROW_WALK, finalDelay)
(sprite as? AssembledSpriteAnimation)?.overrideDelay = finalDelay
(spriteGlow as? AssembledSpriteAnimation)?.overrideDelay = finalDelay
}
catch (e: NullPointerException) {
println(animDesc!!.animations.keys.joinToString())
@@ -757,8 +765,17 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L
}
}
else {
sprite?.switchRow(SPRITE_ROW_IDLE)
spriteGlow?.switchRow(SPRITE_ROW_IDLE)
if (this is HasAssembledSprite) {
(sprite as? AssembledSpriteAnimation)?.currentAnimation = "ANIM_IDLE"
(spriteGlow as? AssembledSpriteAnimation)?.currentAnimation = "ANIM_IDLE"
(sprite as? AssembledSpriteAnimation)?.overrideDelay = 0f
(spriteGlow as? AssembledSpriteAnimation)?.overrideDelay = 0f
}
else {
(sprite as? SheetSpriteAnimation)?.switchRow(SPRITE_ROW_IDLE)
(spriteGlow as? SheetSpriteAnimation)?.switchRow(SPRITE_ROW_IDLE)
}
}
}
}

View File

@@ -29,8 +29,9 @@ class FixtureLogicSignalEmitter : FixtureBase, Electric {
density = 1400.0
setHitboxDimension(TILE_SIZE, TILE_SIZE, 0, -1)
makeNewSprite(TextureRegionPack(itemImage.texture, TILE_SIZE, TILE_SIZE))
sprite!!.setRowsAndFrames(1, 1)
makeNewSprite(TextureRegionPack(itemImage.texture, TILE_SIZE, TILE_SIZE)).let {
it.setRowsAndFrames(1,1)
}
actorValue[AVKey.BASEMASS] = MASS
}

View File

@@ -40,8 +40,9 @@ internal class FixtureStorageChest : FixtureBase {
setHitboxDimension(TILE_SIZE, TILE_SIZE, 0, -1)
makeNewSprite(TextureRegionPack(CommonResourcePool.getAsTextureRegion("itemplaceholder_16").texture, 16, 16))
sprite!!.setRowsAndFrames(1, 1)
makeNewSprite(TextureRegionPack(CommonResourcePool.getAsTextureRegion("itemplaceholder_16").texture, 16, 16)).let {
it.setRowsAndFrames(1,1)
}
actorValue[AVKey.BASEMASS] = MASS

View File

@@ -3,6 +3,7 @@ package net.torvald.terrarum.modulebasegame.gameactors
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.gdx.graphics.Cvec
import net.torvald.random.HQRNG
import net.torvald.spriteanimation.SheetSpriteAnimation
import net.torvald.terrarum.BlockCodex
import net.torvald.terrarum.CommonResourcePool
import net.torvald.terrarum.ModMgr
@@ -52,8 +53,9 @@ internal class FixtureTikiTorch : FixtureBase, Luminous {
lightBoxList.add(Lightbox(Hitbox(6.0, 5.0, 4.0, 3.0), color))
makeNewSprite(FixtureBase.getSpritesheet("basegame", "sprites/fixtures/tiki_torch.tga", 16, 32))
sprite!!.setRowsAndFrames(1, 2)
makeNewSprite(FixtureBase.getSpritesheet("basegame", "sprites/fixtures/tiki_torch.tga", 16, 32)).let {
it.setRowsAndFrames(1,2)
}
actorValue[AVKey.BASEMASS] = MASS
}
@@ -73,7 +75,7 @@ internal class FixtureTikiTorch : FixtureBase, Luminous {
spawnTimer -= nextDelay
nextDelay = rng.nextFloat() * 0.25f + 0.25f
sprite?.delays?.set(0, rng.nextFloat() * 0.4f + 0.1f)
(sprite as? SheetSpriteAnimation)?.delays?.set(0, rng.nextFloat() * 0.4f + 0.1f)
}
spawnTimer += delta

View File

@@ -83,9 +83,9 @@ class IngamePlayer : ActorHumanoid, HasAssembledSprite {
/** To be used later by the game to rebuild the sprite.
* Which `_rebuild` function to use is determined at the load time.
*/
@Transient private lateinit var rebuildfun: (item: GameItem?) -> Unit
@Transient private lateinit var rebuildfunGlow: (item: GameItem?) -> Unit
@Transient internal var rebuildingDiskSkimmer: DiskSkimmer? = null
// @Transient private lateinit var rebuildfun: (item: GameItem?) -> Unit
// @Transient private lateinit var rebuildfunGlow: (item: GameItem?) -> Unit
// @Transient internal var rebuildingDiskSkimmer: DiskSkimmer? = null
/**
* Example usage:
@@ -97,7 +97,7 @@ class IngamePlayer : ActorHumanoid, HasAssembledSprite {
* reassembleSprite(this.sprite, this.spriteGlow)
* ```
*/
override fun reassembleSprite(sprite: SpriteAnimation?, spriteGlow: SpriteAnimation?, heldItem: GameItem?) {
/*override fun reassembleSprite(sprite: SpriteAnimation?, spriteGlow: SpriteAnimation?, heldItem: GameItem?) {
if (animDesc != null && sprite != null) {
rebuildfun = { item: GameItem? -> _rebuild(animDesc!!, sprite, item) }; rebuildfun(heldItem)
spriteHeadTexture = AssembleSheetPixmap.getMugshotFromAssetsDir(animDesc!!)
@@ -119,9 +119,9 @@ class IngamePlayer : ActorHumanoid, HasAssembledSprite {
}
if (animDescGlow != null && spriteGlow != null)
rebuildfunGlow = { item: GameItem? -> _rebuild(disk, -1026L, animDescGlow!!, spriteGlow, item) }; rebuildfunGlow(heldItem)
}
}*/
private fun _rebuild(ad: ADProperties, sprite: SpriteAnimation, item: GameItem?) {
/*private fun _rebuild(ad: ADProperties, sprite: SpriteAnimation, item: GameItem?) {
// TODO injecting held item/armour pictures? Would it be AssembleSheetPixmap's job?
val pixmap = AssembleSheetPixmap.fromAssetsDir(ad, item)
@@ -167,15 +167,15 @@ class IngamePlayer : ActorHumanoid, HasAssembledSprite {
sprite.delays = newAnimDelays
sprite.nFrames = newAnimFrames
sprite.nRows = newAnimDelays.size
}
}*/
override fun getSpriteHead(): TextureRegion? {
/*override fun getSpriteHead(): TextureRegion? {
return spriteHeadTexture
}
}*/
@Transient private var unequipNoSpriteUpdate = false
override fun equipItem(item: GameItem) {
/*override fun equipItem(item: GameItem) {
val oldItemID = inventory.itemEquipped[item.equipPosition]
unequipNoSpriteUpdate = true
@@ -208,5 +208,5 @@ class IngamePlayer : ActorHumanoid, HasAssembledSprite {
// println("IngamePlayer.unequipItem")
// printStackTrace(this)
}
}*/
}

View File

@@ -10,7 +10,7 @@ import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
/**
* Created by minjaesong on 2016-03-25.
*/
object PlayerBuilderCynthia {
/*object PlayerBuilderCynthia {
operator fun invoke(): ActorWithBody {
//val p: IngamePlayer = IngamePlayer(GameDate(100, 143)) // random value thrown
@@ -44,4 +44,4 @@ object PlayerBuilderCynthia {
}
}
}*/

View File

@@ -1,5 +1,6 @@
package net.torvald.terrarum.modulebasegame.gameactors
import net.torvald.spriteanimation.AssembledSpriteAnimation
import net.torvald.spriteanimation.SpriteAnimation
import net.torvald.terrarum.ModMgr
import net.torvald.terrarum.gameactors.AVKey
@@ -27,9 +28,9 @@ object PlayerBuilderTestSubject1 {
p.sprite!!.delays = floatArrayOf(2f, 1f/12f) // second value does nothing -- overridden by ActorHumanoid.updateSprite(float)
p.sprite!!.setRowsAndFrames(2, 4)*/
p.sprite = SpriteAnimation(p)
p.spriteGlow = SpriteAnimation(p)
p.reassembleSprite(p.sprite, p.spriteGlow, null)
p.animDesc?.let { p.sprite = AssembledSpriteAnimation(it, p) }
p.animDescGlow?.let { p.spriteGlow = AssembledSpriteAnimation(it, p) }
//p.reassembleSprite(p.sprite, p.spriteGlow, null)
p.setHitboxDimension(15, p.actorValue.getAsInt(AVKey.BASEHEIGHT) ?: ActorHumanoid.BASE_HEIGHT, 21, 0)
// ingame must teleport the player to the spawn point

View File

@@ -1,5 +1,6 @@
package net.torvald.terrarum.modulebasegame.gameactors
import net.torvald.spriteanimation.AssembledSpriteAnimation
import net.torvald.spriteanimation.SpriteAnimation
import net.torvald.terrarum.ModMgr
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
@@ -28,9 +29,9 @@ object PlayerBuilderWerebeastTest {
p.sprite!!.delays = floatArrayOf(2f, 1f/12f) // second value does nothing -- overridden by ActorHumanoid.updateSprite(float)
p.sprite!!.setRowsAndFrames(2, 4)*/
p.sprite = SpriteAnimation(p)
p.spriteGlow = SpriteAnimation(p)
p.reassembleSprite(p.sprite, p.spriteGlow, null)
p.animDesc?.let { p.sprite = AssembledSpriteAnimation(it, p) }
p.animDescGlow?.let { p.spriteGlow = AssembledSpriteAnimation(it, p) }
//p.reassembleSprite(p.sprite, p.spriteGlow, null)
p.setHitboxDimension(22, p.actorValue.getAsInt(AVKey.BASEHEIGHT)!!, 30, 0)
p.setPosition(3.0 * TILE_SIZE, 3.0 * TILE_SIZE)

View File

@@ -120,7 +120,7 @@ class UIInventoryEscMenu(val full: UIInventoryFull) : UICanvas() {
// rebuild the disk skimmers
INGAME.actorContainerActive.filterIsInstance<IngamePlayer>().forEach {
printdbg(this, "Game Save callback -- rebuilding the disk skimmer for IngamePlayer ${it.actorValue.getAsString(AVKey.NAME)}")
it.rebuildingDiskSkimmer?.rebuild()
// it.rebuildingDiskSkimmer?.rebuild()
}
// return to normal state

View File

@@ -3,6 +3,8 @@ package net.torvald.terrarum.modulebasegame.ui
import com.badlogic.gdx.graphics.Camera
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.spriteanimation.AssembledSpriteAnimation
import net.torvald.spriteanimation.SheetSpriteAnimation
import net.torvald.terrarum.*
import net.torvald.terrarum.gameitems.GameItem
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.itemListHeight
@@ -85,11 +87,17 @@ class UIItemInventoryEquippedView(
blendNormal(batch)
batch.color = SPRITE_DRAW_COL
batch.draw(
it.textureRegion.get(0, 0),
posX + (width - it.cellWidth + EXTRA_HEADROOM_X).div(2).toFloat(),
posY + (width - it.cellHeight - EXTRA_HEADROOM_Y).div(2).toFloat()
)
if (it is SheetSpriteAnimation) {
batch.draw(
it.textureRegion.get(0, 0),
posX + (width - it.cellWidth + EXTRA_HEADROOM_X).div(2).toFloat(),
posY + (width - it.cellHeight - EXTRA_HEADROOM_Y).div(2).toFloat()
)
}
else if (it is AssembledSpriteAnimation) {
// TODO
}
}

View File

@@ -7,6 +7,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.badlogic.gdx.graphics.glutils.FrameBuffer
import com.badlogic.gdx.graphics.glutils.ShapeRenderer
import com.badlogic.gdx.utils.GdxRuntimeException
import com.badlogic.gdx.utils.JsonReader
import com.jme3.math.FastMath
import net.torvald.unicode.EMDASH
@@ -28,6 +29,8 @@ import net.torvald.terrarum.serialise.SaveLoadError
import net.torvald.terrarum.spriteassembler.ADProperties
import net.torvald.terrarum.spriteassembler.ADProperties.Companion.EXTRA_HEADROOM_X
import net.torvald.terrarum.spriteassembler.ADProperties.Companion.EXTRA_HEADROOM_Y
import net.torvald.terrarum.spriteassembler.AssembleFrameBase
import net.torvald.terrarum.spriteassembler.AssembleSheetPixmap
import net.torvald.terrarum.ui.Movement
import net.torvald.terrarum.ui.Toolkit
import net.torvald.terrarum.ui.UICanvas
@@ -531,7 +534,7 @@ class UIItemPlayerCells(
"${d}d${h.toString().padStart(2,'0')}h${m.toString().padStart(2,'0')}m${s.toString().padStart(2,'0')}s"
}
private var sprite: SpriteAnimation? = null
private var sprite: TextureRegion? = null
internal var hasTexture = false
private set
@@ -556,16 +559,47 @@ class UIItemPlayerCells(
if (skimmer.initialised && !hasTexture) {
skimmer.getFile(-1L)?.bytes?.let {
try {
val frameName = "ANIM_IDLE_1"
val animFile = skimmer.getFile(-2L)!!
val p = ReadPlayer(skimmer, ByteArray64Reader(it, Common.CHARSET))
p.sprite = SpriteAnimation(p)
p.animDesc = ADProperties(ByteArray64Reader(animFile.bytes, Common.CHARSET))
p.reassembleSpriteFromDisk(skimmer, p.sprite, null, null)
p.sprite!!.textureRegion.get(0,0).let {
thumb = it
thumb!!.flip(false, false)
}
this.sprite = p.sprite
val properties = ADProperties(ByteArray64Reader(animFile.bytes, Common.CHARSET))
val imagesSelfContained = skimmer.hasEntry(-1025L)
val bodypartMapping = Properties().also { if (imagesSelfContained) it.load(ByteArray64Reader(skimmer.getFile(-1025L)!!.bytes, Common.CHARSET)) }
val fileGetter = if (imagesSelfContained)
AssembleSheetPixmap.getVirtualDiskFileGetter(bodypartMapping, skimmer)
else
AssembleSheetPixmap.getAssetsDirFileGetter(properties)
// println(properties.transforms.keys)
val canvas = Pixmap(properties.cols * (properties.frameWidth), properties.rows * (properties.frameHeight), Pixmap.Format.RGBA8888).also { it.blending = Pixmap.Blending.SourceOver }
val theAnim = properties.getAnimByFrameName(frameName)
val skeleton = theAnim.skeleton.joints.reversed()
val transforms = properties.getTransform(frameName)
val bodypartOrigins = properties.bodypartJoints
val bodypartImages = properties.bodypartJoints.keys.map { partname ->
fileGetter(partname).let { file ->
if (file == null) partname to null
else {
try {
val bytes = file.readAllBytes()
partname to Pixmap(bytes, 0, bytes.size)
}
catch (e: GdxRuntimeException) {
partname to null
}
}
}
}.toMap()
val transformList = AssembleFrameBase.makeTransformList(skeleton, transforms)
// manually draw 0th frame of ANIM_IDLE
AssembleSheetPixmap.drawFrame(0, 0, canvas, properties, bodypartOrigins, bodypartImages, transformList, null)
bodypartImages.values.forEach { it?.dispose() }
this.sprite = TextureRegion(Texture(canvas))
}
catch (e: Throwable) {
throw SaveLoadError(skimmer.diskFile, e)
@@ -620,7 +654,7 @@ class UIItemPlayerCells(
override fun dispose() {
thumb?.texture?.dispose()
thumbPixmap?.dispose()
sprite?.dispose()
sprite?.texture?.dispose()
}

View File

@@ -1,5 +1,6 @@
package net.torvald.terrarum.serialise
import net.torvald.spriteanimation.AssembledSpriteAnimation
import net.torvald.spriteanimation.HasAssembledSprite
import net.torvald.spriteanimation.SpriteAnimation
import net.torvald.terrarum.spriteassembler.ADProperties
@@ -12,6 +13,7 @@ import net.torvald.terrarum.gameitems.ItemID
import net.torvald.terrarum.itemproperties.ItemRemapTable
import net.torvald.terrarum.modulebasegame.TerrarumIngame
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
import net.torvald.terrarum.printStackTrace
import net.torvald.terrarum.savegame.*
import java.io.Reader
import java.util.*
@@ -151,27 +153,27 @@ object ReadActor {
val animFileGlow = disk.getFile(-3L)
val bodypartsFile = disk.getFile(-1025)
actor.sprite = SpriteAnimation(actor)
actor.animDesc = ADProperties(ByteArray64Reader(animFile!!.bytes, Common.CHARSET))
actor.sprite = AssembledSpriteAnimation(actor.animDesc!!, actor, if (bodypartsFile != null) disk else null, if (bodypartsFile != null) -1025 else null)
if (animFileGlow != null) {
actor.spriteGlow = SpriteAnimation(actor)
actor.animDescGlow = ADProperties(ByteArray64Reader(animFileGlow.bytes, Common.CHARSET))
actor.spriteGlow = AssembledSpriteAnimation(actor.animDescGlow!!, actor, if (bodypartsFile != null) disk else null, if (bodypartsFile != null) -1025 else null)
}
ItemCodex.loadFromSave(disk.getBackingFile(), actor.dynamicToStaticTable, actor.dynamicItemInventory)
val heldItem = ItemCodex[actor.inventory.itemEquipped[GameItem.EquipPosition.HAND_GRIP]]
// val heldItem = ItemCodex[actor.inventory.itemEquipped[GameItem.EquipPosition.HAND_GRIP]]
if (bodypartsFile != null)
/*if (bodypartsFile != null)
actor.reassembleSpriteFromDisk(disk, actor.sprite!!, actor.spriteGlow, heldItem)
else
actor.reassembleSprite(actor.sprite!!, actor.spriteGlow, heldItem)
actor.reassembleSprite(actor.sprite!!, actor.spriteGlow, heldItem)*/
}
else if (actor is ActorWithBody && actor is HasAssembledSprite) {
if (actor.animDesc != null) actor.sprite = SpriteAnimation(actor)
if (actor.animDescGlow != null) actor.spriteGlow = SpriteAnimation(actor)
if (actor.animDesc != null) actor.sprite = AssembledSpriteAnimation(actor.animDesc!!, actor)
if (actor.animDescGlow != null) actor.spriteGlow = AssembledSpriteAnimation(actor.animDescGlow!!, actor)
actor.reassembleSprite(actor.sprite, actor.spriteGlow, null)
//actor.reassembleSprite(actor.sprite, actor.spriteGlow, null)
}

View File

@@ -34,6 +34,10 @@ internal data class Transform(val joint: Joint, val translate: ADPropertyObject.
override fun toString() = "$joint transform: $translate"
}
/**
* If this class is held by a IngamePlayer, this won't get serialised (will be read from a file on loading);
* if this class is held by a non-player, this will get serialised.
*/
class ADProperties {
private var fileFrom = ""
@Transient private var adlString = ""
@@ -43,7 +47,8 @@ class ADProperties {
private val propTable = HashMap<String, List<ADPropertyObject>>()
/** list of bodyparts used by all the skeletons (HEAD, UPPER_TORSO, LOWER_TORSO) */
// lateinit var bodyparts: List<String>; private set
lateinit var bodyparts: List<String>; private set
/** [bodyparts] but in a full file path */
lateinit var bodypartFiles: List<String>; private set
/** properties that are being used as skeletons (SKELETON_STAND) */
internal lateinit var skeletons: HashMap<String, Skeleton>; private set
@@ -219,6 +224,7 @@ class ADProperties {
this.skeletons = skeletons
this.animations = animations
this.bodyparts = this.bodypartJoints.keys.toList()
this.bodypartFiles = this.bodypartJoints.keys.map { toFilename(it) }
this.transforms = transforms
@@ -238,8 +244,8 @@ class ADProperties {
internal fun getAnimByFrameName(frameName: String) = animations[getAnimNameFromFrame(frameName)]!!
internal fun getFrameNumberFromName(frameName: String) = frameName.substring(frameName.lastIndexOf('_') + 1 until frameName.length).toInt()
internal fun getSkeleton(name: String) = skeletons[name]!!
internal fun getTransform(name: String) = transforms[name]!!
internal fun getSkeleton(name: String) = skeletons[name] ?: throw NullPointerException("No skeleton with name '$name'")
internal fun getTransform(name: String) = transforms[name] ?: throw NullPointerException("No tranform with name '$name'")
/**
* Removes number suffix from the animation name
@@ -327,7 +333,7 @@ class ADPropertyObject(propertyRaw: String) {
fun isADstring(property: String) = !isADvariable(property)
}
internal data class Vector2i(var x: Int, var y: Int) {
data class Vector2i(var x: Int, var y: Int) {
override fun toString() = "($x, $y)"
operator fun plus(other: Vector2i) = Vector2i(this.x + other.x, this.y + other.y)

View File

@@ -132,7 +132,7 @@ object AssembleSheetPixmap {
return tr
}
private fun drawThisFrame(frameName: String,
fun drawThisFrame(frameName: String,
canvas: Pixmap,
properties: ADProperties,
fileGetter: (String) -> InputStream?,
@@ -168,7 +168,7 @@ object AssembleSheetPixmap {
bodypartImages.values.forEach { it?.dispose() }
}
private fun drawFrame(row: Int, column: Int,
fun drawFrame(row: Int, column: Int,
canvas: Pixmap,
props: ADProperties,
bodypartOrigins: HashMap<String, ADPropertyObject.Vector2i>,