[Editor] Enable storing Tile Sets and loading Game Maps with them

This commit is contained in:
2021-02-12 09:21:37 +01:00
parent 02acad538b
commit 12d9d6d7df
7 changed files with 44 additions and 12 deletions

View File

@@ -3,27 +3,30 @@ package com.bartlomiejpluta.base.editor.map.serial
import com.bartlomiejpluta.base.editor.map.model.layer.Layer 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.layer.TileLayer
import com.bartlomiejpluta.base.editor.map.model.map.GameMap import com.bartlomiejpluta.base.editor.map.model.map.GameMap
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
import com.bartlomiejpluta.base.editor.tileset.model.Tile import com.bartlomiejpluta.base.editor.tileset.model.Tile
import com.bartlomiejpluta.base.editor.tileset.model.TileSet import com.bartlomiejpluta.base.editor.tileset.model.TileSet
import com.bartlomiejpluta.base.proto.GameMapProto import com.bartlomiejpluta.base.proto.GameMapProto
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component import org.springframework.stereotype.Component
import tornadofx.ResourceLookup
import java.io.InputStream import java.io.InputStream
@Component @Component
class ProtobufMapDeserializer : MapDeserializer { class ProtobufMapDeserializer : MapDeserializer {
private val resources = ResourceLookup(this)
private val tileset = TileSet("Test TileSet", resources.image("/textures/tileset.png"), 160, 8) @Autowired
private lateinit var projectContext: ProjectContext
override fun deserialize(input: InputStream): GameMap { override fun deserialize(input: InputStream): GameMap {
val map = GameMap(tileset)
val proto = GameMapProto.GameMap.parseFrom(input) val proto = GameMapProto.GameMap.parseFrom(input)
val tileSet = projectContext.loadTileSet(proto.tileSetUID)
val map = GameMap(tileSet)
map.uid = proto.uid map.uid = proto.uid
map.rows = proto.rows map.rows = proto.rows
map.columns = proto.columns map.columns = proto.columns
proto.layersList.forEach { proto.layersList.forEach {
map.layers.add(deserializeLayer(map.rows, map.columns, tileset, it)) map.layers.add(deserializeLayer(map.rows, map.columns, tileSet, it))
} }
return map return map

View File

@@ -15,6 +15,7 @@ class ProtobufMapSerializer : MapSerializer {
protoMap.uid = item.uid protoMap.uid = item.uid
protoMap.rows = item.rows protoMap.rows = item.rows
protoMap.columns = item.columns protoMap.columns = item.columns
protoMap.tileSetUID = item.tileSet.uid
item.layers.forEach { layer -> protoMap.addLayers(serializeLayer(layer)) } item.layers.forEach { layer -> protoMap.addLayers(serializeLayer(layer)) }

View File

@@ -1,6 +1,8 @@
package com.bartlomiejpluta.base.editor.map.view.wizard package com.bartlomiejpluta.base.editor.map.view.wizard
import com.bartlomiejpluta.base.editor.asset.model.Asset
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapBuilderVM import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapBuilderVM
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
import com.bartlomiejpluta.base.editor.tileset.model.TileSet import com.bartlomiejpluta.base.editor.tileset.model.TileSet
import javafx.scene.control.ListView import javafx.scene.control.ListView
import tornadofx.* import tornadofx.*
@@ -10,11 +12,15 @@ class MapTileSetSelectionView : View("Tile Set") {
private var tileSetsListView: ListView<TileSet> by singleAssign() private var tileSetsListView: ListView<TileSet> by singleAssign()
// TODO(Fetch it from project assets) private val projectContext: ProjectContext by di()
private val tileSets = listOf(
TileSet("Big TileSet", resources.image("/textures/tileset.png"), 160, 8), // FIXME
TileSet("Mage City", resources.image("/textures/magecity.png"), 44, 8) // Because of loading all the images at once and storing them in cache
).asObservable() // this solution is not best efficient. It could be better to store images
// in the local cache, scoped to this view.
private val tileSets =
projectContext.project?.tileSets?.map(Asset::uid)?.map(projectContext::loadTileSet)?.asObservable()
?: throw IllegalStateException("There is no open project in the context")
// FIXME // FIXME

View File

@@ -10,9 +10,11 @@ import com.bartlomiejpluta.base.editor.project.serial.ProjectDeserializer
import com.bartlomiejpluta.base.editor.project.serial.ProjectSerializer import com.bartlomiejpluta.base.editor.project.serial.ProjectSerializer
import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAsset import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAsset
import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAssetBuilder import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAssetBuilder
import com.bartlomiejpluta.base.editor.tileset.model.TileSet
import com.bartlomiejpluta.base.editor.util.uid.UID import com.bartlomiejpluta.base.editor.util.uid.UID
import javafx.beans.property.ObjectProperty import javafx.beans.property.ObjectProperty
import javafx.beans.property.SimpleObjectProperty import javafx.beans.property.SimpleObjectProperty
import javafx.scene.image.Image
import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component import org.springframework.stereotype.Component
import tornadofx.getValue import tornadofx.getValue
@@ -23,6 +25,7 @@ import java.io.FileOutputStream
@Component @Component
class DefaultProjectContext : ProjectContext { class DefaultProjectContext : ProjectContext {
private val tileSetCache = mutableMapOf<String, TileSet>()
@Autowired @Autowired
private lateinit var projectSerializer: ProjectSerializer private lateinit var projectSerializer: ProjectSerializer
@@ -42,6 +45,7 @@ class DefaultProjectContext : ProjectContext {
init { init {
projectProperty.addListener { _, _, newProject -> projectProperty.addListener { _, _, newProject ->
newProject?.mkdirs() newProject?.mkdirs()
tileSetCache.clear()
} }
} }
@@ -94,4 +98,15 @@ class DefaultProjectContext : ProjectContext {
} }
} }
} }
override fun loadTileSet(uid: String) = tileSetCache.getOrPut(uid) {
project?.let {
val asset = it.tileSets.first { tileSet -> tileSet.uid == uid }
?: throw IllegalStateException("The Tile Set with uid [$uid] does not exist ")
val image = File(it.tileSetsDirectory, asset.source).inputStream().use { fis -> Image(fis) }
TileSet(uid, asset.name, image, asset.rows, asset.columns)
} ?: throw IllegalStateException("There is no open project in the context")
}
} }

View File

@@ -3,6 +3,7 @@ package com.bartlomiejpluta.base.editor.project.context
import com.bartlomiejpluta.base.editor.map.model.map.GameMap import com.bartlomiejpluta.base.editor.map.model.map.GameMap
import com.bartlomiejpluta.base.editor.project.model.Project import com.bartlomiejpluta.base.editor.project.model.Project
import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAssetBuilder import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAssetBuilder
import com.bartlomiejpluta.base.editor.tileset.model.TileSet
import javafx.beans.property.ObjectProperty import javafx.beans.property.ObjectProperty
import java.io.File import java.io.File
@@ -17,4 +18,5 @@ interface ProjectContext {
fun loadMap(uid: String): GameMap fun loadMap(uid: String): GameMap
fun importTileSet(builder: TileSetAssetBuilder) fun importTileSet(builder: TileSetAssetBuilder)
fun loadTileSet(uid: String): TileSet
} }

View File

@@ -1,6 +1,7 @@
package com.bartlomiejpluta.base.editor.tileset.model package com.bartlomiejpluta.base.editor.tileset.model
import com.bartlomiejpluta.base.editor.map.model.brush.Brush import com.bartlomiejpluta.base.editor.map.model.brush.Brush
import javafx.beans.property.ReadOnlyStringWrapper
import javafx.beans.property.SimpleIntegerProperty import javafx.beans.property.SimpleIntegerProperty
import javafx.beans.property.SimpleObjectProperty import javafx.beans.property.SimpleObjectProperty
import javafx.beans.property.SimpleStringProperty import javafx.beans.property.SimpleStringProperty
@@ -12,7 +13,10 @@ import tornadofx.toObservable
import java.nio.ByteBuffer import java.nio.ByteBuffer
class TileSet(name: String, image: Image, rows: Int, columns: Int) { class TileSet(uid: String, name: String, image: Image, rows: Int, columns: Int) {
val uidProperty = ReadOnlyStringWrapper(uid)
val uid by uidProperty
val nameProperty = SimpleStringProperty(name) val nameProperty = SimpleStringProperty(name)
val name by nameProperty val name by nameProperty

View File

@@ -7,7 +7,8 @@ message GameMap {
required string uid = 1; required string uid = 1;
required uint32 rows = 2; required uint32 rows = 2;
required uint32 columns = 3; required uint32 columns = 3;
repeated Layer layers = 4; required string tileSetUID = 4;
repeated Layer layers = 5;
} }
message Layer { message Layer {