tapestry sprite to draw frame

This commit is contained in:
minjaesong
2022-02-28 11:39:29 +09:00
parent 142fcab930
commit 68d8bf13b7
8 changed files with 118 additions and 24 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -115,6 +115,11 @@ object CommonResourcePool {
return pool[identifier]!!
}
fun getOrNull(identifier: String) = pool[identifier]
fun getOrDefault(identifier: String, defaultValue: Any) = pool.getOrDefault(identifier, defaultValue)
fun getOrPut(identifier: String, defaultValue: () -> Any) = pool.getOrPut(identifier, defaultValue)
fun getOrElse(identifier: String, defaultValue: () -> Any) = pool.getOrElse(identifier, defaultValue)
inline fun <reified T> getAs(identifier: String) = get(identifier) as T
fun getAsTextureRegionPack(identifier: String) = getAs<TextureRegionPack>(identifier)
fun getAsTextureRegion(identifier: String) = getAs<TextureRegion>(identifier)

View File

@@ -37,6 +37,7 @@ import java.io.PrintStream
import java.util.*
import kotlin.math.absoluteValue
import kotlin.math.round
import kotlin.math.roundToInt
@@ -348,6 +349,20 @@ inline fun FrameBuffer.inActionF(camera: OrthographicCamera?, batch: SpriteBatch
}
private val rgbMultLUT = Array(256) { y -> IntArray(256) { x ->
val i = (x % 256) / 255f
val j = (y / 256) / 255f
(i * j).times(255f).roundToInt()
} }
infix fun Int.rgbamul(other: Int): Int {
val r = rgbMultLUT[this.ushr(24).and(255)][other.ushr(24).and(255)]
val g = rgbMultLUT[this.ushr(16).and(255)][other.ushr(16).and(255)]
val b = rgbMultLUT[this.ushr(8).and(255)][other.ushr(8).and(255)]
val a = rgbMultLUT[this.ushr(0).and(255)][other.ushr(0).and(255)]
return r.shl(24) or g.shl(16) or b.shl(8) or a
}
infix fun Color.mul(other: Color): Color = this.cpy().mul(other)
infix fun Color.mulAndAssign(other: Color): Color {
this.r *= other.r

View File

@@ -109,13 +109,11 @@ object DecodeTapestry {
val FORMAT_16 = 1
val FORMAT_64 = 2
operator fun invoke(fileObj: File): TapestryObject {
operator fun invoke(file: ByteArray): TapestryInfo {
fun magicMismatch(magic: ByteArray, array: ByteArray): Boolean {
return !Arrays.equals(array.sliceArray(0..magic.lastIndex), magic)
}
val file = fileObj.readBytes()
val magic = file.copyOfRange(0, 4)
if (magicMismatch(MAGIC, magic))
@@ -174,6 +172,8 @@ object DecodeTapestry {
readCounter++
}
return TapestryObject(outImageData, artName, authorName) { "$ccW$authorName, $ccC$artName" }
return TapestryInfo(outImageData, artName, authorName)
}
}
}
data class TapestryInfo(val pixmap: Pixmap, val artName: String, val authorName: String)

View File

@@ -1,12 +1,15 @@
package net.torvald.terrarum.modulebasegame.gameactors
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.*
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
import net.torvald.terrarum.ceilInt
import net.torvald.terrarum.blockproperties.Block
import net.torvald.terrarum.gameactors.ActorID
import net.torvald.terrarum.gameitems.ItemID
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
/**
@@ -14,34 +17,86 @@ import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
*/
class TapestryObject : FixtureBase {
// physics = false only speeds up for ~2 frames with 50 tapestries
@Transient private var initialised = false
var artName = ""; private set
var artAuthor = ""; private set
val tw = 1
val th = 1
private var rawBytes = ByteArray(tw * th * 256)
private var frameBlock: ItemID = Block.PLANK_NORMAL
private constructor() : super()
constructor(pixmap: Pixmap, artName: String, artAuthor: String, nameFun: () -> String) : super() {
constructor(rawBytes: ByteArray, framingMaterial: ItemID) : super() {
this.artName = artName
this.artAuthor = artAuthor
this.nameFun = nameFun
val texture = Texture(pixmap)
pixmap.dispose()
texture.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
val texturePack = TextureRegionPack(texture, texture.width, texture.height)
makeNewSprite(texturePack)
setHitboxDimension(texture.width, texture.height, 0, 0)
setPosition(Terrarum.mouseX, Terrarum.mouseY)
// you CAN'T destroy the image
// redefine blockbox
this.blockBox = BlockBox(BlockBox.NO_COLLISION, texture.width.div(TILE_SIZEF).ceilInt(), texture.height.div(TILE_SIZEF).ceilInt())
this.renderOrder = RenderOrder.BEHIND
this.nameFun = { "$ccW$artAuthor, $ccC$artName" }
this.rawBytes = rawBytes
this.frameBlock = framingMaterial
}
override fun update(delta: Float) {
if (!initialised) {
initialised = true
val (pixmap, name, author) = DecodeTapestry(rawBytes)
artName = name
artAuthor = author
if (pixmap.width % TILE_SIZE != 0 || pixmap.height % TILE_SIZE != 0 || pixmap.width * pixmap.height == 0) {
throw UnsupportedOperationException("Tapestry size not multiple of tile size: (${pixmap.width}x${pixmap.height})")
}
// draw canvas and frame texture over the pixmap
val tileFilename = "${frameBlock.replace(':','-')}"
val frame = CommonResourcePool.getOrPut("tapestries-common-frame_$tileFilename.tga") {
Pixmap(ModMgr.getGdxFilesFromEveryMod("tapestries/common/frame_$tileFilename.tga").last().second)
} as Pixmap
val canvas = CommonResourcePool.getOrPut("tapestries-common-canvas") {
Pixmap(ModMgr.getGdxFilesFromEveryMod("tapestries/common/canvas.tga").last().second)
} as Pixmap
val tw = pixmap.width.div(TILE_SIZEF).ceilInt()
val th = pixmap.height.div(TILE_SIZEF).ceilInt()
// blend canvas texture
for (y in 0 until pixmap.height) { for (x in 0 until pixmap.width) {
val srcCol = canvas.getPixel(x % pixmap.width, y % pixmap.height)
val dstCol = pixmap.getPixel(x, y)
pixmap.drawPixel(x, y, dstCol rgbamul srcCol)
} }
// draw frame
for (ty in 0 until th) { for (tx in 0 until tw) {
val srcx = TILE_SIZE * (if (tw == 1) 0 else if (tx == 0) 1 else if (tx == tw - 1) 3 else 2)
val srcy = TILE_SIZE * (if (th == 1) 0 else if (ty == 0) 1 else if (tw == th - 1) 3 else 2)
val dstx = tx * TILE_SIZE
val dsty = ty * TILE_SIZE
pixmap.drawPixmap(frame, srcx, srcy, TILE_SIZE, TILE_SIZE, dstx, dsty, TILE_SIZE, TILE_SIZE)
} }
val texture = Texture(pixmap)
texture.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
val texturePack = TextureRegionPack(texture, texture.width, texture.height)
makeNewSprite(texturePack)
setHitboxDimension(texture.width, texture.height, 0, 0)
setPosition(Terrarum.mouseX, Terrarum.mouseY)
// redefine blockbox
this.blockBox = BlockBox(BlockBox.NO_COLLISION, tw, th)
this.renderOrder = RenderOrder.BEHIND
pixmap.dispose()
INGAME.disposables.add(texture)
}
super.update(delta)
}

View File

@@ -203,6 +203,16 @@ object Common {
return rng
}
})
// kotlin.ByteArray
jsoner.setSerializer(ByteArray::class.java, object : Json.Serializer<ByteArray> {
override fun write(json: Json, obj: ByteArray, knownType: Class<*>?) {
json.writeValue(bytesToZipdStr(obj.iterator()))
}
override fun read(json: Json, jsonData: JsonValue, type: Class<*>?): ByteArray {
return strToBytes(StringReader(jsonData.asString())).toByteArray()
}
})
}
private data class LayerInfo(val h: String, val b: String, val x: Int, val y: Int)

Binary file not shown.