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.

251 lines
7.9 KiB

4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 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 cats.effect.concurrent.Ref
  5. import com.jme3.input.InputManager
  6. import com.jme3.input.KeyInput
  7. import com.jme3.input.MouseInput
  8. import com.jme3.input.controls.KeyTrigger
  9. import com.jme3.input.controls.MouseAxisTrigger
  10. import monix.bio.Task
  11. import monix.{eval => me}
  12. import wow.doge.mygame.implicits._
  13. import wow.doge.mygame.subsystems.events.EventBus
  14. import wow.doge.mygame.subsystems.events.EventsModule.GameEventBus
  15. import wow.doge.mygame.subsystems.events.PlayerCameraEvent
  16. import wow.doge.mygame.subsystems.events.PlayerEvent
  17. import wow.doge.mygame.subsystems.events.PlayerMovementEvent
  18. import wow.doge.mygame.utils.IOUtils._
  19. object GameInputHandler {
  20. class Props(
  21. inputManager: InputManager,
  22. playerEventBus: GameEventBus[PlayerEvent]
  23. // playerCameraEventBus: GameEventBus[PlayerCameraEvent]
  24. // tickEventBus: GameEventBus[TickEvent]
  25. ) {
  26. def begin =
  27. for {
  28. _ <- Task(setupMovementKeys(inputManager))
  29. // _ <- UIO(setupAnalogMovementKeys)
  30. _ <- Task(setupCameraKeys())
  31. _ <- toIO(
  32. me.Task.parSequence(
  33. Seq(
  34. generateMovementInputEvents(
  35. inputManager,
  36. playerEventBus
  37. ).completedL,
  38. // generateAnalogMovementEvents(
  39. // inputManager,
  40. // playerEventBus
  41. // ).completedL,
  42. generateCameraEvents(
  43. inputManager,
  44. playerEventBus
  45. ).completedL,
  46. Ref
  47. .of[me.Task, Boolean](false)
  48. .flatMap(value => cursorToggle(value))
  49. )
  50. )
  51. ).startAndForget
  52. } yield ()
  53. def setupMovementKeys(inputManager: InputManager) =
  54. inputManager.withEnumMappings(PlayerMovementInput) {
  55. case PlayerMovementInput.WalkRight =>
  56. new KeyTrigger(KeyInput.KEY_D) :: Nil
  57. case PlayerMovementInput.WalkLeft =>
  58. new KeyTrigger(KeyInput.KEY_A) :: Nil
  59. case PlayerMovementInput.WalkForward =>
  60. new KeyTrigger(KeyInput.KEY_W) :: Nil
  61. case PlayerMovementInput.WalkBackward =>
  62. new KeyTrigger(KeyInput.KEY_S) :: Nil
  63. case PlayerMovementInput.Jump =>
  64. new KeyTrigger(KeyInput.KEY_SPACE) :: Nil
  65. }
  66. def setupAnalogMovementKeys() =
  67. inputManager.withEnumMappings(PlayerAnalogMovementInput) {
  68. case PlayerAnalogMovementInput.TurnRight =>
  69. Seq(new KeyTrigger(KeyInput.KEY_D))
  70. case PlayerAnalogMovementInput.TurnLeft =>
  71. Seq(new KeyTrigger(KeyInput.KEY_A))
  72. }
  73. def setupCameraKeys() =
  74. inputManager.withEnumMappings(PlayerCameraInput) {
  75. case PlayerCameraInput.CameraRotateLeft =>
  76. Seq(
  77. new KeyTrigger(KeyInput.KEY_LEFT),
  78. new MouseAxisTrigger(MouseInput.AXIS_X, false)
  79. )
  80. case PlayerCameraInput.CameraRotateRight =>
  81. Seq(
  82. new KeyTrigger(KeyInput.KEY_RIGHT),
  83. new MouseAxisTrigger(MouseInput.AXIS_X, true)
  84. )
  85. case PlayerCameraInput.CameraRotateUp =>
  86. Seq(
  87. new KeyTrigger(KeyInput.KEY_UP),
  88. new MouseAxisTrigger(MouseInput.AXIS_Y, false)
  89. )
  90. case PlayerCameraInput.CameraRotateDown =>
  91. Seq(
  92. new KeyTrigger(KeyInput.KEY_DOWN),
  93. new MouseAxisTrigger(MouseInput.AXIS_Y, true)
  94. )
  95. }
  96. def cursorToggle(toggleRef: Ref[me.Task, Boolean]) =
  97. for {
  98. _ <- me.Task(
  99. inputManager.withMapping(
  100. MiscInput.ToggleCursor,
  101. new KeyTrigger(KeyInput.KEY_Z)
  102. )
  103. )
  104. _ <-
  105. inputManager
  106. .enumEntryObservableAction(MiscInput.ToggleCursor)
  107. .doOnNext(action =>
  108. action.binding match {
  109. case MiscInput.ToggleCursor =>
  110. if (action.value) for {
  111. value <- toggleRef.getAndUpdate(!_)
  112. _ <- me.Task(inputManager.setCursorVisible(value))
  113. } yield ()
  114. else me.Task.unit
  115. // case _ => me.Task.unit
  116. }
  117. )
  118. .completedL
  119. } yield ()
  120. }
  121. def generateMovementInputEvents(
  122. inputManager: InputManager,
  123. playerEventBus: GameEventBus[PlayerEvent]
  124. ) = {
  125. val name = "playerMovementInputEventsGenerator"
  126. inputManager
  127. .enumObservableAction(PlayerMovementInput)
  128. // .dump("O")
  129. .doOnNext { action =>
  130. action.binding match {
  131. case PlayerMovementInput.WalkLeft =>
  132. me.Task(
  133. playerEventBus ! EventBus.Publish(
  134. PlayerMovementEvent.PlayerMovedLeft(pressed = action.value),
  135. name
  136. )
  137. )
  138. case PlayerMovementInput.WalkRight =>
  139. me.Task(
  140. playerEventBus ! EventBus.Publish(
  141. PlayerMovementEvent.PlayerMovedRight(pressed = action.value),
  142. name
  143. )
  144. )
  145. case PlayerMovementInput.WalkForward =>
  146. me.Task(
  147. playerEventBus ! EventBus.Publish(
  148. PlayerMovementEvent.PlayerMovedForward(pressed = action.value),
  149. name
  150. )
  151. )
  152. case PlayerMovementInput.WalkBackward =>
  153. me.Task(
  154. playerEventBus ! EventBus.Publish(
  155. PlayerMovementEvent.PlayerMovedBackward(pressed = action.value),
  156. name
  157. )
  158. )
  159. case PlayerMovementInput.Jump =>
  160. if (action.value) {
  161. me.Task(
  162. playerEventBus ! EventBus.Publish(
  163. PlayerMovementEvent.PlayerJumped,
  164. name
  165. )
  166. )
  167. } else me.Task.unit
  168. }
  169. }
  170. }
  171. def generateAnalogMovementEvents(
  172. inputManager: InputManager,
  173. playerEventBus: GameEventBus[PlayerEvent]
  174. ) = {
  175. // val name = "analogMovementEventsGenerator"
  176. inputManager
  177. .enumAnalogObservable(PlayerAnalogMovementInput)
  178. .sample(1.millis)
  179. // .doOnNext(analogEvent =>
  180. // analogEvent.binding match {
  181. // case PlayerAnalogMovementInput.TurnRight =>
  182. // me.Task(
  183. // playerMovementEventBus ! EventBus.Publish(
  184. // PlayerMovementEvent.PlayerTurnedRight,
  185. // name
  186. // )
  187. // )
  188. // case PlayerAnalogMovementInput.TurnLeft =>
  189. // me.Task(
  190. // playerMovementEventBus ! EventBus.Publish(
  191. // PlayerMovementEvent.PlayerTurnedLeft,
  192. // name
  193. // )
  194. // )
  195. // }
  196. // )
  197. }
  198. def generateCameraEvents(
  199. inputManager: InputManager,
  200. playerEventBus: ActorRef[EventBus.Command[PlayerEvent]]
  201. ) = {
  202. val name = "cameraMovementEventsGenerator"
  203. inputManager
  204. .enumAnalogObservable(PlayerCameraInput)
  205. .sample(1.millis)
  206. .doOnNext(analogEvent =>
  207. analogEvent.binding match {
  208. case PlayerCameraInput.CameraRotateLeft =>
  209. me.Task(
  210. playerEventBus ! EventBus.Publish(
  211. PlayerCameraEvent.CameraLeft,
  212. name
  213. )
  214. )
  215. case PlayerCameraInput.CameraRotateRight =>
  216. me.Task(
  217. playerEventBus ! EventBus.Publish(
  218. PlayerCameraEvent.CameraRight,
  219. name
  220. )
  221. )
  222. case PlayerCameraInput.CameraRotateUp =>
  223. me.Task(
  224. playerEventBus ! EventBus.Publish(
  225. PlayerCameraEvent.CameraMovedUp,
  226. name
  227. )
  228. )
  229. case PlayerCameraInput.CameraRotateDown =>
  230. me.Task(
  231. playerEventBus ! EventBus.Publish(
  232. PlayerCameraEvent.CameraMovedDown,
  233. name
  234. )
  235. )
  236. }
  237. )
  238. }
  239. }