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.

247 lines
7.2 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
  1. package wow.doge.mygame.game.subsystems.input
  2. import com.jme3.input.InputManager
  3. import wow.doge.mygame.implicits._
  4. import akka.actor.typed.ActorRef
  5. import wow.doge.mygame.events.EventBus
  6. import com.jme3.input.KeyInput
  7. import com.jme3.input.controls.KeyTrigger
  8. import monix.bio.UIO
  9. import wow.doge.mygame.utils.IOUtils._
  10. import wow.doge.mygame.subsystems.events.EntityMovementEvent.PlayerMovementEvent
  11. import scala.concurrent.duration._
  12. import com.jme3.input.controls.MouseAxisTrigger
  13. import com.jme3.input.MouseInput
  14. import wow.doge.mygame.subsystems.events.PlayerCameraEvent
  15. // class GameInputHandler(
  16. // inputManager: InputManager
  17. // // inputEventBus: InputEventBus
  18. // ) {}
  19. object GameInputHandler {
  20. final case class Props(
  21. inputManager: InputManager,
  22. playerMovementEventBus: ActorRef[
  23. EventBus.Command[PlayerMovementEvent]
  24. ],
  25. playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]]
  26. ) {
  27. def begin =
  28. for {
  29. _ <- UIO(setupKeys(inputManager))
  30. _ <- toIO(
  31. generateMovementInputEvents(
  32. inputManager,
  33. playerMovementEventBus
  34. ).completedL.startAndForget
  35. )
  36. _ <- toIO(
  37. generateRotateEvents(
  38. inputManager,
  39. playerMovementEventBus
  40. ).completedL.startAndForget
  41. )
  42. _ <- toIO(
  43. generateCameraEvents(
  44. inputManager,
  45. playerCameraEventBus
  46. ).completedL.startAndForget
  47. )
  48. _ <- toIO(
  49. myTest(
  50. inputManager
  51. ).completedL.startAndForget
  52. )
  53. } yield ()
  54. }
  55. def setupKeys(inputManager: InputManager) =
  56. inputManager
  57. .withMapping(
  58. PlayerMovementInput.WalkLeft.entryName,
  59. new KeyTrigger(KeyInput.KEY_A)
  60. // new KeyTrigger(KeyInput.KEY_LEFT)
  61. )
  62. .withMapping(
  63. PlayerMovementInput.WalkRight.entryName,
  64. new KeyTrigger(KeyInput.KEY_D)
  65. // new KeyTrigger(KeyInput.KEY_RIGHT)
  66. )
  67. .withMapping(
  68. PlayerMovementInput.WalkForward.entryName,
  69. new KeyTrigger(KeyInput.KEY_W)
  70. // new KeyTrigger(KeyInput.KEY_UP)
  71. )
  72. .withMapping(
  73. PlayerMovementInput.WalkBackward.entryName,
  74. new KeyTrigger(KeyInput.KEY_S)
  75. // new KeyTrigger(KeyInput.KEY_DOWN)
  76. )
  77. .withMapping(
  78. "Jump",
  79. new KeyTrigger(KeyInput.KEY_SPACE)
  80. )
  81. .withMapping(
  82. PlayerAnalogInput.TurnRight.entryName,
  83. new KeyTrigger(KeyInput.KEY_RIGHT),
  84. new MouseAxisTrigger(MouseInput.AXIS_X, true)
  85. )
  86. .withMapping(
  87. PlayerAnalogInput.TurnLeft.entryName,
  88. new KeyTrigger(KeyInput.KEY_LEFT),
  89. new MouseAxisTrigger(MouseInput.AXIS_X, false)
  90. )
  91. .withMapping(
  92. "CAMERA_UP",
  93. // new KeyTrigger(KeyInput.KEY_LEFT),
  94. new MouseAxisTrigger(MouseInput.AXIS_Y, false)
  95. )
  96. .withMapping(
  97. "CAMERA_DOWN",
  98. // new KeyTrigger(KeyInput.KEY_LEFT),
  99. new MouseAxisTrigger(MouseInput.AXIS_Y, true)
  100. )
  101. .setCursorVisible(false)
  102. def generateMovementInputEvents(
  103. inputManager: InputManager,
  104. playerMovementEventBus: ActorRef[
  105. EventBus.Command[PlayerMovementEvent]
  106. ]
  107. ) = {
  108. val name = "playerMovementInputEventsGenerator"
  109. inputManager
  110. .enumObservableAction(PlayerMovementInput)
  111. // .dump("O")
  112. .doOnNext { action =>
  113. action.binding match {
  114. case PlayerMovementInput.WalkLeft =>
  115. toTask(
  116. playerMovementEventBus !! EventBus.Publish(
  117. PlayerMovementEvent.PlayerMovedLeft(pressed = action.value),
  118. name
  119. )
  120. )
  121. case PlayerMovementInput.WalkRight =>
  122. toTask(
  123. playerMovementEventBus !! EventBus.Publish(
  124. PlayerMovementEvent.PlayerMovedRight(pressed = action.value),
  125. name
  126. )
  127. )
  128. case PlayerMovementInput.WalkForward =>
  129. toTask(
  130. playerMovementEventBus !! EventBus.Publish(
  131. PlayerMovementEvent.PlayerMovedForward(pressed = action.value),
  132. name
  133. )
  134. )
  135. case PlayerMovementInput.WalkBackward =>
  136. toTask(
  137. playerMovementEventBus !! EventBus.Publish(
  138. PlayerMovementEvent.PlayerMovedBackward(pressed = action.value),
  139. name
  140. )
  141. )
  142. // case "Jump" if action.value =>
  143. // toTask(
  144. // playerMovementEventBus !! EventBus.Publish(
  145. // PlayerMovementEvent.PlayerJumped,
  146. // name
  147. // )
  148. // )
  149. // case _ => monix.eval.Task.unit
  150. }
  151. }
  152. }
  153. def myTest(inputManager: InputManager) = {
  154. inputManager
  155. .enumObservableAction(PlayerMovementEnum)
  156. .sample(1.millis)
  157. .mapEval(action =>
  158. action.binding match {
  159. case PlayerMovementEnum.MOVE_RIGHT =>
  160. monix.eval.Task(println("move right")) >> monix.eval.Task.unit
  161. case PlayerMovementEnum.MOVE_LEFT =>
  162. monix.eval.Task(println("move left"))
  163. }
  164. )
  165. }
  166. def generateRotateEvents(
  167. inputManager: InputManager,
  168. playerMovementEventBus: ActorRef[
  169. EventBus.Command[PlayerMovementEvent]
  170. ]
  171. ) = {
  172. val name = "rotateMovementEventsGenerator"
  173. inputManager
  174. .enumAnalogObservable(PlayerAnalogInput)
  175. .sample(1.millis)
  176. .map(e => e)
  177. .doOnNext(analogEvent =>
  178. analogEvent.binding match {
  179. case PlayerAnalogInput.TurnRight =>
  180. toTask(
  181. playerMovementEventBus !! EventBus.Publish(
  182. PlayerMovementEvent.PlayerRotatedRight,
  183. name
  184. )
  185. )
  186. case PlayerAnalogInput.TurnLeft =>
  187. toTask(
  188. playerMovementEventBus !! EventBus.Publish(
  189. PlayerMovementEvent.PlayerRotatedLeft,
  190. name
  191. )
  192. )
  193. }
  194. )
  195. }
  196. def generateCameraEvents(
  197. inputManager: InputManager,
  198. playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]]
  199. ) = {
  200. val name = "cameraMovementEventsGenerator"
  201. inputManager
  202. .analogObservable("CAMERA_UP", "CAMERA_DOWN")
  203. .sample(1.millis)
  204. .mapEval(analogEvent =>
  205. analogEvent.binding.name match {
  206. case "CAMERA_UP" =>
  207. toTask(
  208. playerCameraEventBus !! EventBus.Publish(
  209. PlayerCameraEvent.CameraMovedUp,
  210. name
  211. )
  212. )
  213. case "CAMERA_DOWN" =>
  214. toTask(
  215. playerCameraEventBus !! EventBus.Publish(
  216. PlayerCameraEvent.CameraMovedDown,
  217. name
  218. )
  219. )
  220. case _ => monix.eval.Task.unit
  221. }
  222. )
  223. }
  224. // def bindMappings(inputManager: InputManager, mappings: ActionMapping*) = {
  225. // inputManager
  226. // .observableAction(mappings.map(_.name): _*)
  227. // .doOnNext(action =>
  228. // mappings.map(m =>
  229. // if (action.binding.name == m.name) toTask(m.cb(action))
  230. // else monix.eval.Task.unit
  231. // )
  232. // )
  233. // }
  234. }
  235. // case class ActionMapping(name: String, cb: ActionEvent => Task[Unit])