diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/canvas/MapCanvas.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/canvas/MapCanvas.kt index e04f5bd9..fc19e950 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/canvas/MapCanvas.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/canvas/MapCanvas.kt @@ -150,11 +150,13 @@ class MapCanvas(val map: GameMapVM, private val editorStateVM: EditorStateVM, pr val x = imageLayer.x.toDouble() val y = imageLayer.y.toDouble() + when (imageLayer.mode) { - ImageLayerMode.NORMAL -> gc.drawImage(imageLayer.image, x, y) - ImageLayerMode.FIT_SCREEN -> gc.drawImage(imageLayer.image, x, y) ImageLayerMode.FIT_MAP -> gc.drawImage(imageLayer.image, x, y, map.width, map.height) else -> { + val width = imageLayer.image.width * imageLayer.scaleX + val height = imageLayer.image.height * imageLayer.scaleY + gc.drawImage(imageLayer.image, x, y, width, height) } } diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/model/enumeration/ImageLayerMode.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/model/enumeration/ImageLayerMode.kt index dc474423..1dd7a838 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/model/enumeration/ImageLayerMode.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/model/enumeration/ImageLayerMode.kt @@ -2,6 +2,6 @@ package com.bartlomiejpluta.base.editor.map.model.enumeration enum class ImageLayerMode { NORMAL, - FIT_SCREEN, - FIT_MAP + FIT_MAP, + FIT_SCREEN } \ No newline at end of file diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/model/layer/ImageLayer.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/model/layer/ImageLayer.kt index 1ed32562..4fa601c9 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/model/layer/ImageLayer.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/model/layer/ImageLayer.kt @@ -3,18 +3,28 @@ package com.bartlomiejpluta.base.editor.map.model.layer import com.bartlomiejpluta.base.editor.image.asset.ImageAsset import com.bartlomiejpluta.base.editor.map.model.enumeration.ImageLayerMode import javafx.beans.binding.Bindings.createObjectBinding -import javafx.beans.property.SimpleObjectProperty import javafx.beans.property.SimpleStringProperty import javafx.scene.image.Image import tornadofx.getValue import tornadofx.setValue +import tornadofx.toProperty -class ImageLayer(name: String, imageAsset: ImageAsset, x: Int, y: Int, mode: ImageLayerMode, opacity: Int) : Layer { +class ImageLayer( + name: String, + imageAsset: ImageAsset, + opacity: Int = 100, + x: Int = 0, + y: Int = 0, + scaleX: Double = 1.0, + scaleY: Double = 1.0, + mode: ImageLayerMode = ImageLayerMode.NORMAL, + parallax: Boolean = false +) : Layer { override val nameProperty = SimpleStringProperty(name) override var name by nameProperty - val imageAssetProperty = SimpleObjectProperty(imageAsset) + val imageAssetProperty = imageAsset.toProperty() var imageAsset by imageAssetProperty val imageProperty = createObjectBinding({ @@ -23,18 +33,26 @@ class ImageLayer(name: String, imageAsset: ImageAsset, x: Int, y: Int, mode: Ima val image by imageProperty - val opacityProperty = SimpleObjectProperty(opacity) + val opacityProperty = opacity.toProperty() var opacity by opacityProperty - val modeProperty = SimpleObjectProperty(mode) - var mode by modeProperty - - val xProperty = SimpleObjectProperty(x) + val xProperty = x.toProperty() var x by xProperty - val yProperty = SimpleObjectProperty(y) + val yProperty = y.toProperty() var y by yProperty + val scaleXProperty = scaleX.toProperty() + var scaleX by scaleXProperty + + val scaleYProperty = scaleY.toProperty() + var scaleY by scaleYProperty + + val modeProperty = mode.toProperty() + var mode by modeProperty + + val parallaxProperty = parallax.toProperty() + var parallax by parallaxProperty override fun resize(rows: Int, columns: Int) { // We essentially need to do nothing diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/parameter/layer/ImageLayerParametersBinder.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/parameter/layer/ImageLayerParametersBinder.kt index f5616291..949bde17 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/parameter/layer/ImageLayerParametersBinder.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/parameter/layer/ImageLayerParametersBinder.kt @@ -1,12 +1,10 @@ package com.bartlomiejpluta.base.editor.map.parameter.layer -import com.bartlomiejpluta.base.editor.common.parameter.model.EnumParameter -import com.bartlomiejpluta.base.editor.common.parameter.model.GraphicAssetParameter -import com.bartlomiejpluta.base.editor.common.parameter.model.IntegerParameter -import com.bartlomiejpluta.base.editor.common.parameter.model.Parameter +import com.bartlomiejpluta.base.editor.common.parameter.model.* import com.bartlomiejpluta.base.editor.map.model.enumeration.ImageLayerMode import com.bartlomiejpluta.base.editor.map.model.layer.ImageLayer import com.bartlomiejpluta.base.editor.project.model.Project +import javafx.beans.binding.Bindings.createBooleanBinding import javafx.collections.ObservableList import org.springframework.stereotype.Component @@ -28,10 +26,6 @@ class ImageLayerParametersBinder : LayerParametersBinder { onCommit() } - val mode = EnumParameter("mode", ImageLayerMode.NORMAL, autocommit = true) { _, _, _ -> - onCommit() - } - val x = IntegerParameter("x", 0, autocommit = true) { _, _, _ -> onCommit() } @@ -40,12 +34,43 @@ class ImageLayerParametersBinder : LayerParametersBinder { onCommit() } + val scaleX = DoubleParameter("scaleX", 1.0, 0.0, Double.MAX_VALUE, 0.01, autocommit = true) { _, _, _ -> + onCommit() + } + + val scaleY = DoubleParameter("scaleY", 1.0, 0.0, Double.MAX_VALUE, 0.01, autocommit = true) { _, _, _ -> + onCommit() + } + + val mode = EnumParameter("mode", ImageLayerMode.NORMAL, autocommit = true) { _, _, _ -> + onCommit() + } + + val parallax = BooleanParameter("parallax") { _, _, _ -> + onCommit() + } + image.bindBidirectional(layer.imageAssetProperty) opacity.bindBidirectional(layer.opacityProperty) - mode.bindBidirectional(layer.modeProperty) x.bindBidirectional(layer.xProperty) y.bindBidirectional(layer.yProperty) + scaleX.bindBidirectional(layer.scaleXProperty) + scaleY.bindBidirectional(layer.scaleYProperty) + mode.bindBidirectional(layer.modeProperty) + parallax.bindBidirectional(layer.parallaxProperty) - parameters.addAll(image, opacity, mode, x, y) + val isNormalMode = createBooleanBinding({ mode.value == ImageLayerMode.NORMAL }, mode.valueProperty).apply { + addListener { _, _, value -> + if (!value) { + scaleX.value = 1.0 + scaleY.value = 1.0 + } + } + } + + scaleX.editableProperty.bind(isNormalMode) + scaleY.editableProperty.bind(isNormalMode) + + parameters.addAll(image, opacity, x, y, scaleX, scaleY, mode, parallax) } } \ No newline at end of file diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/serial/ProtobufMapDeserializer.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/serial/ProtobufMapDeserializer.kt index ae720cf3..ad9f0f62 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/serial/ProtobufMapDeserializer.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/serial/ProtobufMapDeserializer.kt @@ -88,14 +88,17 @@ class ProtobufMapDeserializer : MapDeserializer { return ImageLayer( name = proto.name, imageAsset = projectContext.findImageAsset(proto.imageLayer.imageUID), + opacity = proto.imageLayer.opacity, x = proto.imageLayer.x, y = proto.imageLayer.y, - opacity = proto.imageLayer.opacity, + scaleX = proto.imageLayer.scaleX, + scaleY = proto.imageLayer.scaleY, mode = when (proto.imageLayer.mode!!) { GameMapProto.ImageLayerMode.NORMAL -> ImageLayerMode.NORMAL - GameMapProto.ImageLayerMode.FIT_SCREEN -> ImageLayerMode.FIT_SCREEN GameMapProto.ImageLayerMode.FIT_MAP -> ImageLayerMode.FIT_MAP - } + GameMapProto.ImageLayerMode.FIT_SCREEN -> ImageLayerMode.FIT_SCREEN + }, + parallax = proto.imageLayer.parallax ) } } diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/serial/ProtobufMapSerializer.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/serial/ProtobufMapSerializer.kt index 8e7da87f..1e35db8d 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/serial/ProtobufMapSerializer.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/serial/ProtobufMapSerializer.kt @@ -57,15 +57,18 @@ class ProtobufMapSerializer : MapSerializer { is ImageLayer -> GameMapProto.ImageLayer.newBuilder() .setImageUID(layer.imageAsset.uid) .setOpacity(layer.opacity) + .setX(layer.x) + .setY(layer.y) + .setScaleX(layer.scaleX) + .setScaleY(layer.scaleY) .setMode( when (layer.mode!!) { ImageLayerMode.NORMAL -> GameMapProto.ImageLayerMode.NORMAL - ImageLayerMode.FIT_SCREEN -> GameMapProto.ImageLayerMode.FIT_SCREEN ImageLayerMode.FIT_MAP -> GameMapProto.ImageLayerMode.FIT_MAP + ImageLayerMode.FIT_SCREEN -> GameMapProto.ImageLayerMode.FIT_SCREEN } ) - .setX(layer.x) - .setY(layer.y) + .setParallax(layer.parallax) .build() .let { GameMapProto.Layer.newBuilder().setName(layer.name).setImageLayer(it).build() } diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/view/editor/MapLayersView.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/view/editor/MapLayersView.kt index 986e0975..c867153f 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/view/editor/MapLayersView.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/map/view/editor/MapLayersView.kt @@ -9,7 +9,6 @@ import com.bartlomiejpluta.base.editor.command.model.map.RenameLayerCommand import com.bartlomiejpluta.base.editor.command.service.UndoRedoService import com.bartlomiejpluta.base.editor.event.RedrawMapRequestEvent import com.bartlomiejpluta.base.editor.image.asset.ImageAsset -import com.bartlomiejpluta.base.editor.map.model.enumeration.ImageLayerMode import com.bartlomiejpluta.base.editor.map.model.layer.* import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM @@ -91,7 +90,7 @@ class MapLayersView : View() { SelectGraphicAssetFragment::assets to projectContext.project?.images!! ).apply { onComplete { - val layer = ImageLayer("Layer ${mapVM.layers.size + 1}", it, 0, 0, ImageLayerMode.NORMAL, 100) + val layer = ImageLayer("Layer ${mapVM.layers.size + 1}", it) val command = CreateLayerCommand(mapVM.item, layer) command.execute() layersPane.selectionModel.select(mapVM.layers.size - 1) diff --git a/proto/src/main/proto/map.proto b/proto/src/main/proto/map.proto index 34853c25..a2a1d7db 100644 --- a/proto/src/main/proto/map.proto +++ b/proto/src/main/proto/map.proto @@ -49,13 +49,16 @@ message ColorLayer { message ImageLayer { required string imageUID = 1; required uint32 opacity = 2; - required ImageLayerMode mode = 3; - required int32 x = 4; - required int32 y = 5; + required int32 x = 3; + required int32 y = 4; + required double scaleX = 5; + required double scaleY = 6; + required ImageLayerMode mode = 7; + required bool parallax = 8; } enum ImageLayerMode { - NORMAL = 0; - FIT_SCREEN = 1; + NORMAL = 1; FIT_MAP = 2; -} + FIT_SCREEN = 3; +} \ No newline at end of file