From e5f1ef12608a957745740ecccbc72befe23737a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Przemys=C5=82aw=20Pluta?= Date: Thu, 4 Feb 2021 18:41:21 +0100 Subject: [PATCH] [Editor] Create brushes --- .../base/editor/render/canvas/map/MapBrush.kt | 92 +++++++++++++++++++ .../editor/render/canvas/map/MapCanvas.kt | 73 ++++++++------- .../render/canvas/map/MapPaintingTrace.kt | 2 +- .../base/editor/view/component/map/MapPane.kt | 18 +++- 4 files changed, 147 insertions(+), 38 deletions(-) create mode 100755 editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/map/MapBrush.kt 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/MapBrush.kt new file mode 100755 index 00000000..6939ce53 --- /dev/null +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/map/MapBrush.kt @@ -0,0 +1,92 @@ +package com.bartlomiejpluta.base.editor.render.canvas.map + +import com.bartlomiejpluta.base.editor.model.map.map.GameMap +import com.bartlomiejpluta.base.editor.model.tileset.Tile +import com.bartlomiejpluta.base.editor.render.model.Renderable +import javafx.scene.canvas.GraphicsContext +import javafx.scene.input.MouseEvent + +class MapBrush( + private val map: GameMap, + private val brush: Array>, + private val paintingCallback: (MapPaintingTrace) -> Unit +) : Renderable { + 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) + } + } + + gc.globalAlpha = alpha + + } + + private fun renderTile(gc: GraphicsContext, tile: Tile, column: Int, row: Int) { + gc.drawImage( + tile.image, + tileWidth * (mouseColumn - centerColumn + column), + tileHeight * (mouseRow - centerRow + row) + ) + } + + fun handleMouseInput(event: MapMouseEvent) { + mouseRow = event.row + mouseColumn = event.column + + when (event.type) { + MouseEvent.MOUSE_PRESSED -> beginTrace() + MouseEvent.MOUSE_DRAGGED -> proceedTrace() + MouseEvent.MOUSE_RELEASED -> commitTrace() + } + } + + private fun commitTrace() { + currentTrace?.let { + paintingCallback(it) + currentTrace = null + } + } + + private fun proceedTrace() { + currentTrace?.apply { + for ((row, columns) in brush.withIndex()) { + for ((column, tile) in columns.withIndex()) { + paint(0, mouseRow - centerRow + row, mouseColumn - centerColumn + column, tile) + } + } + } + } + + private fun beginTrace() { + 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) + } + } + } + } +} \ 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 e7c18433..002ef564 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 @@ -3,16 +3,13 @@ package com.bartlomiejpluta.base.editor.render.canvas.map import com.bartlomiejpluta.base.editor.model.map.map.GameMap import com.bartlomiejpluta.base.editor.model.map.layer.Layer import com.bartlomiejpluta.base.editor.model.map.layer.TileLayer -import com.bartlomiejpluta.base.editor.model.tileset.TileSet import com.bartlomiejpluta.base.editor.render.model.Renderable import javafx.scene.canvas.GraphicsContext -import javafx.scene.input.MouseEvent -import javafx.scene.paint.Color import org.apache.commons.logging.LogFactory -class MapCanvas(private val map: GameMap, private val paintingCallback: (MapPaintingTrace) -> Unit) : Renderable { - private var tileSet = map.tileSet +class MapCanvas(val map: GameMap, var brush: MapBrush) : Renderable { + var tileSet = map.tileSet private var layers = map.layers private var rows = map.rows private var columns = map.columns @@ -21,10 +18,20 @@ class MapCanvas(private val map: GameMap, private val paintingCallback: (MapPain private var mapWidth = map.width.toDouble() private var mapHeight = map.height.toDouble() - private var mouseColumn = -1 - private var mouseRow = -1 + var mouseColumn = -1 + private set + + var mouseRow = -1 + private set + + // private val brush = MapBrush( +// this, arrayOf( +// arrayOf(tileSet.getTile(140, 4), tileSet.getTile(140, 4), tileSet.getTile(140, 4)), +// arrayOf(tileSet.getTile(140, 4), tileSet.getTile(140, 4), tileSet.getTile(140, 4)), +// arrayOf(tileSet.getTile(140, 4), tileSet.getTile(140, 4), tileSet.getTile(140, 4)) +// ) +// ) - private var currentTrace: MapPaintingTrace? = null override fun render(gc: GraphicsContext) { @@ -64,42 +71,40 @@ class MapCanvas(private val map: GameMap, private val paintingCallback: (MapPain } private fun renderCursor(gc: GraphicsContext) { - if (mouseColumn >= 0 && mouseRow >= 0) { - gc.fill = CURSOR_BRUSH - gc.fillRect(mouseColumn * tileWidth, mouseRow * tileHeight, tileWidth, tileHeight) +// if (mouseColumn >= 4 && mouseRow >= 4) { +// gc.globalAlpha.let { alpha -> +// gc.globalAlpha = 0.4 +// gc.drawImage(tile.image, mouseColumn * tileWidth, mouseRow * tileHeight) +// gc.globalAlpha = alpha +// } - gc.fill = CURSOR_STROKE_BRUSH - gc.strokeRect(mouseColumn * tileWidth, mouseRow * tileHeight, tileWidth, tileHeight) - } + brush.render(gc) +// } } fun handleMouseInput(event: MapMouseEvent) { mouseRow = event.row mouseColumn = event.column - val tile = tileSet.getTile(24, 4) - - when (event.type) { - MouseEvent.MOUSE_PRESSED -> { - currentTrace = MapPaintingTrace(map, "Paint trace").apply { - paint(0, mouseRow, mouseColumn, tile) - } - } - - MouseEvent.MOUSE_DRAGGED -> currentTrace?.apply { - paint(0, mouseRow, mouseColumn, tile) - } - - MouseEvent.MOUSE_RELEASED -> currentTrace?.let { - paintingCallback(it) - currentTrace = null - } - } +// when (event.type) { +// MouseEvent.MOUSE_PRESSED -> { +// currentTrace = MapPaintingTrace(map, "Paint trace").apply { +// paint(0, mouseRow, mouseColumn, tile) +// } +// } +// +// MouseEvent.MOUSE_DRAGGED -> currentTrace?.apply { +// paint(0, mouseRow, mouseColumn, tile) +// } +// +// MouseEvent.MOUSE_RELEASED -> currentTrace?.let { +// paintingCallback(it) +// currentTrace = null +// } +// } } companion object { - val CURSOR_BRUSH = Color.color(0.7, 0.3, 0.8, 0.6) - val CURSOR_STROKE_BRUSH = Color.color(0.7, 0.3, 0.8, 1.0) private val log = LogFactory.getLog(MapCanvas::class.java) } } \ No newline at end of file diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/map/MapPaintingTrace.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/map/MapPaintingTrace.kt index 37d8b8d9..19a71b7d 100755 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/map/MapPaintingTrace.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/render/canvas/map/MapPaintingTrace.kt @@ -10,7 +10,7 @@ data class MapPaintingTrace(val map: GameMap, override val commandName: String) private val trace = mutableListOf() fun paint(layerIndex: Int, row: Int, column: Int, tile: Tile?) { - if (row >= map.rows || column >= map.columns) { + if (row >= map.rows || column >= map.columns || row < 0 || column < 0) { return } 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 8b3f6952..780425c3 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 @@ -1,7 +1,7 @@ package com.bartlomiejpluta.base.editor.view.component.map import com.bartlomiejpluta.base.editor.model.map.map.GameMap -import com.bartlomiejpluta.base.editor.model.tileset.TileSet +import com.bartlomiejpluta.base.editor.render.canvas.map.MapBrush import com.bartlomiejpluta.base.editor.render.canvas.map.MapCanvas import com.bartlomiejpluta.base.editor.render.canvas.map.MapMouseEvent import com.bartlomiejpluta.base.editor.render.canvas.map.MapPaintingTrace @@ -9,9 +9,18 @@ import javafx.event.EventHandler import javafx.scene.canvas.Canvas import javafx.scene.input.MouseEvent + + class MapPane(map: GameMap, paintingCallback: (MapPaintingTrace) -> Unit) : Canvas(), EventHandler { private var tileSet = map.tileSet - private val mapCanvas = MapCanvas(map, paintingCallback) + private var brush: MapBrush + private val mapCanvas: MapCanvas + + private val brushDefinition = arrayOf( + arrayOf(tileSet.getTile(140, 4), tileSet.getTile(140, 5), tileSet.getTile(140, 6)), + arrayOf(tileSet.getTile(141, 4), tileSet.getTile(141, 5), tileSet.getTile(141, 6)), + arrayOf(tileSet.getTile(142, 4), tileSet.getTile(142, 5), tileSet.getTile(142, 6)) + ) init { onMouseMoved = this @@ -19,6 +28,9 @@ class MapPane(map: GameMap, paintingCallback: (MapPaintingTrace) -> Unit) : Canv onMousePressed = this onMouseReleased = this + brush = MapBrush(map, brushDefinition, paintingCallback) + mapCanvas = MapCanvas(map, brush) + tileSet = map.tileSet width = map.width.toDouble() height = map.height.toDouble() @@ -31,7 +43,7 @@ class MapPane(map: GameMap, paintingCallback: (MapPaintingTrace) -> Unit) : Canv override fun handle(event: MouseEvent?) { if (event != null) { - mapCanvas.handleMouseInput(MapMouseEvent.of(event, tileSet)) + brush.handleMouseInput(MapMouseEvent.of(event, tileSet)) } mapCanvas.render(graphicsContext2D)