From 2ea3b985140fb92ce69eaa6297c5a49799dcd51b Mon Sep 17 00:00:00 2001 From: James Daly Date: Mon, 17 Jun 2019 22:16:19 -0400 Subject: [PATCH] Added animations for dealing damage, but they currently happen concurrently --- FakeMon/src/fmon/battle/BattleUI.scala | 77 ++++++++++++++++++++- FakeMon/src/fmon/battle/battle.fxml | 8 ++- FakeMon/src/fmon/battle/msg/DamageMsg.scala | 7 ++ FakeMon/src/fmon/stat/Move.scala | 5 +- 4 files changed, 92 insertions(+), 5 deletions(-) create mode 100644 FakeMon/src/fmon/battle/msg/DamageMsg.scala diff --git a/FakeMon/src/fmon/battle/BattleUI.scala b/FakeMon/src/fmon/battle/BattleUI.scala index 6aff388..2db932f 100644 --- a/FakeMon/src/fmon/battle/BattleUI.scala +++ b/FakeMon/src/fmon/battle/BattleUI.scala @@ -4,11 +4,19 @@ import javafx.fxml.FXML import javafx.fxml.FXMLLoader import javafx.fxml.JavaFXBuilderFactory import javafx.scene.{control => jfxsc} +import javafx.scene.image.ImageView import scalafx.Includes._ -import scalafx.scene.Parent +import scalafx.animation._ +import scalafx.geometry.{Point2D, Pos} +import scalafx.scene.{Group, Parent} import scalafx.scene.control._ import scalafx.scene.layout._ +import scalafx.scene.paint.Color +import scalafx.scene.shape.{Circle, Polygon} +import scalafx.scene.text.Font +import scalafx.scene.transform.Rotate +import scalafx.util.Duration import fmon.battle.msg._ import fmon.stat._ @@ -17,6 +25,11 @@ import fmon.stat.Statistic._ class BattleUI extends SignalConsumer { @FXML var buttonPane: javafx.scene.layout.VBox = _ @FXML var messages: jfxsc.TextArea = _ + @FXML var animationPane: javafx.scene.layout.Pane = _ + + @FXML var backgroundImg: ImageView = _ + @FXML var playerImg: ImageView = _ + @FXML var enemyImg: ImageView = _ @FXML var playerMonController: InfoWidget = _ @FXML var enemyMonController: InfoWidget = _ @@ -47,9 +60,71 @@ class BattleUI extends SignalConsumer { def !(msg: Signal): Unit = { msg match { case Message(text) => messages.text = s"${messages.text()}${text}\n" + case DamageMsg(dmg, target, element) => playDamage(dmg, target, element) } } + private def playDamage(damage: Int, target: Monster, element: Element): Unit = { + val r = 25 + val color = Color.AliceBlue + val center = findCenter(target) + print(center) + + val circle = new Circle { + radius = r + fill = color + } + val points = new Group((0 until 6).map(i => { + new Polygon { + points ++= Seq(-r/2, r, 0, 2*r, +r/2, r) + fill = color + transforms += new Rotate(60 * i, 0, 0, 0, Rotate.ZAxis) + } + }): _*) + val label = new Label(s"${damage}") { + font = Font(24) + alignment = Pos.Center + } + val group = new Group(circle, points, label) + group.translateX = center.x + group.translateY = center.y + + val animation = new SequentialTransition(group, Seq( + // Fade In + new FadeTransition{ + fromValue = 0.0 + toValue = 1.0 + duration = Duration(250) + }, + // Fade Out + new FadeTransition{ + fromValue = 1.0 + toValue = 0.0 + duration = Duration(750) + } + )) + animation.onFinished = handle{ + animationPane.children -= group + } + animation.play() + animationPane.children += group + } + + private def findCenter(monster: Monster): Point2D = { + if (monster == engine.player.lead.mon) { + centerOfControl(playerImg) + } else { + centerOfControl(enemyImg) + } + } + + private def centerOfControl(control: ImageView): Point2D = { + val bounds = control.boundsInParent() + val x = bounds.minX + bounds.width / 2 + val y = bounds.minY + bounds.height / 2 + new Point2D(x, y) + } + private def loadMoveButton(move: Move): Button = { val fxmlLoader = new FXMLLoader(getClass.getResource("moveButton.fxml")) fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory()) diff --git a/FakeMon/src/fmon/battle/battle.fxml b/FakeMon/src/fmon/battle/battle.fxml index 9bf7d70..886e214 100644 --- a/FakeMon/src/fmon/battle/battle.fxml +++ b/FakeMon/src/fmon/battle/battle.fxml @@ -9,6 +9,7 @@ + @@ -54,21 +55,22 @@ - + - + - + + diff --git a/FakeMon/src/fmon/battle/msg/DamageMsg.scala b/FakeMon/src/fmon/battle/msg/DamageMsg.scala new file mode 100644 index 0000000..2caadb9 --- /dev/null +++ b/FakeMon/src/fmon/battle/msg/DamageMsg.scala @@ -0,0 +1,7 @@ +package fmon.battle.msg + +import fmon.stat.{Element, Monster} + +case class DamageMsg(val amount: Int, target: Monster, val element: Element) extends Signal { + +} \ No newline at end of file diff --git a/FakeMon/src/fmon/stat/Move.scala b/FakeMon/src/fmon/stat/Move.scala index 3b253fc..bbd8e6a 100644 --- a/FakeMon/src/fmon/stat/Move.scala +++ b/FakeMon/src/fmon/stat/Move.scala @@ -9,7 +9,7 @@ import scala.io.Source import scala.util.Random import Statistic._ -import fmon.battle.msg.{Message, SignalConsumer} +import fmon.battle.msg._ import fmon.util._ object MoveType extends Enumeration { @@ -81,8 +81,10 @@ abstract class Move extends MoveTurn { val actualDmg = target.takeDamage(dmg) if (dmg == actualDmg) { reader ! Message(s"$target takes $actualDmg damage!") + reader ! DamageMsg(dmg, target, element) } else { reader ! Message(s"$target takes $actualDmg (+${dmg - actualDmg} overkill) damage!") + reader ! DamageMsg(dmg, target, element) } if (drain > 0.frac) { val healing = Math.max(drain * actualDmg, 1) @@ -92,6 +94,7 @@ abstract class Move extends MoveTurn { val recoil = Math.max(-drain * actualDmg, 1) user.takeDamage(recoil) reader ! Message(s"$user took $recoil damage from recoil!") + reader ! DamageMsg(actualDmg, target, Element("None")) } target.base.ability.onAfterDamage(user, this, target, actualDmg)