Created a builder for making maps
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package fmon.battle
|
||||
|
||||
import java.io._
|
||||
import java.util.concurrent.locks.{Condition, ReentrantLock}
|
||||
|
||||
import javafx.application.Platform
|
||||
@@ -23,6 +24,7 @@ import scalafx.scene.transform.Rotate
|
||||
import scalafx.util.Duration
|
||||
|
||||
import fmon.battle.msg._
|
||||
import fmon.draw._
|
||||
import fmon.stat._
|
||||
import fmon.stat.Statistic._
|
||||
|
||||
@@ -78,6 +80,7 @@ class BattleUI extends SignalConsumer {
|
||||
lock.lock()
|
||||
try {
|
||||
msg match {
|
||||
case AnimateMsg(ani, target) => playAnimation(ani, target)
|
||||
case Message(text) => messages.text = s"${messages.text()}${text}\n"
|
||||
case DamageMsg(dmg, target, element) => playDamage(dmg, target, element)
|
||||
}
|
||||
@@ -93,6 +96,29 @@ class BattleUI extends SignalConsumer {
|
||||
|
||||
}
|
||||
|
||||
private def playAnimation(aniname: String, target: Monster): Unit = {
|
||||
numPlaying += 1
|
||||
def helper = {
|
||||
val animation = AnimationToken(aniname).load(new File(raw"C:\Users\dalyj\Documents\Design\Images\TimmahLexusX reduced\Reduced Animations"))
|
||||
val imgView = new ImageView
|
||||
animationPane.children += imgView
|
||||
|
||||
val center = findCenter(target)
|
||||
imgView.translateX = center.x - 96 // TODO : Compute result
|
||||
imgView.translateY = center.y - 96
|
||||
|
||||
val duration = Duration(animation.frames.size * 50)
|
||||
val transition = new SpriteAnimation(imgView, animation, duration)
|
||||
transition.onFinished = handle{
|
||||
animationPane.children -= imgView
|
||||
finishPlay()
|
||||
}
|
||||
transition.play()
|
||||
}
|
||||
val task = Task(helper)
|
||||
Platform.runLater(task)
|
||||
}
|
||||
|
||||
private def playDamage(damage: Int, target: Monster, element: Element): Unit = {
|
||||
numPlaying += 1
|
||||
def helper = {
|
||||
|
||||
25
FakeMon/src/fmon/battle/msg/AnimateMsg.scala
Normal file
25
FakeMon/src/fmon/battle/msg/AnimateMsg.scala
Normal file
@@ -0,0 +1,25 @@
|
||||
package fmon.battle.msg
|
||||
|
||||
import fmon.stat.{Element, Monster}
|
||||
|
||||
case class AnimateMsg(val animation: String, target: Monster) extends Signal {
|
||||
|
||||
}
|
||||
|
||||
object AnimateMsg {
|
||||
def apply(element: Element, target: Monster): AnimateMsg = {
|
||||
val ani = element.name match {
|
||||
case "Poison" => "Poison Bubble"
|
||||
case "Electric" => "Lightning Lines"
|
||||
case "Fire" => "Rising Fire 1"
|
||||
case "Rock" => "Rock Blast"
|
||||
case "Ground" => "Stalagmites"
|
||||
case "Water" => "Rain"
|
||||
case "Flying" => "Gale"
|
||||
case "Ice" => "Glacier"
|
||||
case "Fairy" => "Light and Glass"
|
||||
case _ => "Buster"
|
||||
}
|
||||
AnimateMsg(ani, target)
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package fmon.draw
|
||||
|
||||
import java.io.{File, FileInputStream}
|
||||
|
||||
import javafx.animation.{Transition => JTransition}
|
||||
|
||||
import scalafx.Includes._
|
||||
@@ -7,6 +9,8 @@ import scalafx.animation._
|
||||
import scalafx.scene.image.ImageView
|
||||
import scalafx.util.Duration
|
||||
|
||||
import fmon.util.YamlHelper
|
||||
|
||||
class SpriteAnimation(val view: ImageView, val image: Drawable, val duration: Duration) extends JTransition {
|
||||
setCycleDuration(duration)
|
||||
setInterpolator(Interpolator.Linear)
|
||||
@@ -24,4 +28,20 @@ class AnimatedImage(val frames: IndexedSeq[Drawable]) extends Drawable {
|
||||
val index = Math.min((frames.size * t).toInt, frames.size - 1)
|
||||
frames(index).draw(view, t)
|
||||
}
|
||||
}
|
||||
|
||||
case class AnimationToken(val filename: String, val indices: IndexedSeq[Int]) {
|
||||
def load(dir: File) = {
|
||||
val file = new File(s"${dir.getPath}/${filename}")
|
||||
val palette = Palette.square(new FileInputStream(file), 5)
|
||||
val images = palette.images
|
||||
val frames = indices.map(i => images(i))
|
||||
new AnimatedImage(frames)
|
||||
}
|
||||
}
|
||||
|
||||
object AnimationToken {
|
||||
val tokens = YamlHelper.extractMap[AnimationToken](new FileInputStream(raw"C:\Users\dalyj\Documents\Design\animations.yaml"))
|
||||
|
||||
def apply(name: String) = tokens(name)
|
||||
}
|
||||
211
FakeMon/src/fmon/draw/tile/AutoFloorTile.scala
Normal file
211
FakeMon/src/fmon/draw/tile/AutoFloorTile.scala
Normal file
@@ -0,0 +1,211 @@
|
||||
package fmon.draw.tile
|
||||
|
||||
import java.io.{File, FileInputStream}
|
||||
|
||||
import scalafx.scene.SnapshotParameters
|
||||
import scalafx.scene.canvas.Canvas
|
||||
import scalafx.scene.image._
|
||||
import scalafx.scene.paint.Color
|
||||
|
||||
import fmon.draw._
|
||||
import fmon.util._
|
||||
|
||||
import Direction._
|
||||
|
||||
class AutoFloorTile(val palette: Palette, val size: Int = 48) {
|
||||
|
||||
def icon: StillImg = palette.apply(0, 0, 2, 2)
|
||||
|
||||
def build(dirs: Set[Direction.Value]) = {
|
||||
val canvas = new scalafx.scene.canvas.Canvas(size, size)
|
||||
val g = canvas.graphicsContext2D
|
||||
|
||||
val ne = getNE(dirs)
|
||||
val nw = getNW(dirs)
|
||||
val se = getSE(dirs)
|
||||
val sw = getSW(dirs)
|
||||
|
||||
canvas.graphicsContext2D.drawImage(nw, 0, 0)
|
||||
canvas.graphicsContext2D.drawImage(ne, size / 2, 0)
|
||||
canvas.graphicsContext2D.drawImage(sw, 0, size / 2)
|
||||
canvas.graphicsContext2D.drawImage(se, size / 2, size / 2)
|
||||
|
||||
val wi = new WritableImage(size, size)
|
||||
val parameters = new SnapshotParameters(){
|
||||
fill = Color.Transparent
|
||||
}
|
||||
val img = canvas.snapshot(parameters, wi)
|
||||
StillImg(img, 0, 0, size, size)
|
||||
}
|
||||
|
||||
private def getNE(dirs: Set[Direction.Value]): Image = {
|
||||
if (!dirs(Northeast) && dirs(North) && dirs(East)) {
|
||||
palette(3, 0).croppedImage()
|
||||
} else {
|
||||
val x = if (dirs(East)) 1 else 3
|
||||
val y = if (dirs(North)) 4 else 2
|
||||
palette(x, y).croppedImage
|
||||
}
|
||||
}
|
||||
|
||||
private def getNW(dirs: Set[Direction.Value]): Image = {
|
||||
if (!dirs(Northwest) && dirs(North) && dirs(West)) {
|
||||
palette(2, 0).croppedImage()
|
||||
} else {
|
||||
val x = if (dirs(West)) 2 else 0
|
||||
val y = if (dirs(North)) 4 else 2
|
||||
palette(x, y).croppedImage
|
||||
}
|
||||
}
|
||||
|
||||
private def getSE(dirs: Set[Direction.Value]): Image = {
|
||||
if (!dirs(Southeast) && dirs(South) && dirs(East)) {
|
||||
palette(3, 1).croppedImage()
|
||||
} else {
|
||||
val x = if (dirs(East)) 1 else 3
|
||||
val y = if (dirs(South)) 3 else 5
|
||||
palette(x, y).croppedImage
|
||||
}
|
||||
}
|
||||
|
||||
private def getSW(dirs: Set[Direction.Value]): Image = {
|
||||
if (!dirs(Southwest) && dirs(South) && dirs(West)) {
|
||||
palette(2, 1).croppedImage()
|
||||
} else {
|
||||
val x = if (dirs(West)) 2 else 0
|
||||
val y = if (dirs(South)) 3 else 5
|
||||
palette(x, y).croppedImage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AutoWallTile(val palette: Palette, val size: Int = 48) {
|
||||
def icon: StillImg = {
|
||||
val canvas = new scalafx.scene.canvas.Canvas(size, size)
|
||||
val g = canvas.graphicsContext2D
|
||||
|
||||
val ul = palette.apply(0, 0)
|
||||
val ur = palette.apply(3, 0)
|
||||
val ll = palette.apply(0, 3)
|
||||
val lr = palette.apply(3, 3)
|
||||
|
||||
canvas.graphicsContext2D.drawImage(ul.croppedImage(), 0, 0)
|
||||
canvas.graphicsContext2D.drawImage(ur.croppedImage(), size / 2, 0)
|
||||
canvas.graphicsContext2D.drawImage(ll.croppedImage(), 0, size / 2)
|
||||
canvas.graphicsContext2D.drawImage(lr.croppedImage(), size / 2, size / 2)
|
||||
|
||||
val wi = new WritableImage(size, size)
|
||||
val parameters = new SnapshotParameters(){
|
||||
fill = Color.Transparent
|
||||
}
|
||||
val img = canvas.snapshot(parameters, wi)
|
||||
StillImg(img, 0, 0, size, size)
|
||||
}
|
||||
|
||||
def build(dirs: Set[Direction.Value]) = {
|
||||
val canvas = new scalafx.scene.canvas.Canvas(size, size)
|
||||
val g = canvas.graphicsContext2D
|
||||
|
||||
val ul = buildUL(dirs)
|
||||
val ur = buildUR(dirs)
|
||||
val ll = buildLL(dirs)
|
||||
val lr = buildLR(dirs)
|
||||
|
||||
canvas.graphicsContext2D.drawImage(ul.croppedImage(), 0, 0)
|
||||
canvas.graphicsContext2D.drawImage(ur.croppedImage(), size / 2, 0)
|
||||
canvas.graphicsContext2D.drawImage(ll.croppedImage(), 0, size / 2)
|
||||
canvas.graphicsContext2D.drawImage(lr.croppedImage(), size / 2, size / 2)
|
||||
|
||||
val wi = new WritableImage(size, size)
|
||||
val parameters = new SnapshotParameters(){
|
||||
fill = Color.Transparent
|
||||
}
|
||||
val img = canvas.snapshot(parameters, wi)
|
||||
StillImg(img, 0, 0, size, size)
|
||||
}
|
||||
|
||||
private def buildUL(dirs: Set[Direction.Value]) = {
|
||||
val x = if (dirs(West)) 2 else 0
|
||||
val y = if (dirs(North)) 2 else 0
|
||||
palette(x, y)
|
||||
}
|
||||
|
||||
private def buildUR(dirs: Set[Direction.Value]) = {
|
||||
val x = if (dirs(East)) 1 else 3
|
||||
val y = if (dirs(North)) 2 else 0
|
||||
palette(x, y)
|
||||
}
|
||||
|
||||
private def buildLL(dirs: Set[Direction.Value]) = {
|
||||
val x = if (dirs(West)) 2 else 0
|
||||
val y = if (dirs(South)) 1 else 3
|
||||
palette(x, y)
|
||||
}
|
||||
|
||||
private def buildLR(dirs: Set[Direction.Value]) = {
|
||||
val x = if (dirs(East)) 1 else 3
|
||||
val y = if (dirs(South)) 1 else 3
|
||||
palette(x, y)
|
||||
}
|
||||
}
|
||||
|
||||
class AutoTilePalette(val palette: Palette, val size: Int) {
|
||||
def this(file: File, size: Int = 48) = this(Palette.bySize(new FileInputStream(file), size, size), size)
|
||||
|
||||
def apply(x: Int, y: Int) = {
|
||||
val img = palette.apply(x * 2, y * 3, 2, 3).croppedImage()
|
||||
new AutoFloorTile(new Palette(img, 4, 6), size)
|
||||
}
|
||||
}
|
||||
|
||||
import scalafx.Includes._
|
||||
import scalafx.application.JFXApp
|
||||
import scalafx.scene._
|
||||
import scalafx.scene.image.ImageView
|
||||
import scalafx.scene.layout.TilePane
|
||||
import scalafx.scene.paint.Color
|
||||
|
||||
import Color._
|
||||
|
||||
object AutoTileDemo extends JFXApp {
|
||||
final val MaxX = 3
|
||||
final val MaxY = 3
|
||||
|
||||
val file = raw"C:\Users\dalyj\Documents\Design\Images\AutoTiles\tilea2.png"
|
||||
val palette = new AutoTilePalette(new File(file), 32)
|
||||
val tile = palette(2, 0)
|
||||
val imgs = for (y <- 0 to MaxY; x <- 0 to MaxX) yield {
|
||||
val dirs = (x, y) match {
|
||||
case (0, 0) => Set(East, South)
|
||||
case (MaxX, MaxY) => Set(West, North)
|
||||
case (0, MaxY) => Set(East, North)
|
||||
case (MaxX, 0) => Set(West, South)
|
||||
case (0, _) => Set(East, North, South)
|
||||
case (MaxX, _) => Set(West, North, South)
|
||||
case (_, 0) => Set(East, West, South)
|
||||
case (_, MaxY) => Set(East, West, North)
|
||||
case (_, _) => Set(East, West, North, South)
|
||||
}
|
||||
tile.build(dirs)
|
||||
}
|
||||
val tiles = imgs.map(i => new ImageView(i.croppedImage()).delegate)
|
||||
|
||||
|
||||
val pane = new TilePane(){
|
||||
prefColumns = MaxX + 1
|
||||
prefRows = MaxY + 1
|
||||
}
|
||||
pane.children ++= tiles
|
||||
pane.children += new ImageView(tile.icon.croppedImage())
|
||||
|
||||
stage = new JFXApp.PrimaryStage {
|
||||
title.value = "Hello Stage"
|
||||
width = 600
|
||||
height = 450
|
||||
scene = new Scene {
|
||||
fill = LightGreen
|
||||
content = pane
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -83,6 +83,7 @@ abstract class Move extends MoveTurn {
|
||||
reader ! Message(s"$user used $name.")
|
||||
if (onTryMove(user, this, target, reader, rng)) {
|
||||
if (attackRoll(user, target)) {
|
||||
reader ! AnimateMsg(element, target)
|
||||
if (pow > 0 || powCallback != null || damageCallback != null) {
|
||||
val dmg = damageRoll(user, target)
|
||||
val actualDmg = target.takeDamage(dmg)
|
||||
|
||||
7
FakeMon/src/fmon/util/Direction.scala
Normal file
7
FakeMon/src/fmon/util/Direction.scala
Normal file
@@ -0,0 +1,7 @@
|
||||
package fmon.util
|
||||
|
||||
object Direction extends Enumeration {
|
||||
val North, Northeast, East, Southeast, South, Southwest, West, Northwest = Value
|
||||
|
||||
val cardinals = Set(North, East, South, West)
|
||||
}
|
||||
Reference in New Issue
Block a user