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.

202 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
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. PlayerAnalogInput.TurnRight.entryName,
  64. new KeyTrigger(KeyInput.KEY_RIGHT),
  65. new MouseAxisTrigger(MouseInput.AXIS_X, true)
  66. )
  67. .withMapping(
  68. PlayerAnalogInput.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. .setCursorVisible(false)
  83. def generateMovementInputEvents(
  84. inputManager: InputManager,
  85. playerMovementEventBus: ActorRef[
  86. EventBus.Command[PlayerMovementEvent]
  87. ]
  88. ) = {
  89. val name = "playerMovementInputEventsGenerator"
  90. inputManager
  91. .enumObservableAction(PlayerMovementInput)
  92. // .dump("O")
  93. .doOnNext { action =>
  94. action.binding match {
  95. case PlayerMovementInput.WalkLeft =>
  96. toTask(
  97. playerMovementEventBus !! EventBus.Publish(
  98. PlayerMovementEvent.PlayerMovedLeft(pressed = action.value),
  99. name
  100. )
  101. )
  102. case PlayerMovementInput.WalkRight =>
  103. toTask(
  104. playerMovementEventBus !! EventBus.Publish(
  105. PlayerMovementEvent.PlayerMovedRight(pressed = action.value),
  106. name
  107. )
  108. )
  109. case PlayerMovementInput.WalkForward =>
  110. toTask(
  111. playerMovementEventBus !! EventBus.Publish(
  112. PlayerMovementEvent.PlayerMovedForward(pressed = action.value),
  113. name
  114. )
  115. )
  116. case PlayerMovementInput.WalkBackward =>
  117. toTask(
  118. playerMovementEventBus !! EventBus.Publish(
  119. PlayerMovementEvent.PlayerMovedBackward(pressed = action.value),
  120. name
  121. )
  122. )
  123. case PlayerMovementInput.Jump =>
  124. if (action.value) {
  125. toTask(
  126. playerMovementEventBus !! EventBus.Publish(
  127. PlayerMovementEvent.PlayerJumped,
  128. name
  129. )
  130. )
  131. } else monix.eval.Task.unit
  132. }
  133. }
  134. }
  135. def generateRotateEvents(
  136. inputManager: InputManager,
  137. playerMovementEventBus: ActorRef[
  138. EventBus.Command[PlayerMovementEvent]
  139. ]
  140. ) = {
  141. val name = "rotateMovementEventsGenerator"
  142. inputManager
  143. .enumAnalogObservable(PlayerAnalogInput)
  144. .sample(1.millis)
  145. // .map(e => e)
  146. .doOnNext(analogEvent =>
  147. analogEvent.binding match {
  148. case PlayerAnalogInput.TurnRight =>
  149. toTask(
  150. playerMovementEventBus !! EventBus.Publish(
  151. PlayerMovementEvent.PlayerRotatedRight,
  152. name
  153. )
  154. )
  155. case PlayerAnalogInput.TurnLeft =>
  156. toTask(
  157. playerMovementEventBus !! EventBus.Publish(
  158. PlayerMovementEvent.PlayerRotatedLeft,
  159. name
  160. )
  161. )
  162. }
  163. )
  164. }
  165. def generateCameraEvents(
  166. inputManager: InputManager,
  167. playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]]
  168. ) = {
  169. val name = "cameraMovementEventsGenerator"
  170. inputManager
  171. .analogObservable("CAMERA_UP", "CAMERA_DOWN")
  172. .sample(1.millis)
  173. .mapEval(analogEvent =>
  174. analogEvent.binding.name match {
  175. case "CAMERA_UP" =>
  176. toTask(
  177. playerCameraEventBus !! EventBus.Publish(
  178. PlayerCameraEvent.CameraMovedUp,
  179. name
  180. )
  181. )
  182. case "CAMERA_DOWN" =>
  183. toTask(
  184. playerCameraEventBus !! EventBus.Publish(
  185. PlayerCameraEvent.CameraMovedDown,
  186. name
  187. )
  188. )
  189. case _ => monix.eval.Task.unit
  190. }
  191. )
  192. }
  193. }