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.

149 lines
5.0 KiB

3 years ago
  1. package wow.doge.mygame.game.entities.player
  2. import scala.concurrent.duration._
  3. import akka.actor.typed.ActorRef
  4. import akka.actor.typed.Behavior
  5. import akka.actor.typed.LogOptions
  6. import akka.actor.typed.PostStop
  7. import akka.actor.typed.SupervisorStrategy
  8. import akka.actor.typed.scaladsl.ActorContext
  9. import akka.actor.typed.scaladsl.Behaviors
  10. import com.typesafe.scalalogging.Logger
  11. import org.slf4j.event.Level
  12. import wow.doge.mygame.Dispatchers
  13. import wow.doge.mygame.game.entities.PlayerCameraActor
  14. import wow.doge.mygame.game.entities.PlayerCameraEventListener
  15. import wow.doge.mygame.game.entities.PlayerMovementEventListener
  16. import wow.doge.mygame.implicits._
  17. import wow.doge.mygame.subsystems.events.EventBus
  18. import wow.doge.mygame.subsystems.events.EventsModule.GameEventBus
  19. import wow.doge.mygame.subsystems.events.PlayerEvent
  20. import wow.doge.mygame.subsystems.events.TickEvent
  21. import wow.doge.mygame.subsystems.events.TickEvent.RenderTick
  22. import wow.doge.mygame.subsystems.movement.ImMovementActor
  23. object PlayerActorSupervisor2 {
  24. sealed trait Command
  25. case object Tick extends Command
  26. sealed trait Movement extends Command
  27. final case class MoveLeft(pressed: Boolean) extends Movement
  28. final case class MoveUp(pressed: Boolean) extends Movement
  29. final case class MoveRight(pressed: Boolean) extends Movement
  30. final case class MoveDown(pressed: Boolean) extends Movement
  31. case object Jump extends Movement
  32. sealed trait Camera
  33. case object RotateLeft extends Camera
  34. case object RotateRight extends Camera
  35. case object RotateUp extends Camera
  36. case object RotateDown extends Camera
  37. class Props(
  38. val playerEventBus: GameEventBus[PlayerEvent],
  39. val tickEventBus: GameEventBus[TickEvent],
  40. val imMovementActorBehavior: Behavior[ImMovementActor.Command],
  41. val playerCameraActorBehavior: Behavior[PlayerCameraActor.Command]
  42. ) {
  43. def behavior =
  44. Behaviors.logMessages(
  45. LogOptions()
  46. .withLevel(Level.TRACE)
  47. .withLogger(
  48. Logger[PlayerActorSupervisor2].underlying
  49. ),
  50. Behaviors
  51. .setup[Command] { ctx =>
  52. ctx.log.infoP("Starting PlayerActor")
  53. // spawn children actors
  54. val movementActor =
  55. ctx.spawn(
  56. Behaviors
  57. .supervise(imMovementActorBehavior)
  58. .onFailure[Exception](
  59. SupervisorStrategy.restart.withLimit(2, 100.millis)
  60. ),
  61. "playerMovementActor",
  62. Dispatchers.jmeDispatcher
  63. )
  64. val playerCameraActor =
  65. ctx.spawn(
  66. playerCameraActorBehavior,
  67. "playerCameraActor",
  68. Dispatchers.jmeDispatcher
  69. )
  70. val playerCameraEl = ctx.spawn(
  71. PlayerCameraEventListener(playerCameraActor),
  72. "playerCameraActorEl"
  73. )
  74. val playerMovementEl = ctx.spawn(
  75. Behaviors
  76. .supervise(PlayerMovementEventListener(movementActor))
  77. .onFailure[Exception](
  78. SupervisorStrategy.restart.withLimit(2, 100.millis)
  79. ),
  80. "playerMovementEventHandler"
  81. )
  82. val renderTickEl = {
  83. val behavior: Behavior[RenderTick.type] =
  84. Behaviors.setup(ctx =>
  85. Behaviors
  86. .receiveMessage[RenderTick.type] {
  87. case RenderTick =>
  88. movementActor ! ImMovementActor.Tick
  89. // playerCameraActor ! PlayerCameraActor.Tick
  90. Behaviors.same
  91. }
  92. .receiveSignal {
  93. case (_, PostStop) =>
  94. ctx.log.infoP("stopped")
  95. Behaviors.same
  96. }
  97. )
  98. ctx.spawn(behavior, "playerMovementTickListener")
  99. }
  100. //init listeners
  101. playerEventBus ! EventBus.Subscribe(playerMovementEl)
  102. tickEventBus ! EventBus.Subscribe(renderTickEl)
  103. playerEventBus ! EventBus.Subscribe(playerCameraEl)
  104. new PlayerActorSupervisor2(
  105. ctx,
  106. this,
  107. Children(movementActor)
  108. ).receive
  109. }
  110. )
  111. }
  112. case class Children(
  113. movementActor: ActorRef[ImMovementActor.Command]
  114. )
  115. }
  116. class PlayerActorSupervisor2(
  117. ctx: ActorContext[PlayerActorSupervisor2.Command],
  118. props: PlayerActorSupervisor2.Props,
  119. children: PlayerActorSupervisor2.Children
  120. ) {
  121. import PlayerActorSupervisor2._
  122. def receive =
  123. Behaviors
  124. .receiveMessage[Command] {
  125. case m @ MoveDown(pressed) =>
  126. // children.movementActor ! m
  127. Behaviors.same
  128. case _ =>
  129. // children.movementActor ! ImMovementActor.MovedDown(true)
  130. Behaviors.same
  131. }
  132. .receiveSignal {
  133. case (_, PostStop) =>
  134. ctx.log.infoP("stopped")
  135. Behaviors.same
  136. }
  137. }