diff --git a/Builder/src/fmon/builder/MapBuilder.fxml b/Builder/src/fmon/builder/MapBuilder.fxml index 2149daf..44c51e3 100644 --- a/Builder/src/fmon/builder/MapBuilder.fxml +++ b/Builder/src/fmon/builder/MapBuilder.fxml @@ -18,7 +18,7 @@ - + @@ -50,6 +50,8 @@ + + @@ -65,20 +67,28 @@ - - - - - + + + + + + + + + - - - - - + + + + + + + + + @@ -88,6 +98,7 @@ + diff --git a/Builder/src/fmon/builder/MapBuilder.scala b/Builder/src/fmon/builder/MapBuilder.scala index 6fd508a..d77e08a 100644 --- a/Builder/src/fmon/builder/MapBuilder.scala +++ b/Builder/src/fmon/builder/MapBuilder.scala @@ -21,24 +21,34 @@ import scalafx.scene.input.MouseEvent import scalafx.scene.paint.Color import scalafx.scene.layout._ import scalafx.stage.FileChooser +import scalafx.stage.Modality import FileChooser.ExtensionFilter import fmon._ +import fmon.builder.dialog.MapProperties import fmon.draw.Palette import fmon.draw.tile._ import fmon.util.{Direction, YamlHelper} import fmon.world._ import Direction._ +import Alert.AlertType import scala.math.{min, max} +sealed trait MapBuilderState + +case object GroundTile extends MapBuilderState +case object DoodadTile extends MapBuilderState + class MapBuilder { @FXML var tileSelector: jfxsl.TilePane = _ @FXML var doodadSelector: jfxsl.TilePane = _ @FXML var gameMap: jfxsl.TilePane = _ + @FXML var doodadMap: jfxsl.TilePane = _ var imgSeq: IndexedSeq[ImageView] = _ + var doodadSeq: IndexedSeq[ImageView] = _ val tilesets = { val dir = new File(raw"C:\Users\James\Documents\Design\Project\Progena\Data") @@ -46,6 +56,7 @@ class MapBuilder { } var tileset: Tileset = _ var currTile: AutoTile = _ + var currState: MapBuilderState = GroundTile var level: GameMap = _ @@ -79,6 +90,7 @@ class MapBuilder { view.handleEvent(MouseEvent.Any) { e: MouseEvent => if (e.eventType == MouseEvent.MouseClicked) { currTile = t + currState = GroundTile } } view.delegate @@ -89,26 +101,50 @@ class MapBuilder { val doodads = tileset.doodadTiles.map(d => { val view = new ImageView(d.icon.croppedImage()) + view.handleEvent(MouseEvent.Any) { + e: MouseEvent => if (e.eventType == MouseEvent.MouseClicked) { + currTile = d + currState = DoodadTile + } + } view.delegate }) doodadSelector.children.clear() doodadSelector.children ++= doodads imgSeq = for (y <- 0 until level.height; x <- 0 until level.width) yield { - val view = new ImageView(currTile.icon.croppedImage()) // TODO Tile with adjacent + val view = new ImageView(level(x, y).icon.croppedImage()) // TODO Tile with adjacent view.handleEvent(MouseEvent.Any) { e: MouseEvent => if (e.eventType == MouseEvent.MouseClicked) { val index = point2index(x, y) - level.tiles = level.tiles.updated(index, currTile) - autotile(x, y) + currState match { + case GroundTile => { + level.tiles = level.tiles.updated(index, currTile) + autotile(x, y) + } + case DoodadTile => { + level.doodads = level.doodads.updated(index, currTile) + doodadSeq(index).image = level.doodads(index).icon.croppedImage() + } + } + } } view } + doodadSeq = for (y <- 0 until level.height; x <- 0 until level.width) yield { + val view = new ImageView(level.doodad(x, y).icon.croppedImage()) + view + } gameMap.children.clear() gameMap.prefColumns = level.width gameMap.prefRows = level.height gameMap.children ++= imgSeq.map(_.delegate) + doodadMap.children.clear() + doodadMap.prefColumns = level.width + doodadMap.prefRows = level.height + doodadMap.children ++= doodadSeq.map(_.delegate) + doodadMap.mouseTransparent = true for (y <- 0 until level.height; x <- 0 until level.width) { smoothTile(x, y) @@ -123,24 +159,39 @@ class MapBuilder { } def smoothTile(x: Int, y: Int) = { - val i = point2index(x, y) - val dirs = scala.collection.mutable.Set[Direction.Value]() - - val onLeft = x == 0 - val onRight = x + 1 == level.width - val onTop = y == 0 - val onBottom = y + 1 == level.height - - if (onLeft || level.tiles(left(i)) == level.tiles(i)) dirs += West - if (onRight || level.tiles(right(i)) == level.tiles(i)) dirs += East - if (onTop || level.tiles(up(i)) == level.tiles(i)) dirs += North - if (onBottom || level.tiles(down(i)) == level.tiles(i)) dirs += South - if (onLeft || onTop || level.tiles(left(up(i))) == level.tiles(i)) dirs += Northwest - if (onLeft || onBottom || level.tiles(down(left(i))) == level.tiles(i)) dirs += Southwest - if (onTop || onRight || level.tiles(right(up(i))) == level.tiles(i)) dirs += Northeast - if (onBottom || onRight || level.tiles(right(down(i))) == level.tiles(i)) dirs += Southeast - val index = point2index(x, y) - imgSeq(index).image = level.tiles(index).build(dirs.toSet).croppedImage() + imgSeq(level.pt2index(x, y)).image = level.smoothed(x, y) + } + + @FXML + def onPropertiesDialog: Unit = { + val fxmlLoader = new FXMLLoader(getClass().getResource("dialog/MapProperties.fxml")) + val parent: Parent = fxmlLoader.load() + val dialogController = fxmlLoader.getController[MapProperties](); + //dialogController.setAppMainObservableList(tvObservableList); + dialogController.init(level) + + val dialog = new Alert(AlertType.Confirmation) { + title = "Map Properties" + dialogPane().content = parent + headerText = "" + graphic = null + } + val result = dialog.showAndWait() + println(result) + result match { + case Some(ButtonType.OK) => { + println(dialogController.width, dialogController.height) + level = new GameMap(dialogController.width, dialogController.height, tileset) + level.tiles = level.tiles.map(_ => currTile) + setup() + } + case _ => () + } + /*val scene = new Scene(parent, 300, 200); + val stage = new Stage(); + stage.initModality(Modality.ApplicationModal); + stage.setScene(scene); + stage.showAndWait();*/ } def save() = { diff --git a/Builder/src/fmon/builder/dialog/MapProperties.fxml b/Builder/src/fmon/builder/dialog/MapProperties.fxml new file mode 100644 index 0000000..3a6fa7d --- /dev/null +++ b/Builder/src/fmon/builder/dialog/MapProperties.fxml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/Builder/src/fmon/builder/dialog/MapProperties.scala b/Builder/src/fmon/builder/dialog/MapProperties.scala new file mode 100644 index 0000000..0043046 --- /dev/null +++ b/Builder/src/fmon/builder/dialog/MapProperties.scala @@ -0,0 +1,26 @@ +package fmon.builder.dialog + +import javafx.fxml.FXML +import javafx.scene.{control => jfxsc, layout => jfxsl, Parent, Scene} + +import scalafx.Includes._ +import scalafx.scene.control.SpinnerValueFactory + +import fmon.world.GameMap + +class MapProperties { + @FXML var widthSpin: jfxsc.Spinner[Int] = _ + @FXML var heightSpin: jfxsc.Spinner[Int] = _ + + @FXML def initialize(): Unit = { + println(widthSpin) + } + + def init(level: GameMap): Unit = { + widthSpin.valueFactory().value = level.width + heightSpin.valueFactory().value = level.height + } + + def width = widthSpin.value() + def height = heightSpin.value() +} \ No newline at end of file diff --git a/FakeMon/src/fmon/world/GameMap.scala b/FakeMon/src/fmon/world/GameMap.scala index 362a665..d063852 100644 --- a/FakeMon/src/fmon/world/GameMap.scala +++ b/FakeMon/src/fmon/world/GameMap.scala @@ -1,13 +1,19 @@ package fmon.world +import scalafx.scene.image.Image + import java.io._ +import fmon.draw._ import fmon.draw.tile._ import fmon.util._ +import Direction._ + class GameMap(val width: Int, val height: Int, val tileset: Tileset) { var tiles: IndexedSeq[AutoTile] = for (y <- 0 until height; x <- 0 until width) yield tileset.groundTiles.head + var doodads: IndexedSeq[AutoTile] = for (y <- 0 until height; x <- 0 until width) yield tileset.doodadTiles.head def saveTo(file: File): Unit = { val ostream = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file))) @@ -17,12 +23,43 @@ class GameMap(val width: Int, val height: Int, val tileset: Tileset) { val tileIndices = tileset.groundTiles.zipWithIndex.toMap tiles.foreach(t => ostream.writeInt(tileIndices(t))) //ostream.writeObject(tiles.map(tileIndices(_)).mkString(" ")) + val doodadIndices = tileset.doodadTiles.zipWithIndex.toMap + doodads.foreach(t => ostream.writeInt(doodadIndices(t))) ostream.close() } + def apply(x: Int, y: Int): AutoTile = tiles(pt2index(x, y)) + def doodad(x: Int, y: Int): AutoTile = doodads(pt2index(x, y)) + + def smoothed(x: Int, y: Int): Image = { + val i = pt2index(x, y) + val dirs = scala.collection.mutable.Set[Direction.Value]() + + val onLeft = x == 0 + val onRight = x + 1 == width + val onTop = y == 0 + val onBottom = y + 1 == height + + if (onLeft || tiles(left(i)) == tiles(i)) dirs += West + if (onRight || tiles(right(i)) == tiles(i)) dirs += East + if (onTop || tiles(up(i)) == tiles(i)) dirs += North + if (onBottom || tiles(down(i)) == tiles(i)) dirs += South + if (onLeft || onTop || tiles(left(up(i))) == tiles(i)) dirs += Northwest + if (onLeft || onBottom || tiles(down(left(i))) == tiles(i)) dirs += Southwest + if (onTop || onRight || tiles(right(up(i))) == tiles(i)) dirs += Northeast + if (onBottom || onRight || tiles(right(down(i))) == tiles(i)) dirs += Southeast + val index = pt2index(x, y) + tiles(index).build(dirs.toSet).croppedImage() + } + def pt2index(x: Int, y: Int) = y * width + x def index2x(i: Int) = i % width def index2y(i: Int) = i / width + + def left(i: Int) = i - 1 + def right(i: Int) = i + 1 + def up(i: Int) = i - width + def down(i: Int) = i + width } object GameMap { @@ -36,9 +73,12 @@ object GameMap { val tokens = YamlHelper.extractSeq[TilesetToken](new FileInputStream(new File(dir, "Tilesets.yaml"))).map(t => (t.name, t)).toMap val tileset = tokens("Outside").load(resourceDir) val indices = for (y <- 0 until height; x <- 0 until width) yield istream.readInt() + val dindices = for (y <- 0 until height; x <- 0 until width) yield istream.readInt() val map = new GameMap(width, height, tileset) val tiles = indices.map(i => tileset.groundTiles(i)) + val doodads = dindices.map(i => tileset.doodadTiles(i)) map.tiles = tiles + map.doodads = doodads map } } \ No newline at end of file diff --git a/FakeMon/src/fmon/world/Tileset.scala b/FakeMon/src/fmon/world/Tileset.scala index b954675..3d02251 100644 --- a/FakeMon/src/fmon/world/Tileset.scala +++ b/FakeMon/src/fmon/world/Tileset.scala @@ -7,7 +7,7 @@ import fmon.draw.tile._ class Tileset(val groundTiles: IndexedSeq[AutoTile], val doodadTiles: IndexedSeq[AutoTile], val info: IndexedSeq[TileInfo]) { def groundInfo(index: Int) = info(index) - def doodadTiles(index: Int) = info(index - groundTiles.size) + def doodadInfo(index: Int) = info(index - groundTiles.size) } case class TileInfo( diff --git a/FakeMon/src/fmon/world/ui/GameView.fxml b/FakeMon/src/fmon/world/ui/GameView.fxml new file mode 100644 index 0000000..4944f2c --- /dev/null +++ b/FakeMon/src/fmon/world/ui/GameView.fxml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/FakeMon/src/fmon/world/ui/GameView.scala b/FakeMon/src/fmon/world/ui/GameView.scala new file mode 100644 index 0000000..059d8b2 --- /dev/null +++ b/FakeMon/src/fmon/world/ui/GameView.scala @@ -0,0 +1,75 @@ +package fmon.world.ui + +import java.io._ + +import javafx.application.Application +import javafx.fxml.FXML +import javafx.fxml.FXMLLoader +import javafx.fxml.JavaFXBuilderFactory +import javafx.scene.{control => jfxsc, layout => jfxsl, Parent, Scene} +import javafx.stage.Stage + +import scalafx.Includes._ +import scalafx.beans.property._ +import scalafx.collections.ObservableBuffer +import scalafx.scene.control._ +import scalafx.scene.image.ImageView +import scalafx.scene.input.MouseEvent +import scalafx.scene.paint.Color +import scalafx.scene.layout._ +import scalafx.stage.FileChooser +import scalafx.stage.Modality +import FileChooser.ExtensionFilter + +import fmon._ +import fmon.world._ +import fmon.util.YamlHelper + +class GameView { + @FXML var scroller: jfxsc.ScrollPane = _ + @FXML var background: jfxsl.TilePane = _ + @FXML var doodads: jfxsl.TilePane = _ + + def loadLevel(level: GameMap): Unit = { + background.prefColumns = level.width + val tiles = for (y <- 0 until level.height; x <- 0 until level.width) yield { + new ImageView(level.smoothed(x, y)).delegate + } + + background.children ++= tiles + + doodads.prefColumns = level.width + val dtiles = for (y <- 0 until level.height; x <- 0 until level.width) yield { + new ImageView(level.doodad(x, y).icon.croppedImage()).delegate + } + doodads.children ++= dtiles + } +} + +object GameView { + class GameApp extends Application { + override def start(primaryStage: Stage): Unit = { + val frameLoader = new FXMLLoader(getClass.getResource("GameView.fxml")) + val root: Parent = frameLoader.load() + val controller = frameLoader.getController[GameView]() + + val stageFile = raw"C:\Users\James\Documents\Design\Project\Progena\Data\outside.map" + val level = GameMap.loadFrom(new File(stageFile)) + controller.loadLevel(level) + //val builderLoader = new FXMLLoader(getClass.getResource("ElementBuilder.fxml")) + //val builder: Parent = builderLoader.load() + //val builderController = builderLoader.getController[ElementBuilder]() + + //controller.pane.children = builder + //controller.builder = builderController + + val scene: Scene = new Scene(root) + primaryStage.setScene(scene) + primaryStage.show() + } + } + + def main(args: Array[String]): Unit = { + Application.launch(classOf[GameApp], args: _*) + } +} \ No newline at end of file