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