mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-10 10:34:06 +09:00
tapestry sprite to draw frame
This commit is contained in:
BIN
assets/mods/basegame/tapestries/common/canvas.tga
LFS
Normal file
BIN
assets/mods/basegame/tapestries/common/canvas.tga
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/tapestries/common/frame_basegame-48.tga
LFS
Normal file
BIN
assets/mods/basegame/tapestries/common/frame_basegame-48.tga
LFS
Normal file
Binary file not shown.
@@ -115,6 +115,11 @@ object CommonResourcePool {
|
|||||||
return pool[identifier]!!
|
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
|
inline fun <reified T> getAs(identifier: String) = get(identifier) as T
|
||||||
fun getAsTextureRegionPack(identifier: String) = getAs<TextureRegionPack>(identifier)
|
fun getAsTextureRegionPack(identifier: String) = getAs<TextureRegionPack>(identifier)
|
||||||
fun getAsTextureRegion(identifier: String) = getAs<TextureRegion>(identifier)
|
fun getAsTextureRegion(identifier: String) = getAs<TextureRegion>(identifier)
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import java.io.PrintStream
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
import kotlin.math.round
|
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.mul(other: Color): Color = this.cpy().mul(other)
|
||||||
infix fun Color.mulAndAssign(other: Color): Color {
|
infix fun Color.mulAndAssign(other: Color): Color {
|
||||||
this.r *= other.r
|
this.r *= other.r
|
||||||
|
|||||||
@@ -109,13 +109,11 @@ object DecodeTapestry {
|
|||||||
val FORMAT_16 = 1
|
val FORMAT_16 = 1
|
||||||
val FORMAT_64 = 2
|
val FORMAT_64 = 2
|
||||||
|
|
||||||
operator fun invoke(fileObj: File): TapestryObject {
|
operator fun invoke(file: ByteArray): TapestryInfo {
|
||||||
fun magicMismatch(magic: ByteArray, array: ByteArray): Boolean {
|
fun magicMismatch(magic: ByteArray, array: ByteArray): Boolean {
|
||||||
return !Arrays.equals(array.sliceArray(0..magic.lastIndex), magic)
|
return !Arrays.equals(array.sliceArray(0..magic.lastIndex), magic)
|
||||||
}
|
}
|
||||||
|
|
||||||
val file = fileObj.readBytes()
|
|
||||||
|
|
||||||
val magic = file.copyOfRange(0, 4)
|
val magic = file.copyOfRange(0, 4)
|
||||||
|
|
||||||
if (magicMismatch(MAGIC, magic))
|
if (magicMismatch(MAGIC, magic))
|
||||||
@@ -174,6 +172,8 @@ object DecodeTapestry {
|
|||||||
readCounter++
|
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)
|
||||||
@@ -1,12 +1,15 @@
|
|||||||
package net.torvald.terrarum.modulebasegame.gameactors
|
package net.torvald.terrarum.modulebasegame.gameactors
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.graphics.Pixmap
|
import com.badlogic.gdx.graphics.Pixmap
|
||||||
import com.badlogic.gdx.graphics.Texture
|
import com.badlogic.gdx.graphics.Texture
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
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.TerrarumAppConfiguration.TILE_SIZEF
|
||||||
import net.torvald.terrarum.ceilInt
|
import net.torvald.terrarum.blockproperties.Block
|
||||||
import net.torvald.terrarum.gameactors.ActorID
|
import net.torvald.terrarum.gameactors.ActorID
|
||||||
|
import net.torvald.terrarum.gameitems.ItemID
|
||||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -14,34 +17,86 @@ import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
|||||||
*/
|
*/
|
||||||
class TapestryObject : FixtureBase {
|
class TapestryObject : FixtureBase {
|
||||||
|
|
||||||
// physics = false only speeds up for ~2 frames with 50 tapestries
|
@Transient private var initialised = false
|
||||||
|
|
||||||
var artName = ""; private set
|
var artName = ""; private set
|
||||||
var artAuthor = ""; 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()
|
private constructor() : super()
|
||||||
|
|
||||||
constructor(pixmap: Pixmap, artName: String, artAuthor: String, nameFun: () -> String) : super() {
|
constructor(rawBytes: ByteArray, framingMaterial: ItemID) : super() {
|
||||||
this.artName = artName
|
this.artName = artName
|
||||||
this.artAuthor = artAuthor
|
this.artAuthor = artAuthor
|
||||||
this.nameFun = nameFun
|
this.nameFun = { "$ccW$artAuthor, $ccC$artName" }
|
||||||
|
this.rawBytes = rawBytes
|
||||||
val texture = Texture(pixmap)
|
this.frameBlock = framingMaterial
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun update(delta: Float) {
|
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)
|
super.update(delta)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -203,6 +203,16 @@ object Common {
|
|||||||
return rng
|
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)
|
private data class LayerInfo(val h: String, val b: String, val x: Int, val y: Int)
|
||||||
|
|||||||
BIN
work_files/graphics/tapestries/common/frame_basegame-NUM.kra
LFS
Normal file
BIN
work_files/graphics/tapestries/common/frame_basegame-NUM.kra
LFS
Normal file
Binary file not shown.
Reference in New Issue
Block a user