[Editor] Add support for compiled auto tiles in single asset (not yet working selection) #2.5
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
package com.bartlomiejpluta.base.editor.autotile.canvas
|
||||
|
||||
import com.bartlomiejpluta.base.editor.autotile.model.AutoTile
|
||||
import com.bartlomiejpluta.base.editor.map.model.layer.AutoTileLayer
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM
|
||||
import com.bartlomiejpluta.base.editor.render.input.MapMouseEvent
|
||||
import com.bartlomiejpluta.base.editor.render.input.MapMouseEventHandler
|
||||
import com.bartlomiejpluta.base.editor.render.model.Renderable
|
||||
import javafx.scene.canvas.GraphicsContext
|
||||
import javafx.scene.input.MouseButton
|
||||
import javafx.scene.input.MouseEvent
|
||||
import javafx.scene.paint.Color
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class AutoTileCanvas(private val editorStateVM: EditorStateVM, private val gameMapVM: GameMapVM, private val selection: AutoTileSelection) : Renderable,
|
||||
MapMouseEventHandler {
|
||||
private var mouseRow = -1
|
||||
private var mouseColumn = -1
|
||||
|
||||
override fun render(gc: GraphicsContext) {
|
||||
gc.clearRect(0.0, 0.0, gc.canvas.width, gc.canvas.height)
|
||||
|
||||
if (editorStateVM.selectedLayer is AutoTileLayer) {
|
||||
val autoTile = (editorStateVM.selectedLayer as AutoTileLayer).autoTile
|
||||
renderBackground(gc)
|
||||
renderTiles(gc, autoTile)
|
||||
renderGrid(gc, autoTile)
|
||||
selection.render(gc)
|
||||
}
|
||||
}
|
||||
|
||||
private fun renderBackground(gc: GraphicsContext) {
|
||||
for (x in 0 until (gc.canvas.width / BACKGROUND_TILE_WIDTH).roundToInt()) {
|
||||
for (y in 0 until (gc.canvas.height / BACKGROUND_TILE_HEIGHT).roundToInt()) {
|
||||
gc.fill = when ((x + y) % 2) {
|
||||
0 -> BACKGROUND_COLOR1
|
||||
else -> BACKGROUND_COLOR2
|
||||
}
|
||||
|
||||
gc.fillRect(x * BACKGROUND_TILE_WIDTH, y * BACKGROUND_TILE_HEIGHT, BACKGROUND_TILE_WIDTH, BACKGROUND_TILE_HEIGHT)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun renderTiles(gc: GraphicsContext, autoTile: AutoTile) {
|
||||
autoTile.islandSubTiles.forEachIndexed { i, (topLeft, topRight, bottomLeft, bottomRight) ->
|
||||
val x = (i % autoTile.columns) * gameMapVM.tileWidth
|
||||
val y = (i / autoTile.columns) * gameMapVM.tileHeight
|
||||
gc.drawImage(topLeft, x, y)
|
||||
gc.drawImage(topRight, x + gameMapVM.tileWidth/2, y)
|
||||
gc.drawImage(bottomLeft, x, y + gameMapVM.tileHeight/2)
|
||||
gc.drawImage(bottomRight, x + gameMapVM.tileWidth/2, y + gameMapVM.tileHeight/2)
|
||||
|
||||
|
||||
}
|
||||
// autoTile.forEach { row, column, tile ->
|
||||
// gc.drawImage(tile.image, column * tile.image.width, row * tile.image.height)
|
||||
// }
|
||||
}
|
||||
|
||||
private fun renderGrid(gc: GraphicsContext, autoTile: AutoTile) {
|
||||
gc.stroke = Color.BLACK
|
||||
gc.lineWidth = 0.5
|
||||
|
||||
for (x in 0 until (gc.canvas.width / autoTile.tileWidth).roundToInt()) {
|
||||
gc.strokeLine(x.toDouble() * autoTile.tileWidth, 0.0, x.toDouble() * autoTile.tileWidth, gc.canvas.height)
|
||||
}
|
||||
|
||||
for (y in 0 until (gc.canvas.height / autoTile.tileHeight).roundToInt()) {
|
||||
gc.strokeLine(0.0, y.toDouble() * autoTile.tileHeight, gc.canvas.width, y.toDouble() * autoTile.tileHeight)
|
||||
}
|
||||
|
||||
val w = gc.canvas.width - 1
|
||||
val h = gc.canvas.height - 1
|
||||
|
||||
gc.strokeLine(0.0, 0.0, w, 0.0)
|
||||
gc.strokeLine(w, 0.0, w, h)
|
||||
gc.strokeLine(0.0, h, w, h)
|
||||
gc.strokeLine(0.0, 0.0, 0.0, h)
|
||||
}
|
||||
|
||||
override fun handleMouseInput(event: MapMouseEvent) {
|
||||
mouseRow = event.row
|
||||
mouseColumn = event.column
|
||||
|
||||
if(event.type == MouseEvent.MOUSE_PRESSED && event.button == MouseButton.PRIMARY) {
|
||||
selection.select(event.row.toDouble(), event.column.toDouble())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
private const val BACKGROUND_TILE_WIDTH = 5.0
|
||||
private const val BACKGROUND_TILE_HEIGHT = 5.0
|
||||
private val BACKGROUND_COLOR1 = Color.color(1.0, 1.0, 1.0, 1.0)
|
||||
private val BACKGROUND_COLOR2 = Color.color(0.95, 0.95, 0.95, 1.0)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.bartlomiejpluta.base.editor.autotile.canvas
|
||||
|
||||
import com.bartlomiejpluta.base.editor.map.model.layer.AutoTileLayer
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.BrushVM
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM
|
||||
import com.bartlomiejpluta.base.editor.render.model.Renderable
|
||||
import javafx.scene.canvas.GraphicsContext
|
||||
import javafx.scene.paint.Color
|
||||
|
||||
class AutoTileSelection(private val editorStateVM: EditorStateVM, private val gameMapVM: GameMapVM, private val brushVM: BrushVM) :
|
||||
Renderable {
|
||||
private var x = 0.0
|
||||
private var y = 0.0
|
||||
private var width = gameMapVM.tileWidth.toDouble()
|
||||
private var height = gameMapVM.tileHeight.toDouble()
|
||||
|
||||
|
||||
fun select(row: Double, column: Double) {
|
||||
x = column * width
|
||||
y = row * height
|
||||
|
||||
if (editorStateVM.selectedLayer is AutoTileLayer) {
|
||||
|
||||
}
|
||||
|
||||
// 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) {
|
||||
gc.fill = SELECTION_FILL_COLOR
|
||||
gc.fillRect(x, y, width, height)
|
||||
|
||||
gc.stroke = SELECTION_STROKE_COLOR
|
||||
gc.strokeRect(x, y, width, height)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val SELECTION_FILL_COLOR = Color.color(0.0, 0.7, 1.0, 0.4)
|
||||
private val SELECTION_STROKE_COLOR = Color.color(0.0, 0.7, 1.0, 1.0)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.bartlomiejpluta.base.editor.autotile.component
|
||||
|
||||
import com.bartlomiejpluta.base.editor.autotile.canvas.AutoTileCanvas
|
||||
import com.bartlomiejpluta.base.editor.autotile.canvas.AutoTileSelection
|
||||
import com.bartlomiejpluta.base.editor.map.model.layer.AutoTileLayer
|
||||
import com.bartlomiejpluta.base.editor.map.model.layer.Layer
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.BrushVM
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM
|
||||
import com.bartlomiejpluta.base.editor.render.input.MapMouseEvent
|
||||
import javafx.event.EventHandler
|
||||
import javafx.scene.canvas.Canvas
|
||||
import javafx.scene.input.MouseEvent
|
||||
|
||||
class AutoTilePane(editorStateVM: EditorStateVM, private val gameMapVM: GameMapVM, brushVM: BrushVM) : Canvas(),
|
||||
EventHandler<MouseEvent> {
|
||||
private val selection = AutoTileSelection(editorStateVM, gameMapVM, brushVM)
|
||||
private val autoTileCanvas = AutoTileCanvas(editorStateVM, gameMapVM, selection)
|
||||
|
||||
init {
|
||||
onMouseMoved = this
|
||||
onMouseDragged = this
|
||||
onMousePressed = this
|
||||
onMouseReleased = this
|
||||
|
||||
updateSize(editorStateVM.selectedLayer)
|
||||
|
||||
editorStateVM.selectedLayerProperty.addListener { _, _, layer ->
|
||||
updateSize(layer)
|
||||
}
|
||||
|
||||
brushVM.itemProperty.addListener { _, _, _ -> render() }
|
||||
|
||||
render()
|
||||
}
|
||||
|
||||
private fun updateSize(layer: Layer?) {
|
||||
if (layer is AutoTileLayer) {
|
||||
val tileSet = layer.autoTile
|
||||
width = (tileSet.tileWidth * tileSet.columns).toDouble()
|
||||
height = (tileSet.tileHeight * tileSet.rows).toDouble()
|
||||
} else {
|
||||
width = 0.0
|
||||
height = 0.0
|
||||
}
|
||||
|
||||
render()
|
||||
}
|
||||
|
||||
private fun render() {
|
||||
autoTileCanvas.render(graphicsContext2D)
|
||||
}
|
||||
|
||||
override fun handle(event: MouseEvent?) {
|
||||
if (event != null) {
|
||||
autoTileCanvas.handleMouseInput(MapMouseEvent.of(event, gameMapVM))
|
||||
}
|
||||
|
||||
autoTileCanvas.render(graphicsContext2D)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.bartlomiejpluta.base.editor.autotile.view.editor
|
||||
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.BrushVM
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM
|
||||
import com.bartlomiejpluta.base.editor.autotile.component.AutoTilePane
|
||||
import tornadofx.View
|
||||
import tornadofx.plusAssign
|
||||
import tornadofx.scrollpane
|
||||
|
||||
class AutoTileView : View() {
|
||||
private val gameMapVM = find<GameMapVM>()
|
||||
private val brushVM = find<BrushVM>()
|
||||
private val editorStateVM = find<EditorStateVM>()
|
||||
|
||||
private val autoTilePane = AutoTilePane(editorStateVM, gameMapVM, brushVM)
|
||||
|
||||
override val root = scrollpane {
|
||||
this += autoTilePane
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.bartlomiejpluta.base.editor.map.view.editor
|
||||
|
||||
import com.bartlomiejpluta.base.editor.autotile.view.editor.AutoTileView
|
||||
import com.bartlomiejpluta.base.editor.command.context.UndoableScope
|
||||
import com.bartlomiejpluta.base.editor.command.service.UndoRedoService
|
||||
import com.bartlomiejpluta.base.editor.event.RedrawMapRequestEvent
|
||||
@@ -8,6 +9,7 @@ import com.bartlomiejpluta.base.editor.main.component.EditorTab.Companion.REDO_S
|
||||
import com.bartlomiejpluta.base.editor.main.component.EditorTab.Companion.SAVE_SHORTCUT
|
||||
import com.bartlomiejpluta.base.editor.main.component.EditorTab.Companion.UNDO_SHORTCUT
|
||||
import com.bartlomiejpluta.base.editor.map.controller.MapController
|
||||
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.EditorStateVM
|
||||
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM
|
||||
@@ -29,6 +31,7 @@ class MapFragment : EditorFragment() {
|
||||
private val mapView = find<MapView>()
|
||||
private val layersView = find<MapLayersView>()
|
||||
private val tileSetView = find<TileSetView>()
|
||||
private val autoTileView = find<AutoTileView>()
|
||||
private val toolbarView = find<MapToolbarView>()
|
||||
private val statusBarView = find<MapStatusBarView>()
|
||||
private val layerParameters = find<MapLayerParameters>()
|
||||
@@ -39,6 +42,11 @@ class MapFragment : EditorFragment() {
|
||||
editorStateVM.selectedLayerProperty
|
||||
)
|
||||
|
||||
private val isAutoTileLayerSelected = Bindings.createBooleanBinding(
|
||||
{ editorStateVM.selectedLayer is AutoTileLayer },
|
||||
editorStateVM.selectedLayerProperty
|
||||
)
|
||||
|
||||
override val root = borderpane {
|
||||
top = toolbarView.root
|
||||
|
||||
@@ -59,6 +67,14 @@ class MapFragment : EditorFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
item("Auto Tile", expanded = false) {
|
||||
enableWhen(isAutoTileLayerSelected)
|
||||
|
||||
this += autoTileView.root.apply {
|
||||
maxHeightProperty().bind(this@item.heightProperty())
|
||||
}
|
||||
}
|
||||
|
||||
item("Layer Parameters", expanded = false) {
|
||||
this += layerParameters
|
||||
}
|
||||
|
||||
@@ -70,39 +70,6 @@ class TileSetCanvas(private val editorStateVM: EditorStateVM, private val select
|
||||
gc.strokeLine(0.0, 0.0, 0.0, h)
|
||||
}
|
||||
|
||||
// private fun createGrid(gc: GraphicsContext, chunkWidth: Int, chunkHeight: Int): WritableImage {
|
||||
// val grid = WritableImage(gc.canvas.width.toInt(), gc.canvas.height.toInt())
|
||||
//
|
||||
// val writer = grid.pixelWriter
|
||||
// val color = Color.BLACK
|
||||
// for (x in 0 until grid.width.toInt()) {
|
||||
// for (y in 0 until grid.height.toInt()) {
|
||||
// if (x % chunkWidth == 0) {
|
||||
// writer.setColor(x, y, color)
|
||||
// }
|
||||
//
|
||||
// if (y % chunkHeight == 0) {
|
||||
// writer.setColor(x, y, color)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// val lastX = grid.width.toInt() - 1
|
||||
// val lastY = grid.height.toInt() - 1
|
||||
//
|
||||
// for (x in 0 until grid.width.toInt()) {
|
||||
// writer.setColor(x, 0, color)
|
||||
// writer.setColor(x, lastY, color)
|
||||
// }
|
||||
//
|
||||
// for (y in 0 until grid.height.toInt()) {
|
||||
// writer.setColor(0, y, color)
|
||||
// writer.setColor(lastX, y, color)
|
||||
// }
|
||||
//
|
||||
// return grid
|
||||
// }
|
||||
|
||||
override fun handleMouseInput(event: MapMouseEvent) {
|
||||
mouseRow = event.row
|
||||
mouseColumn = event.column
|
||||
|
||||
Reference in New Issue
Block a user