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.

200 lines
6.1 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
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
4 years ago
4 years ago
4 years ago
  1. package wow.doge.mygame.game.subsystems.input
  2. import scala.concurrent.duration._
  3. import akka.actor.typed.ActorRef
  4. import com.jme3.input.InputManager
  5. import com.jme3.input.KeyInput
  6. import com.jme3.input.MouseInput
  7. import com.jme3.input.controls.KeyTrigger
  8. import com.jme3.input.controls.MouseAxisTrigger
  9. import monix.bio.UIO
  10. import wow.doge.mygame.implicits._
  11. import wow.doge.mygame.subsystems.events.EventBus
  12. import wow.doge.mygame.subsystems.events.EventsModule.GameEventBus
  13. import wow.doge.mygame.subsystems.events.PlayerCameraEvent
  14. import wow.doge.mygame.subsystems.events.PlayerMovementEvent
  15. import wow.doge.mygame.utils.IOUtils._
  16. object GameInputHandler {
  17. final case class Props(
  18. inputManager: InputManager,
  19. playerMovementEventBus: GameEventBus[PlayerMovementEvent],
  20. playerCameraEventBus: GameEventBus[PlayerCameraEvent]
  21. // tickEventBus: GameEventBus[TickEvent]
  22. ) {
  23. def begin =
  24. for {
  25. _ <- UIO(setupMovementKeys(inputManager))
  26. _ <- UIO(setupKeys(inputManager))
  27. _ <- toIO(
  28. generateMovementInputEvents(
  29. inputManager,
  30. playerMovementEventBus
  31. ).completedL.startAndForget
  32. )
  33. _ <- toIO(
  34. generateRotateEvents(
  35. inputManager,
  36. playerMovementEventBus
  37. ).completedL.startAndForget
  38. )
  39. _ <- toIO(
  40. generateCameraEvents(
  41. inputManager,
  42. playerCameraEventBus
  43. ).completedL.startAndForget
  44. )
  45. } yield ()
  46. }
  47. def setupMovementKeys(inputManager: InputManager) =
  48. inputManager.withEnumMappings(PlayerMovementInput) {
  49. case PlayerMovementInput.WalkRight =>
  50. Seq(new KeyTrigger(KeyInput.KEY_D))
  51. case PlayerMovementInput.WalkLeft =>
  52. Seq(new KeyTrigger(KeyInput.KEY_A))
  53. case PlayerMovementInput.WalkForward =>
  54. Seq(new KeyTrigger(KeyInput.KEY_W))
  55. case PlayerMovementInput.WalkBackward =>
  56. Seq(new KeyTrigger(KeyInput.KEY_S))
  57. case PlayerMovementInput.Jump =>
  58. Seq(new KeyTrigger(KeyInput.KEY_SPACE))
  59. }
  60. def setupKeys(inputManager: InputManager) =
  61. inputManager
  62. .withMapping(
  63. PlayerAnalogMovementInput.TurnRight.entryName,
  64. new KeyTrigger(KeyInput.KEY_RIGHT),
  65. new MouseAxisTrigger(MouseInput.AXIS_X, true)
  66. )
  67. .withMapping(
  68. PlayerAnalogMovementInput.TurnLeft.entryName,
  69. new KeyTrigger(KeyInput.KEY_LEFT),
  70. new MouseAxisTrigger(MouseInput.AXIS_X, false)
  71. )
  72. .withMapping(
  73. "CAMERA_UP",
  74. // new KeyTrigger(KeyInput.KEY_LEFT),
  75. new MouseAxisTrigger(MouseInput.AXIS_Y, false)
  76. )
  77. .withMapping(
  78. "CAMERA_DOWN",
  79. // new KeyTrigger(KeyInput.KEY_LEFT),
  80. new MouseAxisTrigger(MouseInput.AXIS_Y, true)
  81. )
  82. def generateMovementInputEvents(
  83. inputManager: InputManager,
  84. playerMovementEventBus: ActorRef[
  85. EventBus.Command[PlayerMovementEvent]
  86. ]
  87. ) = {
  88. val name = "playerMovementInputEventsGenerator"
  89. inputManager
  90. .enumObservableAction(PlayerMovementInput)
  91. // .dump("O")
  92. .doOnNext { action =>
  93. action.binding match {
  94. case PlayerMovementInput.WalkLeft =>
  95. toTask(
  96. playerMovementEventBus !! EventBus.Publish(
  97. PlayerMovementEvent.PlayerMovedLeft(pressed = action.value),
  98. name
  99. )
  100. )
  101. case PlayerMovementInput.WalkRight =>
  102. toTask(
  103. playerMovementEventBus !! EventBus.Publish(
  104. PlayerMovementEvent.PlayerMovedRight(pressed = action.value),
  105. name
  106. )
  107. )
  108. case PlayerMovementInput.WalkForward =>
  109. toTask(
  110. playerMovementEventBus !! EventBus.Publish(
  111. PlayerMovementEvent.PlayerMovedForward(pressed = action.value),
  112. name
  113. )
  114. )
  115. case PlayerMovementInput.WalkBackward =>
  116. toTask(
  117. playerMovementEventBus !! EventBus.Publish(
  118. PlayerMovementEvent.PlayerMovedBackward(pressed = action.value),
  119. name
  120. )
  121. )
  122. case PlayerMovementInput.Jump =>
  123. if (action.value) {
  124. toTask(
  125. playerMovementEventBus !! EventBus.Publish(
  126. PlayerMovementEvent.PlayerJumped,
  127. name
  128. )
  129. )
  130. } else monix.eval.Task.unit
  131. }
  132. }
  133. }
  134. def generateRotateEvents(
  135. inputManager: InputManager,
  136. playerMovementEventBus: ActorRef[
  137. EventBus.Command[PlayerMovementEvent]
  138. ]
  139. ) = {
  140. val name = "rotateMovementEventsGenerator"
  141. inputManager
  142. .enumAnalogObservable(PlayerAnalogMovementInput)
  143. .sample(1.millis)
  144. .doOnNext(analogEvent =>
  145. analogEvent.binding match {
  146. case PlayerAnalogMovementInput.TurnRight =>
  147. toTask(
  148. playerMovementEventBus !! EventBus.Publish(
  149. PlayerMovementEvent.PlayerRotatedRight,
  150. name
  151. )
  152. )
  153. case PlayerAnalogMovementInput.TurnLeft =>
  154. toTask(
  155. playerMovementEventBus !! EventBus.Publish(
  156. PlayerMovementEvent.PlayerRotatedLeft,
  157. name
  158. )
  159. )
  160. }
  161. )
  162. }
  163. def generateCameraEvents(
  164. inputManager: InputManager,
  165. playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]]
  166. ) = {
  167. val name = "cameraMovementEventsGenerator"
  168. inputManager
  169. .analogObservable("CAMERA_UP", "CAMERA_DOWN")
  170. .sample(1.millis)
  171. .doOnNext(analogEvent =>
  172. analogEvent.binding.name match {
  173. case "CAMERA_UP" =>
  174. toTask(
  175. playerCameraEventBus !! EventBus.Publish(
  176. PlayerCameraEvent.CameraMovedUp,
  177. name
  178. )
  179. )
  180. case "CAMERA_DOWN" =>
  181. toTask(
  182. playerCameraEventBus !! EventBus.Publish(
  183. PlayerCameraEvent.CameraMovedDown,
  184. name
  185. )
  186. )
  187. case _ => monix.eval.Task.unit
  188. }
  189. )
  190. }
  191. }