diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/main/controller/MainController.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/main/controller/MainController.kt index 65d05be3..f945f0bd 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/main/controller/MainController.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/main/controller/MainController.kt @@ -81,7 +81,7 @@ class MainController : Controller() { columns = vm.columns handler = vm.handler } - projectContext.importMap(vm.name, map) + projectContext.importMap(vm.name, vm.handlerBaseClass?.takeIf { it.isNotEmpty() }, map) openItems[scope] = GameMapVM(map) } @@ -95,20 +95,28 @@ class MainController : Controller() { setInScope(vm, scope) find(scope).apply { onComplete { - val map = projectContext.importMapFromFile(vm.name, vm.handler, File(vm.file), ::askForNewTileSetAsset, ::askForNewAutoTileAsset) + val map = projectContext.importMapFromFile( + vm.name, + vm.handler, + vm.handlerBaseClass?.takeIf { it.isNotEmpty() }, + File(vm.file), + ::askForNewTileSetAsset, + ::askForNewAutoTileAsset + ) openItems[scope] = GameMapVM(map) } openModal(block = true, resizable = false) } } + private fun askForNewTileSetAsset(name: String, uid: String): String { var newUid = "" find>( Scope(), SelectGraphicAssetFragment::assets to projectContext.project?.tileSets!!, - SelectGraphicAssetFragment::comment to "You are importing a tile layer which originally was defined\nwith an other Tile Set asset data with UID: [$uid].\nPlease select asset you would like to apply for layer $name.\n".toProperty(), + SelectGraphicAssetFragment::comment to "You are importing a tile layer which originally was defined\nwith an other Tile Set asset data with UID: [$uid].\nPlease select asset you would like to apply for layer [$name].\n".toProperty(), SelectGraphicAssetFragment::cancelable to false.toProperty() ).apply { title = "Select Tile Set for layer $name" @@ -129,7 +137,7 @@ class MainController : Controller() { find>( Scope(), SelectGraphicAssetFragment::assets to projectContext.project?.autoTiles!!, - SelectGraphicAssetFragment::comment to "You are importing a tile layer which originally was defined\nwith an other Auto Tile asset data with UID: [$uid].\nPlease select asset you would like to apply for layer $name.\n".toProperty(), + SelectGraphicAssetFragment::comment to "You are importing a tile layer which originally was defined\nwith an other Auto Tile asset data with UID: [$uid].\nPlease select asset you would like to apply for layer [$name].\n".toProperty(), SelectGraphicAssetFragment::cancelable to false.toProperty() ).apply { title = "Select Auto Tile for layer $name" diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/model/map/GameMapBuilder.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/model/map/GameMapBuilder.kt index 54585a19..361d4313 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/model/map/GameMapBuilder.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/model/map/GameMapBuilder.kt @@ -1,13 +1,9 @@ package com.bartlomiejpluta.base.editor.map.model.map -import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAsset -import javafx.beans.property.SimpleDoubleProperty import javafx.beans.property.SimpleIntegerProperty -import javafx.beans.property.SimpleObjectProperty import javafx.beans.property.SimpleStringProperty import tornadofx.getValue import tornadofx.setValue -import java.io.File class GameMapBuilder { val nameProperty = SimpleStringProperty("") @@ -28,6 +24,9 @@ class GameMapBuilder { val handlerProperty = SimpleStringProperty() var handler by handlerProperty + val handlerBaseClassProperty = SimpleStringProperty() + var handlerBaseClass by handlerBaseClassProperty + val fileProperty = SimpleStringProperty("") var file by fileProperty } \ No newline at end of file diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/view/wizard/MapCreationFragment.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/view/wizard/MapCreationFragment.kt index c833e086..3b990232 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/view/wizard/MapCreationFragment.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/view/wizard/MapCreationFragment.kt @@ -1,5 +1,6 @@ package com.bartlomiejpluta.base.editor.map.view.wizard +import com.bartlomiejpluta.base.editor.code.view.select.SelectJavaClassFragment import com.bartlomiejpluta.base.editor.map.model.map.GameMapBuilder import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapBuilderVM import com.bartlomiejpluta.base.editor.util.fx.TextFieldUtil @@ -96,6 +97,26 @@ class MapCreationFragment : Fragment("Basic Data") { trimWhitespace() } } + + field("Map Handler base class") { + hbox { + textfield(mapBuilderVM.handlerBaseClassProperty) { + trimWhitespace() + } + + button("Select") { + action { + find(Scope()).apply { + onComplete { className -> + mapBuilderVM.handlerBaseClassProperty.value = className + } + + openModal(block = true, resizable = false) + } + } + } + } + } } buttonbar { diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/view/wizard/MapImportFragment.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/view/wizard/MapImportFragment.kt index c9fb1421..6124ca23 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/view/wizard/MapImportFragment.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/view/wizard/MapImportFragment.kt @@ -1,5 +1,6 @@ package com.bartlomiejpluta.base.editor.map.view.wizard +import com.bartlomiejpluta.base.editor.code.view.select.SelectJavaClassFragment import com.bartlomiejpluta.base.editor.map.model.map.GameMapBuilder import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapBuilderVM import javafx.stage.FileChooser @@ -51,7 +52,7 @@ class MapImportFragment : Fragment("Basic Data") { } } - label("Only tile, object and color layers will be imported. Any image layers will be dropped out.") + label("Only tile, auto tile, object and color layers will be imported. Any image layers will be dropped out.") field("Map name") { textfield(mapBuilderVM.nameProperty) { @@ -65,6 +66,26 @@ class MapImportFragment : Fragment("Basic Data") { trimWhitespace() } } + + field("Map Handler base class") { + hbox { + textfield(mapBuilderVM.handlerBaseClassProperty) { + trimWhitespace() + } + + button("Select") { + action { + find(Scope()).apply { + onComplete { className -> + mapBuilderVM.handlerBaseClassProperty.value = className + } + + openModal(block = true, resizable = false) + } + } + } + } + } } buttonbar { diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/viewmodel/GameMapBuilderVM.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/viewmodel/GameMapBuilderVM.kt index 99de21b9..de337384 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/viewmodel/GameMapBuilderVM.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/viewmodel/GameMapBuilderVM.kt @@ -24,6 +24,9 @@ class GameMapBuilderVM : ItemViewModel(GameMapBuilder()) { val handlerProperty = bind(GameMapBuilder::handlerProperty, autocommit = true) var handler by handlerProperty + val handlerBaseClassProperty = bind(GameMapBuilder::handlerBaseClassProperty, autocommit = true) + var handlerBaseClass by handlerBaseClassProperty + val fileProperty = bind(GameMapBuilder::fileProperty, autocommit = true) var file by fileProperty } \ No newline at end of file diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/project/context/DefaultProjectContext.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/project/context/DefaultProjectContext.kt index 5a937512..37d10e87 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/project/context/DefaultProjectContext.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/project/context/DefaultProjectContext.kt @@ -1,5 +1,6 @@ package com.bartlomiejpluta.base.editor.project.context +import com.bartlomiejpluta.base.api.map.handler.MapHandler import com.bartlomiejpluta.base.editor.animation.asset.AnimationAsset import com.bartlomiejpluta.base.editor.animation.asset.AnimationAssetData import com.bartlomiejpluta.base.editor.asset.model.Asset @@ -101,7 +102,7 @@ class DefaultProjectContext : ProjectContext { javaClassService.createClassFile(project.runner, project.codeFSNode, "game_runner.ftl") } - override fun importMap(name: String, map: GameMap) { + override fun importMap(name: String, handlerBaseClass: String?, map: GameMap) { project?.let { UID.next(it.maps.map(Asset::uid)).let { uid -> val asset = GameMapAsset(it, uid, name) @@ -120,6 +121,9 @@ class DefaultProjectContext : ProjectContext { } } model["map_code"] = name.split("\\s+".toRegex()).joinToString("_") { part -> part.lowercase() } + model["inheritanceKeyword"] = handlerBaseClass?.let { "extends " } ?: "implements" + model["mapBaseClassName"] = handlerBaseClass?.substringAfterLast(".") ?: MAP_HANDLER_NAME + model["mapBaseImport"] = handlerBaseClass ?: MAP_HANDLER_CANONICAL_NAME } File(it.mapsDirectory, asset.source).outputStream().use { fos -> mapSerializer.serialize(map, fos) } @@ -130,6 +134,7 @@ class DefaultProjectContext : ProjectContext { override fun importMapFromFile( name: String, handler: String, + handlerBaseClass: String?, file: File, replaceTileSet: (String, String) -> String, replaceAutoTile: (String, String) -> String, @@ -145,6 +150,17 @@ class DefaultProjectContext : ProjectContext { javaClassService.createClassFile(handler, project.codeFSNode, "map_handler.ftl") { model -> model["mapUid"] = uid + model["mapName"] = name + model["mapCode"] = name.split("\\s+".toRegex()).joinToString("") { part -> + part.replaceFirstChar { c -> + if (c.isLowerCase()) c.titlecase(Locale.getDefault()) + else c.toString() + } + } + model["map_code"] = name.split("\\s+".toRegex()).joinToString("_") { part -> part.lowercase() } + model["inheritanceKeyword"] = handlerBaseClass?.let { "extends" } ?: "implements" + model["mapBaseClassName"] = handlerBaseClass?.substringAfterLast(".") ?: MAP_HANDLER_NAME + model["mapBaseImport"] = handlerBaseClass ?: MAP_HANDLER_CANONICAL_NAME } File(project.mapsDirectory, asset.source).outputStream().use { fos -> mapSerializer.serialize(map, fos) } @@ -361,4 +377,9 @@ class DefaultProjectContext : ProjectContext { override fun saveScript(code: Code) { code.fileNode.writeText(code.code) } + + companion object { + private val MAP_HANDLER_NAME = MapHandler::class.java.simpleName + private val MAP_HANDLER_CANONICAL_NAME = MapHandler::class.java.canonicalName + } } \ No newline at end of file diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/project/context/ProjectContext.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/project/context/ProjectContext.kt index c6ae2bfb..499513f8 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/project/context/ProjectContext.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/project/context/ProjectContext.kt @@ -32,9 +32,16 @@ interface ProjectContext { fun open(file: File) fun createNewProject(project: Project) - fun importMap(name: String, map: GameMap) - fun importMapFromFile(name: String, handler: String, file: File, replaceTileSet: (String, String) -> String, replaceAutoTile: (String, String) -> String, + fun importMap(name: String, handlerBaseClass: String?, map: GameMap) + fun importMapFromFile( + name: String, + handler: String, + handlerBaseClass: String?, + file: File, + replaceTileSet: (String, String) -> String, + replaceAutoTile: (String, String) -> String, ): GameMap + fun loadMap(uid: String): GameMap fun saveMap(map: GameMap) diff --git a/editor/src/main/resources/java_templates/game_runner.ftl b/editor/src/main/resources/java_templates/game_runner.ftl index 79f95cb5..2ad3829d 100644 --- a/editor/src/main/resources/java_templates/game_runner.ftl +++ b/editor/src/main/resources/java_templates/game_runner.ftl @@ -10,9 +10,12 @@ import com.bartlomiejpluta.base.api.runner.GameRunner; public class ${className} implements GameRunner { private static final Logger log = LoggerFactory.getLogger(${className}.class); + private static ${className} INSTANCE; @Override public void init(Context context) { + ${className}.INSTANCE = this; + // Resume engine, because it is initially paused context.resume(); @@ -21,7 +24,7 @@ public class ${className} implements GameRunner { } @Override - public void input(Screen screen) { + public void input(Input input) { } @@ -34,4 +37,8 @@ public class ${className} implements GameRunner { public void dispose() { // Do something after game loop is end } + + public static ${className} instance() { + return INSTANCE; + } } \ No newline at end of file diff --git a/editor/src/main/resources/java_templates/map_handler.ftl b/editor/src/main/resources/java_templates/map_handler.ftl index a412ad2b..7c6ce6c0 100644 --- a/editor/src/main/resources/java_templates/map_handler.ftl +++ b/editor/src/main/resources/java_templates/map_handler.ftl @@ -1,12 +1,12 @@ package ${package}; +import ${mapBaseImport}; import com.bartlomiejpluta.base.api.context.Context; import com.bartlomiejpluta.base.api.input.Input; import com.bartlomiejpluta.base.api.map.model.GameMap; -import com.bartlomiejpluta.base.api.map.handler.MapHandler; import com.bartlomiejpluta.base.api.screen.Screen; -public class ${className} implements MapHandler { +public class ${className} ${inheritanceKeyword} ${mapBaseClassName} { @Override public void onCreate(Context context, GameMap map) {