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.

253 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
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
4 years ago
4 years ago
4 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. 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. _ <- UIO(setupMovementKeys(inputManager))
  29. // _ <- UIO(setupAnalogMovementKeys)
  30. _ <- UIO(setupCameraKeys())
  31. _ <- toIO(
  32. me.Task.parSequence(
  33. Seq(
  34. playerMovementInputEventsGenerator(
  35. inputManager,
  36. playerEventBus
  37. ).completedL,
  38. // generateAnalogMovementEvents(
  39. // inputManager,
  40. // playerEventBus
  41. // ).completedL,
  42. // cameraMovementEventsGenerator(
  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 methodName(implicit enclosing: sourcecode.Enclosing) =
  122. enclosing.value.split(" ")(0).split("""\.""").last
  123. def playerMovementInputEventsGenerator(
  124. inputManager: InputManager,
  125. playerEventBus: GameEventBus[PlayerEvent]
  126. ) = {
  127. val name = methodName
  128. inputManager
  129. .enumObservableAction(PlayerMovementInput)
  130. // .dump("O")
  131. .doOnNext { action =>
  132. action.binding match {
  133. case PlayerMovementInput.WalkLeft =>
  134. me.Task(
  135. playerEventBus ! EventBus.Publish(
  136. PlayerMovementEvent.PlayerMovedLeft(pressed = action.value),
  137. name
  138. )
  139. )
  140. case PlayerMovementInput.WalkRight =>
  141. me.Task(
  142. playerEventBus ! EventBus.Publish(
  143. PlayerMovementEvent.PlayerMovedRight(pressed = action.value),
  144. name
  145. )
  146. )
  147. case PlayerMovementInput.WalkForward =>
  148. me.Task(
  149. playerEventBus ! EventBus.Publish(
  150. PlayerMovementEvent.PlayerMovedForward(pressed = action.value),
  151. name
  152. )
  153. )
  154. case PlayerMovementInput.WalkBackward =>
  155. me.Task(
  156. playerEventBus ! EventBus.Publish(
  157. PlayerMovementEvent.PlayerMovedBackward(pressed = action.value),
  158. name
  159. )
  160. )
  161. case PlayerMovementInput.Jump =>
  162. if (action.value)
  163. me.Task(
  164. playerEventBus ! EventBus.Publish(
  165. PlayerMovementEvent.PlayerJumped,
  166. name
  167. )
  168. )
  169. else me.Task.unit
  170. }
  171. }
  172. }
  173. def generateAnalogMovementEvents(
  174. inputManager: InputManager,
  175. playerEventBus: GameEventBus[PlayerEvent]
  176. ) =
  177. // val name = "analogMovementEventsGenerator"
  178. inputManager
  179. .enumAnalogObservable(PlayerAnalogMovementInput)
  180. .sample(1.millis)
  181. // .doOnNext(analogEvent =>
  182. // analogEvent.binding match {
  183. // case PlayerAnalogMovementInput.TurnRight =>
  184. // me.Task(
  185. // playerMovementEventBus ! EventBus.Publish(
  186. // PlayerMovementEvent.PlayerTurnedRight,
  187. // name
  188. // )
  189. // )
  190. // case PlayerAnalogMovementInput.TurnLeft =>
  191. // me.Task(
  192. // playerMovementEventBus ! EventBus.Publish(
  193. // PlayerMovementEvent.PlayerTurnedLeft,
  194. // name
  195. // )
  196. // )
  197. // }
  198. // )
  199. def cameraMovementEventsGenerator(
  200. inputManager: InputManager,
  201. playerEventBus: ActorRef[EventBus.Command[PlayerEvent]]
  202. ) = {
  203. val name = methodName
  204. inputManager
  205. .enumAnalogObservable(PlayerCameraInput)
  206. .sample(1.millis)
  207. .doOnNext(analogEvent =>
  208. analogEvent.binding match {
  209. case PlayerCameraInput.CameraRotateLeft =>
  210. me.Task(
  211. playerEventBus ! EventBus.Publish(
  212. PlayerCameraEvent.CameraLeft,
  213. name
  214. )
  215. )
  216. case PlayerCameraInput.CameraRotateRight =>
  217. me.Task(
  218. playerEventBus ! EventBus.Publish(
  219. PlayerCameraEvent.CameraRight,
  220. name
  221. )
  222. )
  223. case PlayerCameraInput.CameraRotateUp =>
  224. me.Task(
  225. playerEventBus ! EventBus.Publish(
  226. PlayerCameraEvent.CameraMovedUp,
  227. name
  228. )
  229. )
  230. case PlayerCameraInput.CameraRotateDown =>
  231. me.Task(
  232. playerEventBus ! EventBus.Publish(
  233. PlayerCameraEvent.CameraMovedDown,
  234. name
  235. )
  236. )
  237. }
  238. )
  239. }
  240. }