Testing out JmonkeyEngine to make a game in Scala with Akka Actors within a pure FP layer
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

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. package wow.doge.mygame.state
  2. import akka.actor.typed.scaladsl.ActorContext
  3. import akka.actor.typed.Behavior
  4. import akka.actor.typed.scaladsl.Behaviors
  5. import com.softwaremill.quicklens._
  6. import wow.doge.mygame.implicits._
  7. import com.jme3.renderer.Camera
  8. import wow.doge.mygame.math.ImVector3f
  9. trait CanMove[-A] {
  10. def getDirection(cam: Camera, cardinalDir: CardinalDirection): ImVector3f
  11. def move(inst: A, direction: ImVector3f): Unit
  12. }
  13. object ImMovementActor {
  14. sealed trait Command
  15. // final case class Tick(tpf: Float) extends Command
  16. final case class Tick(tpf: Float) extends Command
  17. sealed trait Movement extends Command
  18. final case class MovedLeft(pressed: Boolean) extends Movement
  19. final case class MovedUp(pressed: Boolean) extends Movement
  20. final case class MovedRight(pressed: Boolean) extends Movement
  21. final case class MovedDown(pressed: Boolean) extends Movement
  22. final case class Props[T: CanMove](
  23. app: com.jme3.app.Application,
  24. movable: T
  25. )
  26. /**
  27. * Internal state of the actor
  28. *
  29. * @param cardinalDir Immutable, can be shared as is
  30. * @param walkDirection Immutable
  31. */
  32. final case class State(
  33. cardinalDir: CardinalDirection = CardinalDirection()
  34. )
  35. def apply[T: CanMove](props: Props[T]): Behavior[Command] =
  36. Behaviors.setup(ctx => {
  37. ctx.log.info("Hello from MovementActor")
  38. new ImMovementActor(ctx, props).receive(State())
  39. })
  40. }
  41. class ImMovementActor[T](
  42. ctx: ActorContext[ImMovementActor.Command],
  43. props: ImMovementActor.Props[T]
  44. ) {
  45. import ImMovementActor._
  46. def receive(
  47. state: ImMovementActor.State
  48. )(implicit cm: CanMove[T]): Behavior[Command] =
  49. Behaviors.receiveMessage { msg =>
  50. msg match {
  51. case m: Movement =>
  52. m match {
  53. case MovedLeft(pressed) =>
  54. receive(state = state.modify(_.cardinalDir.left).setTo(pressed))
  55. case MovedUp(pressed) =>
  56. receive(state = state.modify(_.cardinalDir.up).setTo(pressed))
  57. case MovedRight(pressed) =>
  58. receive(state = state.modify(_.cardinalDir.right).setTo(pressed))
  59. case MovedDown(pressed) =>
  60. receive(state = state.modify(_.cardinalDir.down).setTo(pressed))
  61. }
  62. case Tick(tpf) =>
  63. val walkDir =
  64. cm.getDirection(props.app.getCamera(), state.cardinalDir)
  65. if (walkDir != ImVector3f.ZERO) {
  66. val tmp = walkDir * 25f * tpf
  67. // props.app.enqueue(new Runnable {
  68. // override def run(): Unit = {
  69. // cm.move(props.movable, tmp)
  70. // }
  71. // })
  72. props.app.enqueueF {
  73. cm.move(props.movable, tmp)
  74. }
  75. }
  76. Behaviors.same
  77. // receive(state = state.modify(_.walkDirection).setTo(walkDir))
  78. }
  79. }
  80. }