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
253 lines
7.9 KiB
package wow.doge.mygame.game.subsystems.input
|
|
|
|
import scala.concurrent.duration._
|
|
|
|
import akka.actor.typed.ActorRef
|
|
import cats.effect.concurrent.Ref
|
|
import com.jme3.input.InputManager
|
|
import com.jme3.input.KeyInput
|
|
import com.jme3.input.MouseInput
|
|
import com.jme3.input.controls.KeyTrigger
|
|
import com.jme3.input.controls.MouseAxisTrigger
|
|
import monix.bio.UIO
|
|
import monix.{eval => me}
|
|
import wow.doge.mygame.implicits._
|
|
import wow.doge.mygame.subsystems.events.EventBus
|
|
import wow.doge.mygame.subsystems.events.EventsModule.GameEventBus
|
|
import wow.doge.mygame.subsystems.events.PlayerCameraEvent
|
|
import wow.doge.mygame.subsystems.events.PlayerEvent
|
|
import wow.doge.mygame.subsystems.events.PlayerMovementEvent
|
|
import wow.doge.mygame.utils.IOUtils._
|
|
|
|
object GameInputHandler {
|
|
|
|
class Props(
|
|
inputManager: InputManager,
|
|
playerEventBus: GameEventBus[PlayerEvent]
|
|
// playerCameraEventBus: GameEventBus[PlayerCameraEvent]
|
|
// tickEventBus: GameEventBus[TickEvent]
|
|
) {
|
|
def begin =
|
|
for {
|
|
_ <- UIO(setupMovementKeys(inputManager))
|
|
// _ <- UIO(setupAnalogMovementKeys)
|
|
_ <- UIO(setupCameraKeys())
|
|
_ <- toIO(
|
|
me.Task.parSequence(
|
|
Seq(
|
|
playerMovementInputEventsGenerator(
|
|
inputManager,
|
|
playerEventBus
|
|
).completedL,
|
|
// generateAnalogMovementEvents(
|
|
// inputManager,
|
|
// playerEventBus
|
|
// ).completedL,
|
|
// cameraMovementEventsGenerator(
|
|
// inputManager,
|
|
// playerEventBus
|
|
// ).completedL,
|
|
Ref
|
|
.of[me.Task, Boolean](false)
|
|
.flatMap(value => cursorToggle(value))
|
|
)
|
|
)
|
|
).startAndForget
|
|
} yield ()
|
|
|
|
def setupMovementKeys(inputManager: InputManager) =
|
|
inputManager.withEnumMappings(PlayerMovementInput) {
|
|
case PlayerMovementInput.WalkRight =>
|
|
new KeyTrigger(KeyInput.KEY_D) :: Nil
|
|
case PlayerMovementInput.WalkLeft =>
|
|
new KeyTrigger(KeyInput.KEY_A) :: Nil
|
|
case PlayerMovementInput.WalkForward =>
|
|
new KeyTrigger(KeyInput.KEY_W) :: Nil
|
|
case PlayerMovementInput.WalkBackward =>
|
|
new KeyTrigger(KeyInput.KEY_S) :: Nil
|
|
case PlayerMovementInput.Jump =>
|
|
new KeyTrigger(KeyInput.KEY_SPACE) :: Nil
|
|
}
|
|
|
|
def setupAnalogMovementKeys() =
|
|
inputManager.withEnumMappings(PlayerAnalogMovementInput) {
|
|
case PlayerAnalogMovementInput.TurnRight =>
|
|
Seq(new KeyTrigger(KeyInput.KEY_D))
|
|
case PlayerAnalogMovementInput.TurnLeft =>
|
|
Seq(new KeyTrigger(KeyInput.KEY_A))
|
|
}
|
|
|
|
def setupCameraKeys() =
|
|
inputManager.withEnumMappings(PlayerCameraInput) {
|
|
case PlayerCameraInput.CameraRotateLeft =>
|
|
Seq(
|
|
new KeyTrigger(KeyInput.KEY_LEFT),
|
|
new MouseAxisTrigger(MouseInput.AXIS_X, false)
|
|
)
|
|
case PlayerCameraInput.CameraRotateRight =>
|
|
Seq(
|
|
new KeyTrigger(KeyInput.KEY_RIGHT),
|
|
new MouseAxisTrigger(MouseInput.AXIS_X, true)
|
|
)
|
|
case PlayerCameraInput.CameraRotateUp =>
|
|
Seq(
|
|
new KeyTrigger(KeyInput.KEY_UP),
|
|
new MouseAxisTrigger(MouseInput.AXIS_Y, false)
|
|
)
|
|
case PlayerCameraInput.CameraRotateDown =>
|
|
Seq(
|
|
new KeyTrigger(KeyInput.KEY_DOWN),
|
|
new MouseAxisTrigger(MouseInput.AXIS_Y, true)
|
|
)
|
|
}
|
|
|
|
def cursorToggle(toggleRef: Ref[me.Task, Boolean]) =
|
|
for {
|
|
_ <- me.Task(
|
|
inputManager.withMapping(
|
|
MiscInput.ToggleCursor,
|
|
new KeyTrigger(KeyInput.KEY_Z)
|
|
)
|
|
)
|
|
_ <-
|
|
inputManager
|
|
.enumEntryObservableAction(MiscInput.ToggleCursor)
|
|
.doOnNext(action =>
|
|
action.binding match {
|
|
case MiscInput.ToggleCursor =>
|
|
if (action.value) for {
|
|
value <- toggleRef.getAndUpdate(!_)
|
|
_ <- me.Task(inputManager.setCursorVisible(value))
|
|
} yield ()
|
|
else me.Task.unit
|
|
// case _ => me.Task.unit
|
|
}
|
|
)
|
|
.completedL
|
|
} yield ()
|
|
|
|
}
|
|
|
|
def methodName(implicit enclosing: sourcecode.Enclosing) =
|
|
enclosing.value.split(" ")(0).split("""\.""").last
|
|
|
|
def playerMovementInputEventsGenerator(
|
|
inputManager: InputManager,
|
|
playerEventBus: GameEventBus[PlayerEvent]
|
|
) = {
|
|
val name = methodName
|
|
inputManager
|
|
.enumObservableAction(PlayerMovementInput)
|
|
// .dump("O")
|
|
.doOnNext { action =>
|
|
action.binding match {
|
|
case PlayerMovementInput.WalkLeft =>
|
|
me.Task(
|
|
playerEventBus ! EventBus.Publish(
|
|
PlayerMovementEvent.PlayerMovedLeft(pressed = action.value),
|
|
name
|
|
)
|
|
)
|
|
case PlayerMovementInput.WalkRight =>
|
|
me.Task(
|
|
playerEventBus ! EventBus.Publish(
|
|
PlayerMovementEvent.PlayerMovedRight(pressed = action.value),
|
|
name
|
|
)
|
|
)
|
|
case PlayerMovementInput.WalkForward =>
|
|
me.Task(
|
|
playerEventBus ! EventBus.Publish(
|
|
PlayerMovementEvent.PlayerMovedForward(pressed = action.value),
|
|
name
|
|
)
|
|
)
|
|
case PlayerMovementInput.WalkBackward =>
|
|
me.Task(
|
|
playerEventBus ! EventBus.Publish(
|
|
PlayerMovementEvent.PlayerMovedBackward(pressed = action.value),
|
|
name
|
|
)
|
|
)
|
|
case PlayerMovementInput.Jump =>
|
|
if (action.value)
|
|
me.Task(
|
|
playerEventBus ! EventBus.Publish(
|
|
PlayerMovementEvent.PlayerJumped,
|
|
name
|
|
)
|
|
)
|
|
else me.Task.unit
|
|
}
|
|
}
|
|
}
|
|
|
|
def generateAnalogMovementEvents(
|
|
inputManager: InputManager,
|
|
playerEventBus: GameEventBus[PlayerEvent]
|
|
) =
|
|
// val name = "analogMovementEventsGenerator"
|
|
inputManager
|
|
.enumAnalogObservable(PlayerAnalogMovementInput)
|
|
.sample(1.millis)
|
|
// .doOnNext(analogEvent =>
|
|
// analogEvent.binding match {
|
|
// case PlayerAnalogMovementInput.TurnRight =>
|
|
// me.Task(
|
|
// playerMovementEventBus ! EventBus.Publish(
|
|
// PlayerMovementEvent.PlayerTurnedRight,
|
|
// name
|
|
// )
|
|
// )
|
|
// case PlayerAnalogMovementInput.TurnLeft =>
|
|
// me.Task(
|
|
// playerMovementEventBus ! EventBus.Publish(
|
|
// PlayerMovementEvent.PlayerTurnedLeft,
|
|
// name
|
|
// )
|
|
// )
|
|
// }
|
|
// )
|
|
|
|
def cameraMovementEventsGenerator(
|
|
inputManager: InputManager,
|
|
playerEventBus: ActorRef[EventBus.Command[PlayerEvent]]
|
|
) = {
|
|
val name = methodName
|
|
inputManager
|
|
.enumAnalogObservable(PlayerCameraInput)
|
|
.sample(1.millis)
|
|
.doOnNext(analogEvent =>
|
|
analogEvent.binding match {
|
|
case PlayerCameraInput.CameraRotateLeft =>
|
|
me.Task(
|
|
playerEventBus ! EventBus.Publish(
|
|
PlayerCameraEvent.CameraLeft,
|
|
name
|
|
)
|
|
)
|
|
case PlayerCameraInput.CameraRotateRight =>
|
|
me.Task(
|
|
playerEventBus ! EventBus.Publish(
|
|
PlayerCameraEvent.CameraRight,
|
|
name
|
|
)
|
|
)
|
|
case PlayerCameraInput.CameraRotateUp =>
|
|
me.Task(
|
|
playerEventBus ! EventBus.Publish(
|
|
PlayerCameraEvent.CameraMovedUp,
|
|
name
|
|
)
|
|
)
|
|
case PlayerCameraInput.CameraRotateDown =>
|
|
me.Task(
|
|
playerEventBus ! EventBus.Publish(
|
|
PlayerCameraEvent.CameraMovedDown,
|
|
name
|
|
)
|
|
)
|
|
}
|
|
)
|
|
}
|
|
}
|