forked from nova/jmonkey-test
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
2.8 KiB
92 lines
2.8 KiB
package wow.doge.mygame.state
|
|
|
|
import akka.actor.typed.scaladsl.ActorContext
|
|
import akka.actor.typed.Behavior
|
|
import akka.actor.typed.scaladsl.Behaviors
|
|
import com.softwaremill.quicklens._
|
|
import wow.doge.mygame.implicits._
|
|
import com.jme3.renderer.Camera
|
|
import wow.doge.mygame.math.ImVector3f
|
|
|
|
trait CanMove[-A] {
|
|
def getDirection(cam: Camera, cardinalDir: CardinalDirection): ImVector3f
|
|
def move(inst: A, direction: ImVector3f): Unit
|
|
}
|
|
|
|
object ImMovementActor {
|
|
sealed trait Command
|
|
// final case class Tick(tpf: Float) extends Command
|
|
final case class Tick(tpf: Float) extends Command
|
|
|
|
sealed trait Movement extends Command
|
|
final case class MovedLeft(pressed: Boolean) extends Movement
|
|
final case class MovedUp(pressed: Boolean) extends Movement
|
|
final case class MovedRight(pressed: Boolean) extends Movement
|
|
final case class MovedDown(pressed: Boolean) extends Movement
|
|
|
|
final case class Props[T: CanMove](
|
|
app: com.jme3.app.Application,
|
|
movable: T
|
|
)
|
|
|
|
/**
|
|
* Internal state of the actor
|
|
*
|
|
* @param cardinalDir Immutable, can be shared as is
|
|
* @param walkDirection Immutable
|
|
*/
|
|
final case class State(
|
|
cardinalDir: CardinalDirection = CardinalDirection()
|
|
)
|
|
|
|
def apply[T: CanMove](props: Props[T]): Behavior[Command] =
|
|
Behaviors.setup(ctx => {
|
|
ctx.log.info("Hello from MovementActor")
|
|
new ImMovementActor(ctx, props).receive(State())
|
|
})
|
|
|
|
}
|
|
|
|
class ImMovementActor[T](
|
|
ctx: ActorContext[ImMovementActor.Command],
|
|
props: ImMovementActor.Props[T]
|
|
) {
|
|
import ImMovementActor._
|
|
|
|
def receive(
|
|
state: ImMovementActor.State
|
|
)(implicit cm: CanMove[T]): Behavior[Command] =
|
|
Behaviors.receiveMessage { msg =>
|
|
msg match {
|
|
case m: Movement =>
|
|
m match {
|
|
case MovedLeft(pressed) =>
|
|
receive(state = state.modify(_.cardinalDir.left).setTo(pressed))
|
|
case MovedUp(pressed) =>
|
|
receive(state = state.modify(_.cardinalDir.up).setTo(pressed))
|
|
case MovedRight(pressed) =>
|
|
receive(state = state.modify(_.cardinalDir.right).setTo(pressed))
|
|
case MovedDown(pressed) =>
|
|
receive(state = state.modify(_.cardinalDir.down).setTo(pressed))
|
|
}
|
|
|
|
case Tick(tpf) =>
|
|
val walkDir =
|
|
cm.getDirection(props.app.getCamera(), state.cardinalDir)
|
|
if (walkDir != ImVector3f.ZERO) {
|
|
val tmp = walkDir * 25f * tpf
|
|
// props.app.enqueue(new Runnable {
|
|
// override def run(): Unit = {
|
|
// cm.move(props.movable, tmp)
|
|
// }
|
|
// })
|
|
props.app.enqueueF {
|
|
cm.move(props.movable, tmp)
|
|
}
|
|
}
|
|
Behaviors.same
|
|
// receive(state = state.modify(_.walkDirection).setTo(walkDir))
|
|
|
|
}
|
|
}
|
|
}
|