[Editor] Enable basic game map serialization/deserialization
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
package com.bartlomiejpluta.base.editor.common.serial
|
||||
|
||||
import java.io.InputStream
|
||||
|
||||
interface Deserializer<T> {
|
||||
fun deserialize(input: InputStream): T
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.bartlomiejpluta.base.editor.common.serial
|
||||
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
interface Serializer<T> {
|
||||
fun serialize(item: T, output: OutputStream)
|
||||
}
|
||||
@@ -5,8 +5,13 @@ import javafx.beans.property.SimpleStringProperty
|
||||
import tornadofx.getValue
|
||||
import tornadofx.setValue
|
||||
|
||||
class TileLayer(name: String, rows: Int, columns: Int) : Layer {
|
||||
var layer: Array<Array<Tile?>> = Array(rows) { Array(columns) { null } }
|
||||
class TileLayer(
|
||||
name: String,
|
||||
rows: Int,
|
||||
columns: Int,
|
||||
layer: Array<Array<Tile?>> = Array(rows) { Array(columns) { null } }
|
||||
) : Layer {
|
||||
var layer = layer
|
||||
private set
|
||||
|
||||
override val nameProperty = SimpleStringProperty(name)
|
||||
@@ -15,7 +20,7 @@ class TileLayer(name: String, rows: Int, columns: Int) : Layer {
|
||||
override fun resize(rows: Int, columns: Int) {
|
||||
layer = Array(rows) { row ->
|
||||
Array(columns) { column ->
|
||||
layer.getOrNull(row) ?. getOrNull(column)
|
||||
layer.getOrNull(row)?.getOrNull(column)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,10 +20,10 @@ class GameMap(val tileSet: TileSet) {
|
||||
val tileHeight = tileSet.tileHeight.toDouble()
|
||||
|
||||
val rowsProperty = SimpleIntegerProperty(INITIAL_ROWS)
|
||||
val rows by rowsProperty
|
||||
var rows by rowsProperty
|
||||
|
||||
val columnsProperty = SimpleIntegerProperty(INITIAL_COLUMNS)
|
||||
val columns by columnsProperty
|
||||
var columns by columnsProperty
|
||||
|
||||
val widthProperty = SimpleDoubleProperty(INITIAL_COLUMNS * tileWidth)
|
||||
var width by widthProperty
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.bartlomiejpluta.base.editor.map.serial
|
||||
|
||||
import com.bartlomiejpluta.base.editor.common.serial.Deserializer
|
||||
import com.bartlomiejpluta.base.editor.map.model.map.GameMap
|
||||
|
||||
interface MapDeserializer : Deserializer<GameMap>
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.bartlomiejpluta.base.editor.map.serial
|
||||
|
||||
import com.bartlomiejpluta.base.editor.common.serial.Serializer
|
||||
import com.bartlomiejpluta.base.editor.map.model.map.GameMap
|
||||
|
||||
interface MapSerializer : Serializer<GameMap>
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.bartlomiejpluta.base.editor.map.serial
|
||||
|
||||
import com.bartlomiejpluta.base.editor.map.model.layer.Layer
|
||||
import com.bartlomiejpluta.base.editor.map.model.layer.TileLayer
|
||||
import com.bartlomiejpluta.base.editor.map.model.map.GameMap
|
||||
import com.bartlomiejpluta.base.editor.tileset.model.Tile
|
||||
import com.bartlomiejpluta.base.editor.tileset.model.TileSet
|
||||
import com.bartlomiejpluta.base.proto.GameMapProto
|
||||
import org.springframework.stereotype.Component
|
||||
import tornadofx.ResourceLookup
|
||||
import java.io.InputStream
|
||||
|
||||
@Component
|
||||
class ProtobufMapDeserializer : MapDeserializer {
|
||||
private val resources = ResourceLookup(this)
|
||||
private val tileset = TileSet(resources.image("/textures/tileset.png"), 160, 8)
|
||||
|
||||
override fun deserialize(input: InputStream): GameMap {
|
||||
val map = GameMap(tileset)
|
||||
val proto = GameMapProto.GameMap.parseFrom(input)
|
||||
map.name = proto.name
|
||||
map.rows = proto.rows
|
||||
map.columns = proto.columns
|
||||
|
||||
proto.layersList.forEach {
|
||||
map.layers.add(deserializeLayer(map.rows, map.columns, tileset, it))
|
||||
}
|
||||
|
||||
return map
|
||||
}
|
||||
|
||||
private fun deserializeLayer(rows: Int, columns: Int, tileSet: TileSet, proto: GameMapProto.Layer): Layer {
|
||||
return when {
|
||||
proto.hasTileLayer() -> deserializeTileLayer(rows, columns, tileSet, proto)
|
||||
|
||||
else -> throw IllegalStateException("Not supported layer type")
|
||||
}
|
||||
}
|
||||
|
||||
private fun deserializeTileLayer(rows: Int, columns: Int, tileSet: TileSet, proto: GameMapProto.Layer): Layer {
|
||||
val layer: Array<Array<Tile?>> = Array(rows) { Array(columns) { null } }
|
||||
|
||||
proto.tileLayer.tilesList.forEachIndexed { index, tile ->
|
||||
layer[index / columns][index % columns] = when(tile) {
|
||||
0 -> null
|
||||
else -> tileSet.getTile(tile-1)
|
||||
}
|
||||
}
|
||||
|
||||
return TileLayer(proto.name, rows, columns, layer)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.bartlomiejpluta.base.editor.map.serial
|
||||
|
||||
import com.bartlomiejpluta.base.editor.map.model.layer.Layer
|
||||
import com.bartlomiejpluta.base.editor.map.model.layer.TileLayer
|
||||
import com.bartlomiejpluta.base.editor.map.model.map.GameMap
|
||||
import com.bartlomiejpluta.base.proto.GameMapProto
|
||||
import org.springframework.stereotype.Component
|
||||
import java.io.OutputStream
|
||||
|
||||
@Component
|
||||
class ProtobufMapSerializer : MapSerializer {
|
||||
|
||||
override fun serialize(map: GameMap, output: OutputStream) {
|
||||
val protoMap = GameMapProto.GameMap.newBuilder()
|
||||
protoMap.name = map.name
|
||||
protoMap.rows = map.rows
|
||||
protoMap.columns = map.columns
|
||||
|
||||
map.layers.forEach { layer -> protoMap.addLayers(serializeLayer(layer)) }
|
||||
|
||||
protoMap.build().writeTo(output)
|
||||
}
|
||||
|
||||
private fun serializeLayer(layer: Layer): GameMapProto.Layer {
|
||||
return when (layer) {
|
||||
is TileLayer -> layer.layer.flatMap { it.asIterable() }
|
||||
.fold(GameMapProto.TileLayer.newBuilder()) { acc, tile -> acc.addTiles((tile?.id?.plus(1)) ?: 0) }
|
||||
.build()
|
||||
.let { GameMapProto.Layer.newBuilder().setName(layer.name).setTileLayer(it).build() }
|
||||
|
||||
else -> throw IllegalStateException("Not supported layer type")
|
||||
}
|
||||
}
|
||||
}
|
||||
23
proto/src/main/proto/map.proto
Executable file
23
proto/src/main/proto/map.proto
Executable file
@@ -0,0 +1,23 @@
|
||||
package com.bartlomiejpluta.base.proto;
|
||||
|
||||
option java_package = "com.bartlomiejpluta.base.proto";
|
||||
option java_outer_classname = "GameMapProto";
|
||||
|
||||
message GameMap {
|
||||
required string name = 1;
|
||||
required uint32 rows = 2;
|
||||
required uint32 columns = 3;
|
||||
repeated Layer layers = 4;
|
||||
}
|
||||
|
||||
message Layer {
|
||||
required string name = 1;
|
||||
|
||||
oneof layer {
|
||||
TileLayer tileLayer = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message TileLayer {
|
||||
repeated uint32 tiles = 1;
|
||||
}
|
||||
Reference in New Issue
Block a user