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.

226 lines
6.9 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
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.events.EventBus
  11. import wow.doge.mygame.implicits._
  12. import wow.doge.mygame.subsystems.events.EntityMovementEvent.PlayerMovementEvent
  13. import wow.doge.mygame.subsystems.events.PlayerCameraEvent
  14. import wow.doge.mygame.utils.IOUtils._
  15. object GameInputHandler {
  16. final case class Props(
  17. inputManager: InputManager,
  18. playerMovementEventBus: ActorRef[
  19. EventBus.Command[PlayerMovementEvent]
  20. ],
  21. playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]]
  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. // PlayerMovementInput.WalkLeft.entryName,
  64. // new KeyTrigger(KeyInput.KEY_A)
  65. // // new KeyTrigger(KeyInput.KEY_LEFT)
  66. // )
  67. // .withMapping(
  68. // PlayerMovementInput.WalkRight.entryName,
  69. // new KeyTrigger(KeyInput.KEY_D)
  70. // // new KeyTrigger(KeyInput.KEY_RIGHT)
  71. // )
  72. // .withMapping(
  73. // PlayerMovementInput.WalkForward.entryName,
  74. // new KeyTrigger(KeyInput.KEY_W)
  75. // // new KeyTrigger(KeyInput.KEY_UP)
  76. // )
  77. // .withMapping(
  78. // PlayerMovementInput.WalkBackward.entryName,
  79. // new KeyTrigger(KeyInput.KEY_S)
  80. // // new KeyTrigger(KeyInput.KEY_DOWN)
  81. // )
  82. // .withMapping(
  83. // PlayerMovementInput.Jump.entryName,
  84. // new KeyTrigger(KeyInput.KEY_SPACE)
  85. // )
  86. .withMapping(
  87. PlayerAnalogInput.TurnRight.entryName,
  88. new KeyTrigger(KeyInput.KEY_RIGHT),
  89. new MouseAxisTrigger(MouseInput.AXIS_X, true)
  90. )
  91. .withMapping(
  92. PlayerAnalogInput.TurnLeft.entryName,
  93. new KeyTrigger(KeyInput.KEY_LEFT),
  94. new MouseAxisTrigger(MouseInput.AXIS_X, false)
  95. )
  96. .withMapping(
  97. "CAMERA_UP",
  98. // new KeyTrigger(KeyInput.KEY_LEFT),
  99. new MouseAxisTrigger(MouseInput.AXIS_Y, false)
  100. )
  101. .withMapping(
  102. "CAMERA_DOWN",
  103. // new KeyTrigger(KeyInput.KEY_LEFT),
  104. new MouseAxisTrigger(MouseInput.AXIS_Y, true)
  105. )
  106. .setCursorVisible(false)
  107. def generateMovementInputEvents(
  108. inputManager: InputManager,
  109. playerMovementEventBus: ActorRef[
  110. EventBus.Command[PlayerMovementEvent]
  111. ]
  112. ) = {
  113. val name = "playerMovementInputEventsGenerator"
  114. inputManager
  115. .enumObservableAction(PlayerMovementInput)
  116. // .dump("O")
  117. .doOnNext { action =>
  118. action.binding match {
  119. case PlayerMovementInput.WalkLeft =>
  120. toTask(
  121. playerMovementEventBus !! EventBus.Publish(
  122. PlayerMovementEvent.PlayerMovedLeft(pressed = action.value),
  123. name
  124. )
  125. )
  126. case PlayerMovementInput.WalkRight =>
  127. toTask(
  128. playerMovementEventBus !! EventBus.Publish(
  129. PlayerMovementEvent.PlayerMovedRight(pressed = action.value),
  130. name
  131. )
  132. )
  133. case PlayerMovementInput.WalkForward =>
  134. toTask(
  135. playerMovementEventBus !! EventBus.Publish(
  136. PlayerMovementEvent.PlayerMovedForward(pressed = action.value),
  137. name
  138. )
  139. )
  140. case PlayerMovementInput.WalkBackward =>
  141. toTask(
  142. playerMovementEventBus !! EventBus.Publish(
  143. PlayerMovementEvent.PlayerMovedBackward(pressed = action.value),
  144. name
  145. )
  146. )
  147. case PlayerMovementInput.Jump =>
  148. if (action.value) {
  149. toTask(
  150. playerMovementEventBus !! EventBus.Publish(
  151. PlayerMovementEvent.PlayerJumped,
  152. name
  153. )
  154. )
  155. } else monix.eval.Task.unit
  156. }
  157. }
  158. }
  159. def generateRotateEvents(
  160. inputManager: InputManager,
  161. playerMovementEventBus: ActorRef[
  162. EventBus.Command[PlayerMovementEvent]
  163. ]
  164. ) = {
  165. val name = "rotateMovementEventsGenerator"
  166. inputManager
  167. .enumAnalogObservable(PlayerAnalogInput)
  168. .sample(1.millis)
  169. // .map(e => e)
  170. .doOnNext(analogEvent =>
  171. analogEvent.binding match {
  172. case PlayerAnalogInput.TurnRight =>
  173. toTask(
  174. playerMovementEventBus !! EventBus.Publish(
  175. PlayerMovementEvent.PlayerRotatedRight,
  176. name
  177. )
  178. )
  179. case PlayerAnalogInput.TurnLeft =>
  180. toTask(
  181. playerMovementEventBus !! EventBus.Publish(
  182. PlayerMovementEvent.PlayerRotatedLeft,
  183. name
  184. )
  185. )
  186. }
  187. )
  188. }
  189. def generateCameraEvents(
  190. inputManager: InputManager,
  191. playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]]
  192. ) = {
  193. val name = "cameraMovementEventsGenerator"
  194. inputManager
  195. .analogObservable("CAMERA_UP", "CAMERA_DOWN")
  196. .sample(1.millis)
  197. .mapEval(analogEvent =>
  198. analogEvent.binding.name match {
  199. case "CAMERA_UP" =>
  200. toTask(
  201. playerCameraEventBus !! EventBus.Publish(
  202. PlayerCameraEvent.CameraMovedUp,
  203. name
  204. )
  205. )
  206. case "CAMERA_DOWN" =>
  207. toTask(
  208. playerCameraEventBus !! EventBus.Publish(
  209. PlayerCameraEvent.CameraMovedDown,
  210. name
  211. )
  212. )
  213. case _ => monix.eval.Task.unit
  214. }
  215. )
  216. }
  217. }