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 new file mode 100755 index 00000000..1e6ef7ba --- /dev/null +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/model/map/brush/Brush.kt @@ -0,0 +1,41 @@ +package com.bartlomiejpluta.base.editor.model.map.brush + +import com.bartlomiejpluta.base.editor.model.tileset.Tile +import javafx.beans.property.SimpleIntegerProperty +import tornadofx.* + +class Brush { + val brush = observableListOf() + val rowsProperty = SimpleIntegerProperty(this, "", 0) + var rows by rowsProperty + val columnsProperty = SimpleIntegerProperty(0) + var columns by columnsProperty + val centerRowProperty = SimpleIntegerProperty(0) + var centerRow by centerRowProperty + val centerColumnProperty = SimpleIntegerProperty(0) + var centerColumn by centerColumnProperty + + + fun updateBrush(newBrush: Array>) { + brush.clear() + columns = 0 + rowsProperty.value = newBrush.size + + newBrush.forEach { brush.addAll(it) } + + if(rowsProperty.value > 0) { + columns = brush.size / rowsProperty.value + } + + centerRow = rows/2 + centerColumn = columns/2 + } + + fun tileAt(row: Int, column: Int) = brush[row * columns + column] + + fun forEach(consumer: (row: Int, column: Int, tile: Tile) -> Unit) { + brush.forEachIndexed { id, tile -> + consumer(id / columns, id % columns, tile) + } + } +} \ No newline at end of file diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/map/MapCanvas.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/map/MapCanvas.kt index e5619ef7..3fa61f04 100755 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/map/MapCanvas.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/map/MapCanvas.kt @@ -10,8 +10,7 @@ import com.bartlomiejpluta.base.editor.render.model.Renderable import javafx.scene.canvas.GraphicsContext -class MapCanvas(val map: GameMap, private val paintingCallback: (MapPaintingTrace) -> Unit) : Renderable, - MapMouseEventHandler { +class MapCanvas(val map: GameMap, private val painter: MapPainter) : Renderable { var tileSet = map.tileSet private var layers = map.layers private var rows = map.rows @@ -21,11 +20,6 @@ class MapCanvas(val map: GameMap, private val paintingCallback: (MapPaintingTrac private var mapWidth = map.width.toDouble() private var mapHeight = map.height.toDouble() - private var brush = MapBrush(map, arrayOf(arrayOf(tileSet.getTile(0, 0))), paintingCallback) - - fun setBrush(brush: Array>) { - this.brush = MapBrush(map, brush, paintingCallback) - } override fun render(gc: GraphicsContext) { gc.clearRect(0.0, 0.0, gc.canvas.width, gc.canvas.height); @@ -33,7 +27,7 @@ class MapCanvas(val map: GameMap, private val paintingCallback: (MapPaintingTrac layers.forEach { dispatchLayerRender(gc, it) } renderGrid(gc) - brush.render(gc) + painter.render(gc) } private fun dispatchLayerRender(gc: GraphicsContext, layer: Layer) { @@ -63,8 +57,4 @@ class MapCanvas(val map: GameMap, private val paintingCallback: (MapPaintingTrac gc.strokeLine(column * tileWidth, 0.0, column * tileWidth, mapHeight) } } - - override fun handleMouseInput(event: MapMouseEvent) { - brush.handleMouseInput(event) - } } \ No newline at end of file diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/map/MapBrush.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/map/MapPainter.kt similarity index 63% rename from editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/map/MapBrush.kt rename to editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/map/MapPainter.kt index 97d57fda..9b45ea1d 100755 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/map/MapBrush.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/map/MapPainter.kt @@ -1,5 +1,6 @@ package com.bartlomiejpluta.base.editor.render.canvas.map +import com.bartlomiejpluta.base.editor.model.map.brush.Brush import com.bartlomiejpluta.base.editor.model.map.map.GameMap import com.bartlomiejpluta.base.editor.model.tileset.Tile import com.bartlomiejpluta.base.editor.render.canvas.input.MapMouseEvent @@ -9,39 +10,24 @@ import javafx.scene.canvas.GraphicsContext import javafx.scene.input.MouseButton import javafx.scene.input.MouseEvent -class MapBrush( +class MapPainter( private val map: GameMap, - private val brush: Array>, + private val brush: Brush, private val paintingCallback: (MapPaintingTrace) -> Unit ) : Renderable, MapMouseEventHandler { private val tileWidth = map.tileSet.tileWidth.toDouble() private val tileHeight = map.tileSet.tileHeight.toDouble() - private val centerRow: Int - private val centerColumn: Int private var mouseRow = -1 private var mouseColumn = -1 private var currentTrace: MapPaintingTrace? = null - init { - if (brush.isEmpty() || brush[0].isEmpty()) { - throw IllegalStateException("Brush size must be at least 1x1") - } - - centerRow = brush.size / 2 - centerColumn = brush[0].size / 2 - } - override fun render(gc: GraphicsContext) { val alpha = gc.globalAlpha gc.globalAlpha = 0.4 - for ((row, columns) in brush.withIndex()) { - for ((column, tile) in columns.withIndex()) { - renderTile(gc, tile, column, row) - } - } + brush.forEach { row, column, tile -> renderTile(gc, tile, column, row) } gc.globalAlpha = alpha @@ -50,8 +36,8 @@ class MapBrush( private fun renderTile(gc: GraphicsContext, tile: Tile, column: Int, row: Int) { gc.drawImage( tile.image, - tileWidth * (mouseColumn - centerColumn + column), - tileHeight * (mouseRow - centerRow + row) + tileWidth * (mouseColumn - brush.centerColumn + column), + tileHeight * (mouseRow - brush.centerRow + row) ) } @@ -69,10 +55,8 @@ class MapBrush( private fun beginTrace(event: MapMouseEvent) { if (event.button == MouseButton.PRIMARY) { currentTrace = MapPaintingTrace(map, "Paint trace").apply { - for ((row, columns) in brush.withIndex()) { - for ((column, tile) in columns.withIndex()) { - paint(0, mouseRow - centerRow + row, mouseColumn - centerColumn + column, tile) - } + brush.forEach { row, column, tile -> + paint(0, mouseRow - brush.centerRow + row, mouseColumn - brush.centerColumn + column, tile) } } } @@ -81,10 +65,8 @@ class MapBrush( private fun proceedTrace(event: MapMouseEvent) { if (event.button == MouseButton.PRIMARY) { currentTrace?.apply { - for ((row, columns) in brush.withIndex()) { - for ((column, tile) in columns.withIndex()) { - paint(0, mouseRow - centerRow + row, mouseColumn - centerColumn + column, tile) - } + brush.forEach { row, column, tile -> + paint(0, mouseRow - brush.centerRow + row, mouseColumn - brush.centerColumn + column, tile) } } } diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/tileset/TileSetCanvas.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/tileset/TileSetCanvas.kt index 99bde9f8..8fd368e3 100755 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/tileset/TileSetCanvas.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/tileset/TileSetCanvas.kt @@ -1,5 +1,6 @@ package com.bartlomiejpluta.base.editor.render.canvas.tileset +import com.bartlomiejpluta.base.editor.model.map.brush.Brush import com.bartlomiejpluta.base.editor.model.tileset.Tile import com.bartlomiejpluta.base.editor.model.tileset.TileSet import com.bartlomiejpluta.base.editor.render.canvas.input.MapMouseEvent @@ -10,9 +11,9 @@ import javafx.scene.input.MouseButton import javafx.scene.input.MouseEvent import javafx.scene.paint.Color -class TileSetCanvas(private val tileSet: TileSet, selectionCallback: (Array>) -> Unit) : Renderable, MapMouseEventHandler { +class TileSetCanvas(private val tileSet: TileSet, brush: Brush) : Renderable, MapMouseEventHandler { private val tiles = tileSet.tiles - private var selection = TileSetSelection(tileSet, selectionCallback) + private var selection = TileSetSelection(tileSet, brush) private var mouseRow = -1 private var mouseColumn = -1 diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/tileset/TileSetSelection.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/tileset/TileSetSelection.kt index c31ecee4..16cf095b 100755 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/tileset/TileSetSelection.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/tileset/TileSetSelection.kt @@ -1,23 +1,18 @@ package com.bartlomiejpluta.base.editor.render.canvas.tileset +import com.bartlomiejpluta.base.editor.model.map.brush.Brush import com.bartlomiejpluta.base.editor.model.tileset.Tile import com.bartlomiejpluta.base.editor.model.tileset.TileSet import com.bartlomiejpluta.base.editor.render.model.Renderable -import javafx.collections.ObservableList import javafx.scene.canvas.GraphicsContext import javafx.scene.paint.Color -import org.apache.commons.logging.LogFactory -import org.slf4j.Logger -import org.slf4j.LoggerFactory -import tornadofx.observableListOf import kotlin.math.abs -import kotlin.math.max import kotlin.math.min class TileSetSelection( private val tileSet: TileSet, - private val selectionCallback: (Array>) -> Unit + private val brush: Brush ) : Renderable { private val tileWidth = tileSet.tileWidth.toDouble() private val tileHeight = tileSet.tileHeight.toDouble() @@ -66,13 +61,13 @@ class TileSetSelection( val rows = offsetRow.toInt() + 1 val columns = offsetColumn.toInt() + 1 - var brush = Array>(rows) { rowIndex -> + var brushArray = Array>(rows) { rowIndex -> Array(columns) { columnIndex -> tileSet.getTile(firstRow + rowIndex, firstColumn + columnIndex) } } - selectionCallback(brush) + brush.updateBrush(brushArray) } override fun render(gc: GraphicsContext) { diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/view/component/map/MapPane.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/view/component/map/MapPane.kt index 900f2759..6de0eda5 100755 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/view/component/map/MapPane.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/view/component/map/MapPane.kt @@ -4,15 +4,18 @@ import com.bartlomiejpluta.base.editor.model.map.map.GameMap import com.bartlomiejpluta.base.editor.model.tileset.Tile import com.bartlomiejpluta.base.editor.render.canvas.map.MapCanvas import com.bartlomiejpluta.base.editor.render.canvas.input.MapMouseEvent +import com.bartlomiejpluta.base.editor.model.map.brush.Brush +import com.bartlomiejpluta.base.editor.render.canvas.map.MapPainter import com.bartlomiejpluta.base.editor.render.canvas.map.MapPaintingTrace import javafx.event.EventHandler import javafx.scene.canvas.Canvas import javafx.scene.input.MouseEvent -class MapPane(map: GameMap, paintingCallback: (MapPaintingTrace) -> Unit) : Canvas(), EventHandler { +class MapPane(map: GameMap, brush: Brush, paintingCallback: (MapPaintingTrace) -> Unit) : Canvas(), EventHandler { private var tileSet = map.tileSet - private val mapCanvas = MapCanvas(map, paintingCallback) + private val painter = MapPainter(map, brush, paintingCallback) + private val mapCanvas = MapCanvas(map, painter) init { onMouseMoved = this @@ -26,7 +29,6 @@ class MapPane(map: GameMap, paintingCallback: (MapPaintingTrace) -> Unit) : Canv render() } - fun setBrush(brush: Array>) = mapCanvas.setBrush(brush) fun render() { mapCanvas.render(graphicsContext2D) @@ -34,7 +36,7 @@ class MapPane(map: GameMap, paintingCallback: (MapPaintingTrace) -> Unit) : Canv override fun handle(event: MouseEvent?) { if (event != null) { - mapCanvas.handleMouseInput(MapMouseEvent.of(event, tileSet)) + painter.handleMouseInput(MapMouseEvent.of(event, tileSet)) } mapCanvas.render(graphicsContext2D) 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 550ed21b..04720f2b 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 @@ -1,5 +1,6 @@ package com.bartlomiejpluta.base.editor.view.component.tileset +import com.bartlomiejpluta.base.editor.model.map.brush.Brush import com.bartlomiejpluta.base.editor.model.tileset.Tile import com.bartlomiejpluta.base.editor.model.tileset.TileSet import com.bartlomiejpluta.base.editor.render.canvas.input.MapMouseEvent @@ -8,8 +9,8 @@ import javafx.event.EventHandler import javafx.scene.canvas.Canvas import javafx.scene.input.MouseEvent -class TileSetPane(private val tileSet: TileSet, selectionCallback: (Array>) -> Unit) : Canvas(), EventHandler { - private val tileSetCanvas = TileSetCanvas(tileSet, selectionCallback) +class TileSetPane(private val tileSet: TileSet, brush: Brush) : Canvas(), EventHandler { + private val tileSetCanvas = TileSetCanvas(tileSet, brush) init { onMouseMoved = this diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/view/fragment/MapFragment.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/view/fragment/MapFragment.kt index 5845439a..ee38130c 100755 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/view/fragment/MapFragment.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/view/fragment/MapFragment.kt @@ -3,6 +3,7 @@ package com.bartlomiejpluta.base.editor.view.fragment import com.bartlomiejpluta.base.editor.command.service.UndoRedoService import com.bartlomiejpluta.base.editor.event.RedrawMapRequestEvent import com.bartlomiejpluta.base.editor.model.map.map.GameMap +import com.bartlomiejpluta.base.editor.model.map.brush.Brush import com.bartlomiejpluta.base.editor.view.component.map.MapPane import com.bartlomiejpluta.base.editor.view.component.tileset.TileSetPane import javafx.beans.property.SimpleDoubleProperty @@ -14,11 +15,13 @@ import tornadofx.* class MapFragment : Fragment() { private val undoRedoService: UndoRedoService by di() + + private val brush = Brush() val scaleProperty = SimpleDoubleProperty(1.0) val map: GameMap by param() - private val mapPane = MapPane(map) { undoRedoService.push(it) } - private val tileSetPane = TileSetPane(map.tileSet) { mapPane.setBrush(it) } + private val mapPane = MapPane(map, brush) { undoRedoService.push(it) } + private val tileSetPane = TileSetPane(map.tileSet, brush) private val transformation = Scale(1.0, 1.0, 0.0, 0.0).apply { xProperty().bind(scaleProperty)