Added animations for dealing damage, but they currently happen concurrently

This commit is contained in:
James Daly 2019-06-17 22:16:19 -04:00
parent 38dbb7fa92
commit 2ea3b98514
4 changed files with 92 additions and 5 deletions

View File

@ -4,11 +4,19 @@ import javafx.fxml.FXML
import javafx.fxml.FXMLLoader import javafx.fxml.FXMLLoader
import javafx.fxml.JavaFXBuilderFactory import javafx.fxml.JavaFXBuilderFactory
import javafx.scene.{control => jfxsc} import javafx.scene.{control => jfxsc}
import javafx.scene.image.ImageView
import scalafx.Includes._ 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.control._
import scalafx.scene.layout._ 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.battle.msg._
import fmon.stat._ import fmon.stat._
@ -17,6 +25,11 @@ import fmon.stat.Statistic._
class BattleUI extends SignalConsumer { class BattleUI extends SignalConsumer {
@FXML var buttonPane: javafx.scene.layout.VBox = _ @FXML var buttonPane: javafx.scene.layout.VBox = _
@FXML var messages: jfxsc.TextArea = _ @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 playerMonController: InfoWidget = _
@FXML var enemyMonController: InfoWidget = _ @FXML var enemyMonController: InfoWidget = _
@ -47,9 +60,71 @@ class BattleUI extends SignalConsumer {
def !(msg: Signal): Unit = { def !(msg: Signal): Unit = {
msg match { msg match {
case Message(text) => messages.text = s"${messages.text()}${text}\n" 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 = { private def loadMoveButton(move: Move): Button = {
val fxmlLoader = new FXMLLoader(getClass.getResource("moveButton.fxml")) val fxmlLoader = new FXMLLoader(getClass.getResource("moveButton.fxml"))
fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory()) fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory())

View File

@ -9,6 +9,7 @@
<?import javafx.scene.image.Image?> <?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?> <?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?> <?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?> <?import javafx.scene.layout.VBox?>
<VBox prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fmon.battle.BattleUI"> <VBox prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fmon.battle.BattleUI">
@ -54,21 +55,22 @@
</MenuBar> </MenuBar>
<AnchorPane maxHeight="-1.0" maxWidth="-1.0" prefHeight="-1.0" prefWidth="-1.0" VBox.vgrow="ALWAYS"> <AnchorPane maxHeight="-1.0" maxWidth="-1.0" prefHeight="-1.0" prefWidth="-1.0" VBox.vgrow="ALWAYS">
<children> <children>
<ImageView fitHeight="575.0" fitWidth="856.0" pickOnBounds="true"> <ImageView fx:id="backgroundImg" fitHeight="575.0" fitWidth="856.0" pickOnBounds="true">
<image> <image>
<Image url="@images/scene01.jpg" /> <Image url="@images/scene01.jpg" />
</image> </image>
</ImageView> </ImageView>
<ImageView fitHeight="250.0" fitWidth="250.0" layoutX="14.0" layoutY="279.0" pickOnBounds="true" preserveRatio="true"> <ImageView fx:id="playerImg" fitHeight="250.0" fitWidth="250.0" layoutX="14.0" layoutY="279.0" pickOnBounds="true" preserveRatio="true">
<image> <image>
<Image url="@images/Colossal%20Bat.png" /> <Image url="@images/Colossal%20Bat.png" />
</image> </image>
</ImageView> </ImageView>
<ImageView fitHeight="250.0" fitWidth="250.0" layoutX="606.0" layoutY="87.0" pickOnBounds="true" preserveRatio="true"> <ImageView fx:id="enemyImg" fitHeight="250.0" fitWidth="250.0" layoutX="606.0" layoutY="87.0" pickOnBounds="true" preserveRatio="true">
<image> <image>
<Image url="@images/Darkness%20Slime.png" /> <Image url="@images/Darkness%20Slime.png" />
</image> </image>
</ImageView> </ImageView>
<Pane fx:id="animationPane" prefHeight="575.0" prefWidth="856.0" />
<ScrollPane hbarPolicy="NEVER" layoutX="32.0" layoutY="29.0" prefHeight="200.0" prefWidth="200.0"> <ScrollPane hbarPolicy="NEVER" layoutX="32.0" layoutY="29.0" prefHeight="200.0" prefWidth="200.0">
<content> <content>
<VBox fx:id="buttonPane" /> <VBox fx:id="buttonPane" />

View File

@ -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 {
}

View File

@ -9,7 +9,7 @@ import scala.io.Source
import scala.util.Random import scala.util.Random
import Statistic._ import Statistic._
import fmon.battle.msg.{Message, SignalConsumer} import fmon.battle.msg._
import fmon.util._ import fmon.util._
object MoveType extends Enumeration { object MoveType extends Enumeration {
@ -81,8 +81,10 @@ abstract class Move extends MoveTurn {
val actualDmg = target.takeDamage(dmg) val actualDmg = target.takeDamage(dmg)
if (dmg == actualDmg) { if (dmg == actualDmg) {
reader ! Message(s"$target takes $actualDmg damage!") reader ! Message(s"$target takes $actualDmg damage!")
reader ! DamageMsg(dmg, target, element)
} else { } else {
reader ! Message(s"$target takes $actualDmg (+${dmg - actualDmg} overkill) damage!") reader ! Message(s"$target takes $actualDmg (+${dmg - actualDmg} overkill) damage!")
reader ! DamageMsg(dmg, target, element)
} }
if (drain > 0.frac) { if (drain > 0.frac) {
val healing = Math.max(drain * actualDmg, 1) val healing = Math.max(drain * actualDmg, 1)
@ -92,6 +94,7 @@ abstract class Move extends MoveTurn {
val recoil = Math.max(-drain * actualDmg, 1) val recoil = Math.max(-drain * actualDmg, 1)
user.takeDamage(recoil) user.takeDamage(recoil)
reader ! Message(s"$user took $recoil damage from recoil!") reader ! Message(s"$user took $recoil damage from recoil!")
reader ! DamageMsg(actualDmg, target, Element("None"))
} }
target.base.ability.onAfterDamage(user, this, target, actualDmg) target.base.ability.onAfterDamage(user, this, target, actualDmg)