[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.getValue
|
||||||
import tornadofx.setValue
|
import tornadofx.setValue
|
||||||
|
|
||||||
class TileLayer(name: String, rows: Int, columns: Int) : Layer {
|
class TileLayer(
|
||||||
var layer: Array<Array<Tile?>> = Array(rows) { Array(columns) { null } }
|
name: String,
|
||||||
|
rows: Int,
|
||||||
|
columns: Int,
|
||||||
|
layer: Array<Array<Tile?>> = Array(rows) { Array(columns) { null } }
|
||||||
|
) : Layer {
|
||||||
|
var layer = layer
|
||||||
private set
|
private set
|
||||||
|
|
||||||
override val nameProperty = SimpleStringProperty(name)
|
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) {
|
override fun resize(rows: Int, columns: Int) {
|
||||||
layer = Array(rows) { row ->
|
layer = Array(rows) { row ->
|
||||||
Array(columns) { column ->
|
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 tileHeight = tileSet.tileHeight.toDouble()
|
||||||
|
|
||||||
val rowsProperty = SimpleIntegerProperty(INITIAL_ROWS)
|
val rowsProperty = SimpleIntegerProperty(INITIAL_ROWS)
|
||||||
val rows by rowsProperty
|
var rows by rowsProperty
|
||||||
|
|
||||||
val columnsProperty = SimpleIntegerProperty(INITIAL_COLUMNS)
|
val columnsProperty = SimpleIntegerProperty(INITIAL_COLUMNS)
|
||||||
val columns by columnsProperty
|
var columns by columnsProperty
|
||||||
|
|
||||||
val widthProperty = SimpleDoubleProperty(INITIAL_COLUMNS * tileWidth)
|
val widthProperty = SimpleDoubleProperty(INITIAL_COLUMNS * tileWidth)
|
||||||
var width by widthProperty
|
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