[Editor] Complete full support for auto tiles #3
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package com.bartlomiejpluta.base.editor.autotile.canvas
|
||||
|
||||
import com.bartlomiejpluta.base.editor.map.model.brush.AutoTileBrush
|
||||
import com.bartlomiejpluta.base.editor.map.model.layer.AutoTileLayer
|
||||
import com.bartlomiejpluta.base.editor.map.model.layer.TileLayer
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.BrushVM
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM
|
||||
@@ -21,20 +23,9 @@ class AutoTileSelection(private val editorStateVM: EditorStateVM, private val ga
|
||||
y = row * height
|
||||
|
||||
if (editorStateVM.selectedLayer is AutoTileLayer) {
|
||||
|
||||
val autoTile = (editorStateVM.selectedLayer as AutoTileLayer).autoTile
|
||||
(brushVM.item as AutoTileBrush).id = (1 + row * autoTile.columns + column).toInt() //((column % autoTile.columns).toInt()) + row.toInt() + 1
|
||||
}
|
||||
|
||||
// if (editorStateVM.selectedLayer is TileLayer) {
|
||||
// val tileSet = (editorStateVM.selectedLayer as TileLayer).tileSetProperty.value
|
||||
// val brushArray = Array(rows) { rowIndex ->
|
||||
// Array(columns) { columnIndex ->
|
||||
// tileSet.getTile(firstRow + rowIndex, firstColumn + columnIndex)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// brushVM.item = Brush.of(brushArray)
|
||||
// brushVM.commit()
|
||||
// }
|
||||
}
|
||||
|
||||
override fun render(gc: GraphicsContext) {
|
||||
|
||||
@@ -14,7 +14,7 @@ class AutoTilePaintingCursor(
|
||||
) : PaintingCursor {
|
||||
|
||||
override fun render(gc: GraphicsContext) {
|
||||
brushVM.forEach { row, column, centerRow, centerColumn, _ ->
|
||||
brushVM.item.forEachInRange { row, column, centerRow, centerColumn ->
|
||||
renderTile(gc, row, column, centerRow, centerColumn)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.bartlomiejpluta.base.editor.map.canvas
|
||||
|
||||
import com.bartlomiejpluta.base.editor.map.model.brush.AutoTileBrush
|
||||
import com.bartlomiejpluta.base.editor.map.model.brush.BrushMode
|
||||
import com.bartlomiejpluta.base.editor.map.model.layer.AutoTileLayer
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.BrushVM
|
||||
@@ -39,14 +40,14 @@ class AutoTilePaintingTrace(val map: GameMapVM, override val commandName: String
|
||||
}
|
||||
|
||||
override fun beginTrace(editorStateVM: EditorStateVM, brushVM: BrushVM, mouseEvent: MapMouseEvent) {
|
||||
brushVM.forEach { row, column, centerRow, centerColumn, _ ->
|
||||
brushVM.item.forEachInRange { row, column, centerRow, centerColumn ->
|
||||
paint(
|
||||
editorStateVM.selectedLayerIndex,
|
||||
editorStateVM.cursorRow - centerRow + row,
|
||||
editorStateVM.cursorColumn - centerColumn + column,
|
||||
when {
|
||||
brushVM.mode == BrushMode.ERASING_MODE -> 0
|
||||
mouseEvent.button == MouseButton.PRIMARY -> 1
|
||||
mouseEvent.button == MouseButton.PRIMARY -> (brushVM.item as AutoTileBrush).id
|
||||
else -> 0
|
||||
}
|
||||
)
|
||||
@@ -54,14 +55,14 @@ class AutoTilePaintingTrace(val map: GameMapVM, override val commandName: String
|
||||
}
|
||||
|
||||
override fun proceedTrace(editorStateVM: EditorStateVM, brushVM: BrushVM, mouseEvent: MapMouseEvent) {
|
||||
brushVM.forEach { row, column, centerRow, centerColumn, _ ->
|
||||
brushVM.item.forEachInRange { row, column, centerRow, centerColumn ->
|
||||
paint(
|
||||
editorStateVM.selectedLayerIndex,
|
||||
editorStateVM.cursorRow - centerRow + row,
|
||||
editorStateVM.cursorColumn - centerColumn + column,
|
||||
when {
|
||||
brushVM.mode == BrushMode.ERASING_MODE -> 0
|
||||
mouseEvent.button == MouseButton.PRIMARY -> 1
|
||||
mouseEvent.button == MouseButton.PRIMARY -> (brushVM.item as AutoTileBrush).id
|
||||
else -> 0
|
||||
}
|
||||
)
|
||||
|
||||
@@ -14,7 +14,7 @@ class PassageAbilityPaintingCursor(
|
||||
) : PaintingCursor {
|
||||
|
||||
override fun render(gc: GraphicsContext) {
|
||||
brushVM.forEach { row, column, centerRow, centerColumn, _ ->
|
||||
brushVM.item.forEachInRange() { row, column, centerRow, centerColumn ->
|
||||
renderTile(gc, row, column, centerRow, centerColumn)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ class PassageAbilityPaintingTrace(val map: GameMapVM, override val commandName:
|
||||
}
|
||||
|
||||
override fun beginTrace(editorStateVM: EditorStateVM, brushVM: BrushVM, mouseEvent: MapMouseEvent) {
|
||||
brushVM.forEach { row, column, centerRow, centerColumn, _ ->
|
||||
brushVM.item.forEachInRange { row, column, centerRow, centerColumn ->
|
||||
paint(
|
||||
editorStateVM.selectedLayerIndex,
|
||||
editorStateVM.cursorRow - centerRow + row,
|
||||
@@ -55,7 +55,7 @@ class PassageAbilityPaintingTrace(val map: GameMapVM, override val commandName:
|
||||
}
|
||||
|
||||
override fun proceedTrace(editorStateVM: EditorStateVM, brushVM: BrushVM, mouseEvent: MapMouseEvent) {
|
||||
brushVM.forEach { row, column, centerRow, centerColumn, _ ->
|
||||
brushVM.item.forEachInRange { row, column, centerRow, centerColumn, ->
|
||||
paint(
|
||||
editorStateVM.selectedLayerIndex,
|
||||
editorStateVM.cursorRow - centerRow + row,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.bartlomiejpluta.base.editor.map.canvas
|
||||
|
||||
import com.bartlomiejpluta.base.editor.map.model.brush.TileBrush
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.BrushVM
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM
|
||||
import com.bartlomiejpluta.base.editor.tileset.model.Tile
|
||||
@@ -14,7 +15,7 @@ class TilePaintingCursor(
|
||||
) : PaintingCursor {
|
||||
|
||||
override fun render(gc: GraphicsContext) {
|
||||
brushVM.forEach { row, column, centerRow, centerColumn, tile ->
|
||||
(brushVM.item as TileBrush).forEachTileOnBrush { row, column, centerRow, centerColumn, tile ->
|
||||
renderTile(gc, row, column, centerRow, centerColumn, tile)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.bartlomiejpluta.base.editor.map.canvas
|
||||
|
||||
import com.bartlomiejpluta.base.editor.map.model.brush.TileBrush
|
||||
import com.bartlomiejpluta.base.editor.map.model.layer.TileLayer
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.BrushVM
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM
|
||||
@@ -40,7 +41,7 @@ data class TilePaintingTrace(val map: GameMapVM, override val commandName: Strin
|
||||
}
|
||||
|
||||
override fun beginTrace(editorStateVM: EditorStateVM, brushVM: BrushVM, mouseEvent: MapMouseEvent) {
|
||||
brushVM.forEach { row, column, centerRow, centerColumn, tile ->
|
||||
(brushVM.item as TileBrush).forEachTileOnBrush { row, column, centerRow, centerColumn, tile ->
|
||||
paint(
|
||||
editorStateVM.selectedLayerIndex,
|
||||
editorStateVM.cursorRow - centerRow + row,
|
||||
@@ -54,7 +55,7 @@ data class TilePaintingTrace(val map: GameMapVM, override val commandName: Strin
|
||||
}
|
||||
|
||||
override fun proceedTrace(editorStateVM: EditorStateVM, brushVM: BrushVM, mouseEvent: MapMouseEvent) {
|
||||
brushVM.forEach { row, column, centerRow, centerColumn, tile ->
|
||||
(brushVM.item as TileBrush).forEachTileOnBrush { row, column, centerRow, centerColumn, tile ->
|
||||
paint(
|
||||
editorStateVM.selectedLayerIndex,
|
||||
editorStateVM.cursorRow - centerRow + row,
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.bartlomiejpluta.base.editor.map.model.brush
|
||||
|
||||
class AutoTileBrush : Brush() {
|
||||
var id = 0
|
||||
}
|
||||
@@ -9,98 +9,27 @@ import tornadofx.getValue
|
||||
import tornadofx.observableListOf
|
||||
import tornadofx.setValue
|
||||
|
||||
class Brush {
|
||||
val brush: ObservableList<Tile>
|
||||
|
||||
val rowsProperty = SimpleIntegerProperty(0)
|
||||
var rows by rowsProperty
|
||||
private set
|
||||
|
||||
val columnsProperty = SimpleIntegerProperty(0)
|
||||
var columns by columnsProperty
|
||||
private set
|
||||
|
||||
val rangeProperty = SimpleIntegerProperty(1)
|
||||
var range by rangeProperty
|
||||
private set
|
||||
|
||||
abstract class Brush {
|
||||
val modeProperty = SimpleObjectProperty(BrushMode.PAINTING_MODE)
|
||||
var mode by modeProperty
|
||||
private set
|
||||
|
||||
val toolProperty = SimpleObjectProperty(BrushTool.DEFAULT)
|
||||
var tool by toolProperty
|
||||
private set
|
||||
|
||||
private constructor(brushArray: Array<Array<Tile>>) {
|
||||
rowsProperty.value = brushArray.size
|
||||
val rangeProperty = SimpleIntegerProperty(1)
|
||||
var range by rangeProperty
|
||||
|
||||
brush = observableListOf()
|
||||
|
||||
brushArray.forEach { brush.addAll(it) }
|
||||
|
||||
if (rowsProperty.value > 0) {
|
||||
columns = brush.size / rowsProperty.value
|
||||
}
|
||||
}
|
||||
|
||||
private constructor(brush: List<Tile>, rows: Int, columns: Int) {
|
||||
this.rows = rows
|
||||
this.columns = columns
|
||||
|
||||
this.brush = brush.asObservable()
|
||||
}
|
||||
|
||||
fun forEach(consumer: (row: Int, column: Int, centerRow: Int, centerColumn: Int, tile: Tile?) -> Unit) {
|
||||
return when {
|
||||
range > 1 || mode == BrushMode.ERASING_MODE -> forEachInRangedBrush(consumer)
|
||||
else -> forEachInRegularBrush(consumer)
|
||||
}
|
||||
}
|
||||
|
||||
private fun forEachInRangedBrush(consumer: (row: Int, column: Int, centerRow: Int, centerColumn: Int, tile: Tile?) -> Unit) {
|
||||
fun forEachInRange(consumer: (row: Int, column: Int, centerRow: Int, centerColumn: Int) -> Unit) {
|
||||
val center = range / 2
|
||||
|
||||
(0 until range).forEach { row ->
|
||||
(0 until range).forEach { column ->
|
||||
consumer(row, column, center, center, getTileByMode(brush[0]))
|
||||
consumer(row, column, center, center)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
this.range = this@Brush.range
|
||||
this.mode = this@Brush.mode
|
||||
this.tool = this@Brush.tool
|
||||
}
|
||||
|
||||
fun withRange(range: Int) = clone().apply {
|
||||
this.range = range
|
||||
}
|
||||
|
||||
fun withMode(mode: BrushMode) = clone().apply {
|
||||
this.mode = mode
|
||||
}
|
||||
|
||||
fun withTool(tool: BrushTool) = clone().apply {
|
||||
this.tool = tool
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun of(brushArray: Array<Array<Tile>>) = Brush(brushArray)
|
||||
fun of(brushArray: Array<Array<Tile>>) = TileBrush(brushArray)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
package com.bartlomiejpluta.base.editor.map.model.brush
|
||||
|
||||
class EmptyBrush : Brush()
|
||||
@@ -0,0 +1,3 @@
|
||||
package com.bartlomiejpluta.base.editor.map.model.brush
|
||||
|
||||
class PassageAbilityBrush : Brush()
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.bartlomiejpluta.base.editor.map.model.brush
|
||||
|
||||
import com.bartlomiejpluta.base.editor.tileset.model.Tile
|
||||
import tornadofx.observableListOf
|
||||
|
||||
class TileBrush(brushArray: Array<Array<Tile>>) : Brush() {
|
||||
private val brush: List<Tile>
|
||||
|
||||
private var columns = 0
|
||||
private var rows = 0
|
||||
|
||||
init {
|
||||
rows = brushArray.size
|
||||
brush = observableListOf()
|
||||
brushArray.forEach { brush.addAll(it) }
|
||||
if (rows > 0) {
|
||||
columns = brush.size / rows
|
||||
}
|
||||
}
|
||||
|
||||
fun forEachTileOnBrush(consumer: (row: Int, column: Int, centerRow: Int, centerColumn: Int, tile: Tile?) -> Unit) {
|
||||
return when {
|
||||
range > 1 || mode == BrushMode.ERASING_MODE -> forEachInRange { row, column, centerRow, centerColumn ->
|
||||
consumer(row, column, centerRow, centerColumn, brush[0])
|
||||
}
|
||||
|
||||
else -> forEachInRegularBrush(consumer)
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,7 @@ class MapToolbarView : View() {
|
||||
}
|
||||
|
||||
editorStateVM.selectedLayerProperty.addListener { _, _, _ ->
|
||||
brushVM.item = brushVM.withTool(BrushTool.DEFAULT)
|
||||
brushVM.tool = BrushTool.DEFAULT
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ class MapToolbarView : View() {
|
||||
enableWhen(isTileLayerSelected.or(isAutoTileLayerSelected).or(isObjectLayerSelected))
|
||||
|
||||
action {
|
||||
brushVM.item = brushVM.withMode(BrushMode.PAINTING_MODE)
|
||||
brushVM.mode = BrushMode.PAINTING_MODE
|
||||
brushVM.commit()
|
||||
}
|
||||
}
|
||||
@@ -115,7 +115,7 @@ class MapToolbarView : View() {
|
||||
enableWhen(isTileLayerSelected.or(isAutoTileLayerSelected).or(isObjectLayerSelected))
|
||||
|
||||
action {
|
||||
brushVM.item = brushVM.withMode(BrushMode.ERASING_MODE)
|
||||
brushVM.mode = BrushMode.ERASING_MODE
|
||||
brushVM.commit()
|
||||
}
|
||||
}
|
||||
@@ -130,7 +130,7 @@ class MapToolbarView : View() {
|
||||
enableWhen(isTileLayerSelected.or(isAutoTileLayerSelected).or(isObjectLayerSelected))
|
||||
|
||||
valueProperty().addListener { _, _, newValue ->
|
||||
brushVM.item = brushVM.withRange(newValue.toInt())
|
||||
brushVM.range = newValue.toInt()
|
||||
brushVM.commit()
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ class MapToolbarView : View() {
|
||||
visibleWhen(isObjectLayerSelected)
|
||||
|
||||
action {
|
||||
brushVM.item = brushVM.withTool(BrushTool.DEFAULT)
|
||||
brushVM.tool = BrushTool.DEFAULT
|
||||
brushVM.commit()
|
||||
}
|
||||
}
|
||||
@@ -162,7 +162,7 @@ class MapToolbarView : View() {
|
||||
visibleWhen(isObjectLayerSelected)
|
||||
|
||||
action {
|
||||
brushVM.item = brushVM.withTool(BrushTool.PASSAGE)
|
||||
brushVM.tool = BrushTool.PASSAGE
|
||||
brushVM.commit()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,11 @@ import com.bartlomiejpluta.base.editor.command.service.UndoRedoService
|
||||
import com.bartlomiejpluta.base.editor.event.RedrawMapRequestEvent
|
||||
import com.bartlomiejpluta.base.editor.map.canvas.PaintingTrace
|
||||
import com.bartlomiejpluta.base.editor.map.component.MapPane
|
||||
import com.bartlomiejpluta.base.editor.map.model.brush.*
|
||||
import com.bartlomiejpluta.base.editor.map.model.layer.AutoTileLayer
|
||||
import com.bartlomiejpluta.base.editor.map.model.layer.Layer
|
||||
import com.bartlomiejpluta.base.editor.map.model.layer.ObjectLayer
|
||||
import com.bartlomiejpluta.base.editor.map.model.layer.TileLayer
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.BrushVM
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM
|
||||
@@ -40,12 +45,24 @@ class MapView : View() {
|
||||
}
|
||||
|
||||
init {
|
||||
// brushVM.item = mapVM.tileSet.baseBrush
|
||||
brushVM.item = EmptyBrush()
|
||||
brushVM.commit()
|
||||
|
||||
editorStateVM.selectedLayerProperty.addListener { _, _, layer ->
|
||||
brushVM.item = determineBrush(layer)
|
||||
brushVM.commit()
|
||||
}
|
||||
|
||||
subscribe<RedrawMapRequestEvent> { mapPane.render() }
|
||||
}
|
||||
|
||||
private fun determineBrush(layer: Layer?) : Brush? = when (layer) {
|
||||
is TileLayer -> TileBrush((arrayOf(arrayOf(layer.tileSetProperty.value.tiles[0]))))
|
||||
is AutoTileLayer -> AutoTileBrush()
|
||||
is ObjectLayer -> PassageAbilityBrush()
|
||||
else -> null
|
||||
}
|
||||
|
||||
private fun pushPaintingTraceToUndoRedoService(trace: PaintingTrace) {
|
||||
if (trace.executed) {
|
||||
undoRedoService.push(trace, scope)
|
||||
|
||||
@@ -1,36 +1,15 @@
|
||||
package com.bartlomiejpluta.base.editor.map.viewmodel
|
||||
|
||||
import com.bartlomiejpluta.base.editor.map.model.brush.Brush
|
||||
import com.bartlomiejpluta.base.editor.map.model.brush.BrushMode
|
||||
import com.bartlomiejpluta.base.editor.map.model.brush.BrushTool
|
||||
import com.bartlomiejpluta.base.editor.tileset.model.Tile
|
||||
import tornadofx.ItemViewModel
|
||||
import tornadofx.getValue
|
||||
import tornadofx.*
|
||||
|
||||
class BrushVM : ItemViewModel<Brush>(Brush.of(arrayOf(arrayOf()))) {
|
||||
val brush = bind(Brush::brush)
|
||||
|
||||
val rowsProperty = bind(Brush::rowsProperty)
|
||||
val rows by rowsProperty
|
||||
|
||||
val columnsProperty = bind(Brush::columnsProperty)
|
||||
val columns by columnsProperty
|
||||
|
||||
val rangeProperty = bind(Brush::rangeProperty)
|
||||
val range by rangeProperty
|
||||
|
||||
val modeProperty = bind(Brush::modeProperty)
|
||||
val mode by modeProperty
|
||||
var mode by modeProperty
|
||||
|
||||
val toolProperty = bind(Brush::toolProperty)
|
||||
val tool by toolProperty
|
||||
var tool by toolProperty
|
||||
|
||||
fun forEach(consumer: (row: Int, column: Int, centerRow: Int, centerColumn: Int, tile: Tile?) -> Unit) =
|
||||
item.forEach(consumer)
|
||||
|
||||
fun withRange(range: Int) = item.withRange(range)
|
||||
|
||||
fun withMode(mode: BrushMode) = item.withMode(mode)
|
||||
|
||||
fun withTool(tool: BrushTool) = item.withTool(tool)
|
||||
val rangeProperty = bind(Brush::rangeProperty)
|
||||
var range by rangeProperty
|
||||
}
|
||||
@@ -43,9 +43,6 @@ class TileSet(uid: String, name: String, image: Image, rows: Int, columns: Int)
|
||||
|
||||
val tiles = (0 until rows * columns).map { cropTile(it / columns, it % columns) }.toObservable()
|
||||
|
||||
val baseBrush: Brush
|
||||
get() = Brush.of(arrayOf(arrayOf(tiles[0])))
|
||||
|
||||
private fun cropTile(row: Int, column: Int): Tile {
|
||||
val reader = image.pixelReader
|
||||
val buffer = ByteBuffer.allocate(tileWidth * tileHeight * 4)
|
||||
|
||||
Reference in New Issue
Block a user