diff --git a/FakeMon/src/fmon/Game.scala b/FakeMon/src/fmon/Game.scala index 3b72fbd..bbfa049 100644 --- a/FakeMon/src/fmon/Game.scala +++ b/FakeMon/src/fmon/Game.scala @@ -29,8 +29,8 @@ class Game extends Application { implicit val rng = new scala.util.Random() val form1 = Form("Diabolo") val form2 = Form("Chanilla") - val movepool1 = IndexedSeq(Move("eruption"), Move("willowisp"), Move("thunderbolt"), Move("thunderwave"), Move("blastburn")) - val movepool2 = IndexedSeq(Move("razorwind")) + val movepool1 = IndexedSeq(Move("eruption"), Move("willowisp"), Move("thunderbolt"), Move("thunderwave"), Move("thundershock")) + val movepool2 = IndexedSeq(Move("tackle")) val p1 = TrainerID("Jaeda", Gender.Female, 0) val p2 = TrainerID("Wild Monster", Gender.Male, 0) val party1 = new Party(p1, new MonsterPtr(Monster.generate("Allied Mon", p1, 500, form1, movepool1)), IndexedSeq()) diff --git a/FakeMon/src/fmon/battle/BattleUI.scala b/FakeMon/src/fmon/battle/BattleUI.scala index 485dd33..190b0c4 100644 --- a/FakeMon/src/fmon/battle/BattleUI.scala +++ b/FakeMon/src/fmon/battle/BattleUI.scala @@ -1,5 +1,8 @@ package fmon.battle +import java.util.concurrent.locks.{Condition, ReentrantLock} + +import javafx.application.Platform import javafx.fxml.FXML import javafx.fxml.FXMLLoader import javafx.fxml.JavaFXBuilderFactory @@ -8,6 +11,7 @@ import javafx.scene.image.ImageView import scalafx.Includes._ import scalafx.animation._ +import scalafx.concurrent.Task import scalafx.geometry.{Point2D, Pos} import scalafx.scene.{Group, Parent} import scalafx.scene.control._ @@ -36,6 +40,10 @@ class BattleUI extends SignalConsumer { private var engine: BattleEngine = _ + private var numPlaying = 0 + private val lock = new ReentrantLock() + private val finishedPlaying = lock.newCondition() + def setEngine(engine: BattleEngine): Unit = { this.engine = engine updateUI() @@ -51,64 +59,100 @@ class BattleUI extends SignalConsumer { enemyMonController.update(enemy) } + def requestUpdateUI(): Unit = { + val task = Task(updateUI) + Platform.runLater(task) + } + def onMove(move: Move): Unit = { implicit val rng = engine.rng implicit val reader = engine val action = Action(engine.player.lead, move, engine.player.pollTarget(move, engine.player.lead, engine.enemy)) - engine.playTurn(action) - updateUI() + val task = Task(engine.playTurn(action)) + val thread = new Thread(task) + thread.setDaemon(true) + thread.start() } 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) + lock.lock() + try { + msg match { + case Message(text) => messages.text = s"${messages.text()}${text}\n" + case DamageMsg(dmg, target, element) => playDamage(dmg, target, element) + } + while (numPlaying > 0) { + finishedPlaying.await() + } + requestUpdateUI() + } catch { + case e: Exception => e.printStackTrace() + } finally { + lock.unlock() } + } private def playDamage(damage: Int, target: Monster, element: Element): Unit = { - val r = 25 - val color = Color.AliceBlue - val center = findCenter(target) - - 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) + numPlaying += 1 + def helper = { + val r = 25 + val color = Color.AliceBlue + val center = findCenter(target) + + val circle = new Circle { + radius = 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) + 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) } - )) - animation.onFinished = handle{ - animationPane.children -= group + }): _*) + 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 + finishPlay() + } + animation.play() + animationPane.children += group + } + val task = Task(helper) + Platform.runLater(task) + } + + private def finishPlay(): Unit = { + lock.lock() + try { + numPlaying -= 1 + updateUI() + finishedPlaying.signal() + } finally { + lock.unlock() } - animation.play() - animationPane.children += group } private def findCenter(monster: Monster): Point2D = {