diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/model/map/brush/Brush.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/model/map/brush/Brush.kt index 6fffb29c..9797f2b3 100755 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/model/map/brush/Brush.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/model/map/brush/Brush.kt @@ -14,21 +14,19 @@ class Brush { val rowsProperty = SimpleIntegerProperty(this, "", 0) var rows by rowsProperty + private set val columnsProperty = SimpleIntegerProperty(0) var columns by columnsProperty - - val centerRowProperty = SimpleIntegerProperty(0) - var centerRow by centerRowProperty - - val centerColumnProperty = SimpleIntegerProperty(0) - var centerColumn by centerColumnProperty + private set val brushRangeProperty = SimpleIntegerProperty(1) var brushRange by brushRangeProperty + private set val modeProperty = SimpleObjectProperty(BrushMode.PAINTING_MODE) var mode by modeProperty + private set private constructor(brushArray: Array>) { rowsProperty.value = brushArray.size @@ -40,9 +38,6 @@ class Brush { if (rowsProperty.value > 0) { columns = brush.size / rowsProperty.value } - - centerRow = rows / 2 - centerColumn = columns / 2 } private constructor(brush: List, rows: Int, columns: Int) { @@ -50,32 +45,53 @@ class Brush { this.columns = columns this.brush = brush.asObservable() - - centerRow = rows / 2 - centerColumn = columns / 2 } - fun forEach(consumer: (row: Int, column: Int, tile: Tile?) -> Unit) { - brush.forEachIndexed { id, tile -> - consumer(id / columns, id % columns, when(mode) { - BrushMode.PAINTING_MODE -> tile - BrushMode.ERASING_MODE -> null - }) + fun forEach(consumer: (row: Int, column: Int, centerRow: Int, centerColumn: Int, tile: Tile?) -> Unit) { + return when { + brushRange > 1 || mode == BrushMode.ERASING_MODE -> forEachInRangedBrush(consumer) + else -> forEachInRegularBrush(consumer) } } - fun withBrushRange(range: Int) = Brush(Array(range) { Array(range) { brush[0] } }).apply { - brushRange = range + private fun forEachInRangedBrush(consumer: (row: Int, column: Int, centerRow: Int, centerColumn: Int, tile: Tile?) -> Unit) { + val center = brushRange / 2 + + (0 until brushRange).forEach { row -> + (0 until brushRange).forEach { column -> + consumer(row, column, center, center, getTileByMode(brush[0])) + } + } + } + + private fun getTileByMode(tile: Tile) = when (mode) { + BrushMode.PAINTING_MODE -> tile + BrushMode.ERASING_MODE -> null + } + + private fun forEachInRegularBrush(consumer: (row: Int, column: Int, centerRow: Int, centerColumn: Int, tile: Tile?) -> Unit) { + val centerRow = rows / 2 + val centerColumn = columns / 2 + + brush.forEachIndexed { id, tile -> + consumer(id / columns, id % columns, centerRow, centerColumn, getTileByMode(tile)) + } + } + + private fun clone() = Brush(brush, rows, columns).apply { + brushRange = this@Brush.brushRange mode = this@Brush.mode } - fun withErasingMode() = Brush(brush, rows, columns).apply { - brushRange = this@Brush.brushRange + fun withBrushRange(range: Int) = clone().apply { + brushRange = range + } + + fun withErasingMode() = clone().apply { mode = BrushMode.ERASING_MODE } - fun withPaintingMode() = Brush(brush, rows, columns).apply { - brushRange = this@Brush.brushRange + fun withPaintingMode() = clone().apply { mode = BrushMode.PAINTING_MODE } diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/map/MapPainter.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/map/MapPainter.kt index a85cd021..a2f770cd 100755 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/map/MapPainter.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/map/MapPainter.kt @@ -27,17 +27,21 @@ class MapPainter( val alpha = gc.globalAlpha gc.globalAlpha = 0.4 - brushVM.forEach { row, column, tile -> tile?.let { renderTile(gc, it, column, row) } } + brushVM.forEach { row, column, centerRow, centerColumn, tile -> + tile?.let { + renderTile(gc, it, column, row, centerRow, centerColumn) + } + } gc.globalAlpha = alpha } - private fun renderTile(gc: GraphicsContext, tile: Tile, column: Int, row: Int) { + private fun renderTile(gc: GraphicsContext, tile: Tile, column: Int, row: Int, centerRow: Int, centerColumn: Int) { gc.drawImage( tile.image, - tileWidth * (mouseColumn - brushVM.centerColumn + column), - tileHeight * (mouseRow - brushVM.centerRow + row) + tileWidth * (mouseColumn - centerColumn + column), + tileHeight * (mouseRow - centerRow + row) ) } @@ -55,13 +59,8 @@ class MapPainter( private fun beginTrace(event: MapMouseEvent) { if (event.button == MouseButton.PRIMARY && mapVM.selectedLayer >= 0) { currentTrace = MapPaintingTrace(mapVM, "Paint trace").apply { - brushVM.forEach { row, column, tile -> - paint( - map.selectedLayer, - mouseRow - brushVM.centerRow + row, - mouseColumn - brushVM.centerColumn + column, - tile - ) + brushVM.forEach { row, column, centerRow, centerColumn, tile -> + paint(map.selectedLayer, mouseRow - centerRow + row, mouseColumn - centerColumn + column, tile) } } } @@ -70,13 +69,8 @@ class MapPainter( private fun proceedTrace(event: MapMouseEvent) { if (event.button == MouseButton.PRIMARY) { currentTrace?.apply { - brushVM.forEach { row, column, tile -> - paint( - map.selectedLayer, - mouseRow - brushVM.centerRow + row, - mouseColumn - brushVM.centerColumn + column, - tile - ) + brushVM.forEach { row, column, centerRow, centerColumn, tile -> + paint(map.selectedLayer, mouseRow - centerRow + row, mouseColumn - centerColumn + column, tile) } } } diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/view/component/tileset/TileSetPane.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/view/component/tileset/TileSetPane.kt index 0216fde4..5b3970d4 100755 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/view/component/tileset/TileSetPane.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/view/component/tileset/TileSetPane.kt @@ -26,11 +26,12 @@ class TileSetPane(private val gameMapVM: GameMapVM, brushVM: BrushVM) : Canvas() // when brush range (size) is increased to 2 or more // (because the range-increased brush can only include // the tile of one type). - brushVM.brushRangeProperty.addListener { _, _, newValue -> - if (newValue.toInt() > 1) { + brushVM.itemProperty.addListener { _, _, brush -> + if (brush.brushRange > 1) { selection.shrinkToTopLeftTile() - render() } + + render() } render() diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/view/map/MapToolbarView.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/view/map/MapToolbarView.kt index 6993e372..62f57650 100755 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/view/map/MapToolbarView.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/view/map/MapToolbarView.kt @@ -8,7 +8,9 @@ import com.bartlomiejpluta.base.editor.viewmodel.map.BrushVM import com.bartlomiejpluta.base.editor.viewmodel.map.GameMapVM import javafx.scene.control.ToggleGroup import org.kordamp.ikonli.javafx.FontIcon +import org.slf4j.LoggerFactory import tornadofx.* +import java.util.* import kotlin.math.max class MapToolbarView : View() { @@ -20,8 +22,8 @@ class MapToolbarView : View() { private val brushVM = find() private val brushMode = ToggleGroup().apply { - brushVM.erasingProperty.addListener { _, _, newValue -> - selectedValueProperty().value = newValue + brushVM.itemProperty.addListener { _, _, brush -> + selectedValueProperty().value = brush.mode } } @@ -101,8 +103,8 @@ class MapToolbarView : View() { brushVM.item = brushVM.withBrushRange(newValue.toInt()) } - brushVM.brushRangeProperty.addListener { _, _, newValue -> - value = newValue.toDouble() + brushVM.itemProperty.addListener { _, _, brush -> + value = brush.brushRange.toDouble() } } diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/viewmodel/map/BrushVM.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/viewmodel/map/BrushVM.kt index 41f14e3e..7942a8a9 100755 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/viewmodel/map/BrushVM.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/viewmodel/map/BrushVM.kt @@ -2,7 +2,8 @@ package com.bartlomiejpluta.base.editor.viewmodel.map import com.bartlomiejpluta.base.editor.model.map.brush.Brush import com.bartlomiejpluta.base.editor.model.tileset.Tile -import tornadofx.* +import tornadofx.ItemViewModel +import tornadofx.getValue class BrushVM : ItemViewModel(Brush.of(arrayOf(arrayOf()))) { val brush = bind(Brush::brush) @@ -13,19 +14,13 @@ class BrushVM : ItemViewModel(Brush.of(arrayOf(arrayOf()))) { val columnsProperty = bind(Brush::columnsProperty) val columns by columnsProperty - val centerRowProperty = bind(Brush::centerRowProperty) - val centerRow by centerRowProperty - - val centerColumnProperty = bind(Brush::centerColumnProperty) - val centerColumn by centerColumnProperty - val brushRangeProperty = bind(Brush::brushRangeProperty) - var brushRange by brushRangeProperty + val brushRange by brushRangeProperty - val erasingProperty = bind(Brush::modeProperty) - var erasing by erasingProperty + val modeProperty = bind(Brush::modeProperty) + val mode by modeProperty - fun forEach(consumer: (row: Int, column: Int, tile: Tile?) -> Unit) = item.forEach(consumer) + fun forEach(consumer: (row: Int, column: Int, centerRow: Int, centerColumn: Int, tile: Tile?) -> Unit) = item.forEach(consumer) fun withBrushRange(range: Int) = item.withBrushRange(range)