diff --git a/FakeMon/src/fmon/draw/AnimatedImage.scala b/FakeMon/src/fmon/draw/AnimatedImage.scala new file mode 100644 index 0000000..2b5627e --- /dev/null +++ b/FakeMon/src/fmon/draw/AnimatedImage.scala @@ -0,0 +1,26 @@ +package fmon.draw + +import javafx.animation.{Transition => JTransition} + +import scalafx.Includes._ +import scalafx.animation._ +import scalafx.scene.image.ImageView +import scalafx.util.Duration + +class SpriteAnimation(val view: ImageView, val image: Drawable, val duration: Duration) extends JTransition { + setCycleDuration(duration) + setInterpolator(Interpolator.Linear) + + def interpolate(t: Double): Unit = { + image.draw(view, t) + } +} + +class AnimatedImage(val frames: IndexedSeq[Drawable]) extends Drawable { + val lastIndex = -1 + + def draw(view: ImageView, t: Double): Unit = { + val index = Math.min((frames.size * t).toInt, frames.size - 1) + frames(index).draw(view, t) + } +} \ No newline at end of file diff --git a/FakeMon/src/fmon/draw/Battler.scala b/FakeMon/src/fmon/draw/Battler.scala new file mode 100644 index 0000000..a1a2445 --- /dev/null +++ b/FakeMon/src/fmon/draw/Battler.scala @@ -0,0 +1,67 @@ +package fmon.draw + +import java.io._ + +object Battler { + final val FramesPerPose = 3 + + def apply(filename: String): Sprite = { + this(new File(filename)) + } + + def apply(file: File): Sprite = { + val palette = new Palette(new FileInputStream(file), 9, 6) + def pose(x: Int, y: Int): AnimatedImage = { + val xx = x * FramesPerPose + val frames = IndexedSeq(palette(xx, y), palette(xx + 1, y), palette(xx + 2, y), palette(xx + 1, y)) + new AnimatedImage(frames) + } + val poses = Map( + "Idle" -> pose(0, 0), + "ReadyPhys" -> pose(0, 1), + "ReadyMag" -> pose(0, 2), + "Guard" -> pose(0, 3), + "Damage" -> pose(0, 4), + "Evade" -> pose(0, 5), + "Stab" -> pose(1, 0), + "Swing" -> pose(1, 1), + "Shoot" -> pose(1, 2), + "PhysSkill" -> pose(1, 3), + "MagSkill" -> pose(1, 4), + "Item" -> pose(1, 5), + "Escape" -> pose(2, 0), + "Victory" -> pose(2, 1), + "Crisis" -> pose(2, 2), + "Abnormal" -> pose(2, 3), + "Sleep" -> pose(2, 4), + "Dead" -> pose(2, 5) + ) + new Sprite("Idle", poses) + } +} + +import scalafx.application.JFXApp +import scalafx.scene._ +import scalafx.scene.control._ +import scalafx.scene.image._ +import scalafx.scene.paint.Color._ +import scalafx.util.Duration + +object DrawingDemo extends JFXApp { + val view = new ImageView + stage = new JFXApp.PrimaryStage { + title.value = "Hello Stage" + width = 600 + height = 450 + scene = new Scene { + fill = LightGreen + content = view + } + } + val battler = Battler(raw"C:\Users\James\Documents\Design\fakemon\images\Aekashics Librarium MV Format Animated Battlers\Aekashics Librarium MV Format Animated Battlers\RPG Maker MV format Animated Sideview Battlers\Bat\Bat1_1.png") + val animation = new SpriteAnimation(view, battler, new Duration(1000)) { + setCycleCount(10) + } + animation.play() + +} \ No newline at end of file diff --git a/FakeMon/src/fmon/draw/Drawable.scala b/FakeMon/src/fmon/draw/Drawable.scala new file mode 100644 index 0000000..624e702 --- /dev/null +++ b/FakeMon/src/fmon/draw/Drawable.scala @@ -0,0 +1,7 @@ +package fmon.draw + +import scalafx.scene.image.ImageView + +trait Drawable { + def draw(view: ImageView, t: Double): Unit +} \ No newline at end of file diff --git a/FakeMon/src/fmon/draw/Palette.scala b/FakeMon/src/fmon/draw/Palette.scala new file mode 100644 index 0000000..0cd316e --- /dev/null +++ b/FakeMon/src/fmon/draw/Palette.scala @@ -0,0 +1,40 @@ +package fmon.draw + +import java.io.InputStream + +import scalafx.geometry.Rectangle2D +import scalafx.scene.image.{Image, ImageView} + +case class Box(val x: Int, val y: Int, val width: Int, val height: Int) + +case class StillImg(val image: Image, val x: Double, val y: Double, val width: Double, val height: Double) extends Drawable { + def draw(view: ImageView, t: Double): Unit = { + if (view.image() != image.delegate) { + view.image = image + } + view.viewport = new Rectangle2D(x, y, width, height) + } +} + +class Palette(val image: Image, val numAcross: Int, val numDown: Int) { + def this(url: String, numAcross: Int, numDown: Int) = this(new Image(url), numAcross, numDown) + def this(stream: InputStream, numAcross: Int, numDown: Int) = this(new Image(stream), numAcross, numDown) + + val imgWidth = image.width() / numAcross + val imgHeight = image.height() / numDown + + def apply(x: Int, y: Int): StillImg = { + StillImg(image, x * imgWidth, y * imgHeight, imgWidth, imgHeight) + } + + def apply(x : Int, y : Int, w : Int, h : Int): StillImg = { + StillImg(image, x * imgWidth, y * imgHeight, w * imgWidth, h * imgHeight) + } + + /** + * Creates a sub-image that spans multiple cells + */ + def apply(cells : Box): StillImg = { + this(cells.x, cells.y, cells.width, cells.height) + } +} \ No newline at end of file diff --git a/FakeMon/src/fmon/draw/Sprite.scala b/FakeMon/src/fmon/draw/Sprite.scala new file mode 100644 index 0000000..8f054c3 --- /dev/null +++ b/FakeMon/src/fmon/draw/Sprite.scala @@ -0,0 +1,9 @@ +package fmon.draw + +import scalafx.scene.image.{Image, ImageView} + +class Sprite(var pose: String, val poses: Map[String, Drawable]) extends Drawable { + def draw(view: ImageView, t: Double): Unit = { + poses(pose).draw(view, t) + } +} \ No newline at end of file