Added movement abilities to NPCs

This commit is contained in:
dalyjame 2019-08-14 17:02:28 -04:00
parent 94f12b5676
commit f7747346d7
6 changed files with 74 additions and 23 deletions

View File

@ -0,0 +1,7 @@
package fmon.script.action
import fmon.script.Action
class MessageAction[A](val msg: String) extends Action[A] {
override def apply(env: A) = println(msg)
}

View File

@ -1,5 +1,7 @@
package fmon.util package fmon.util
import fmon.Direction
object Direction extends Enumeration { object Direction extends Enumeration {
case class Val protected(x: Int = 0, y: Int = 0) extends super.Val { case class Val protected(x: Int = 0, y: Int = 0) extends super.Val {
} }
@ -15,4 +17,6 @@ object Direction extends Enumeration {
val Northwest = Val(x = -1, y = -1) val Northwest = Val(x = -1, y = -1)
val cardinals = Set(North, East, South, West) val cardinals = Set(North, East, South, West)
def byName(s: String): Direction = super.withName(s).asInstanceOf[Direction]
} }

View File

@ -6,12 +6,17 @@ import fmon._
import fmon.draw._ import fmon.draw._
import fmon.util.Direction import fmon.util.Direction
class Actor(val sprite: Sprite, var pos: Position, var move: Movement) { abstract class Actor(val sprite: Sprite, var pos: Position, var move: Movement) {
def x: Int = pos.x def x: Int = pos.x
def y: Int = pos.y def y: Int = pos.y
def xreal: Double = x - move.direction.x * move.completion def xreal: Double = x - move.direction.x * move.completion
def yreal: Double = y - move.direction.y * move.completion def yreal: Double = y - move.direction.y * move.completion
val imgView = new AnimatedImageView(sprite, new Duration(600)) {
x = pos.x * Config.tileSize
y = pos.y * Config.tileSize + Config.yOffset
}
def pose: String = sprite.pose def pose: String = sprite.pose
def pose_=(p: String) = { def pose_=(p: String) = {
sprite.pose = p sprite.pose = p
@ -20,8 +25,21 @@ class Actor(val sprite: Sprite, var pos: Position, var move: Movement) {
def slide(dt: Duration): Unit = { def slide(dt: Duration): Unit = {
move.completion -= dt.toSeconds() * Config.moveSpeed move.completion -= dt.toSeconds() * Config.moveSpeed
if (move.completion <= 0) { if (move.completion <= 0) {
//pos += move.direction move = selectNextMove
move = new Movement(Direction.Stationary, 0) pos += move.direction
if (move.direction != Direction.Stationary) {
imgView.play()
} else {
imgView.stop()
}
} }
imgView.x = xreal * Config.tileSize
imgView.y = yreal * Config.tileSize + Config.yOffset
} }
def selectNextMove: Movement
}
class Hero(sprite: Sprite, pos: Position) extends Actor(sprite, pos, new Movement(Direction.Stationary, 0)) {
def selectNextMove = new Movement(Direction.Stationary, 0)
} }

View File

@ -1,13 +1,16 @@
package fmon.world package fmon.world
class EventPage { import fmon.draw.Sprite
import fmon.script.Action
class EventPage (
// Conditions // Conditions
// Switch // Switch
// Variable // Variable
// Self-Switch // Self-Switch
// Item // Item
// Actor // Actor
// Graphic val sprite : Sprite,
// Priority - Above or below // Priority - Above or below
// Trigger - Action button / On contact // Trigger - Action button / On contact
// Movement // Movement
@ -19,5 +22,6 @@ class EventPage {
// Stepping Animation // Stepping Animation
// Direction Fix // Direction Fix
// Pass through (no-collide) // Pass through (no-collide)
// Contents (event effects) val action: Action[Actor]
) {
} }

View File

@ -1,6 +1,18 @@
package fmon.world package fmon.world
import fmon._
import fmon.util.Direction
class GameEvent(val name: String, val pages: IndexedSeq[EventPage]) { class GameEvent(val name: String, val pages: IndexedSeq[EventPage]) {
def currPage = pages.head // TODO : Conditions
// Event Name // Event Name
// Event Pages // Event Pages
} }
class NPC(val event: GameEvent, pos: Position)
extends Actor(event.currPage.sprite, pos, new Movement(Direction.Stationary, 0.0)) {
def selectNextMove: Movement = {
new Movement(Direction.Stationary, 0.0)
}
}

View File

@ -27,6 +27,7 @@ import FileChooser.ExtensionFilter
import fmon._ import fmon._
import fmon.draw._ import fmon.draw._
import fmon.script.action.MessageAction
import fmon.util.Direction import fmon.util.Direction
import fmon.world._ import fmon.world._
import fmon.util.YamlHelper import fmon.util.YamlHelper
@ -39,7 +40,7 @@ class GameView {
@FXML var characterPane: jfxsl.AnchorPane = _ @FXML var characterPane: jfxsl.AnchorPane = _
var hero: Actor = _ var hero: Actor = _
var npcs = Seq[Actor]() var npcs = Seq[NPC]()
def actors = hero +: npcs def actors = hero +: npcs
var heroImg: AnimatedImageView = _ var heroImg: AnimatedImageView = _
@ -71,22 +72,20 @@ class GameView {
doodads.children ++= dtiles doodads.children ++= dtiles
val heroFile = Config.homedir + raw"Progena\Resources\characters\Actor1.png" val heroFile = Config.homedir + raw"Progena\Resources\characters\Actor1.png"
hero = new Actor(CharSet(new File(heroFile), 1), Position(5, 4), new Movement(Direction.Stationary, 0.0)) hero = new Hero(CharSet(new File(heroFile), 1), Position(5, 4))
heroImg = new AnimatedImageView(hero.sprite, new Duration(600)) { heroImg = hero.imgView
x = hero.x * Config.tileSize
y = hero.y * Config.tileSize + Config.yOffset
}
npcs = (0 until 8).map(i => npcs = (0 until 8).map(i => {
new Actor(CharSet(new File(heroFile), i), Position(7 + i, 4), new Movement(Direction.Stationary, 0.0)) val event = new GameEvent(s"NPC $i", IndexedSeq(new EventPage(
) CharSet(new File(heroFile), i),
new MessageAction(s"I am NPC $i")
)))
new NPC(event, Position(7 + i, 3))
})
characterPane.children += heroImg characterPane.children += heroImg
val npcImgs = npcs.map(npc => new AnimatedImageView(npc.sprite, new Duration(600)) { val npcImgs = npcs.map(npc => npc.imgView)
x = npc.x * Config.tileSize
y = npc.y * Config.tileSize + Config.yOffset
})
npcImgs.foreach(characterPane.children += _) npcImgs.foreach(characterPane.children += _)
timer.start() timer.start()
@ -98,6 +97,7 @@ class GameView {
case KeyCode.D | KeyCode.Right => setDir(East) case KeyCode.D | KeyCode.Right => setDir(East)
case KeyCode.A | KeyCode.Left => setDir(West) case KeyCode.A | KeyCode.Left => setDir(West)
case KeyCode.S | KeyCode.Down => setDir(South) case KeyCode.S | KeyCode.Down => setDir(South)
case KeyCode.Space => activate()
case _ => () case _ => ()
} }
} }
@ -112,15 +112,21 @@ class GameView {
} }
} }
def activate(): Unit = {
if (hero.move.direction == Direction.Stationary) {
val dir = Direction.byName(hero.sprite.pose)
val np = hero.pos + dir
npcs.filter(npc => npc.pos == np).foreach(npc => npc.event.currPage.action(npc))
}
}
def setDir(dir: Direction): Unit = { def setDir(dir: Direction): Unit = {
currDir = Some(dir) currDir = Some(dir)
heroImg.play()
} }
def clearDir(dir: Direction): Unit = { def clearDir(dir: Direction): Unit = {
if (currDir == Some(dir)) { if (currDir == Some(dir)) {
currDir = None currDir = None
heroImg.stop()
} }
} }
@ -147,12 +153,12 @@ class GameView {
if (canPass && unoccupied) { if (canPass && unoccupied) {
hero.pos += dir hero.pos += dir
hero.move = new Movement(dir, 1.0) hero.move = new Movement(dir, 1.0)
hero.imgView.play()
} }
} }
} }
hero.slide(dur) hero.slide(dur)
heroImg.x = hero.xreal * Config.tileSize npcs.foreach(_.slide(dur))
heroImg.y = hero.yreal * Config.tileSize + Config.yOffset
} }
/* /*