Add rest of the player movement messages

This commit is contained in:
Rohan Sircar 2021-03-08 19:18:28 +05:30
parent be9acf81d5
commit f0ae3625bf
4 changed files with 71 additions and 24 deletions

View File

@ -40,7 +40,7 @@ object PlayerActor {
case object Dead extends Status case object Dead extends Status
} }
sealed trait Command sealed trait Command extends Product with Serializable
final case class TakeDamage( final case class TakeDamage(
value: CharacterStats.DamageHealth, value: CharacterStats.DamageHealth,
replyTo: ActorRef[Unit] replyTo: ActorRef[Unit]
@ -57,8 +57,15 @@ object PlayerActor {
replyTo: ActorRef[UIO[Observable[CharacterStats]]] replyTo: ActorRef[UIO[Observable[CharacterStats]]]
) extends Command ) extends Command
sealed trait Movement extends Command final case class MoveLeft(pressed: Boolean) extends Command
final case class MoveLeft(pressed: Boolean) extends Movement final case class MoveUp(pressed: Boolean) extends Command
final case class MoveRight(pressed: Boolean) extends Command
final case class MoveDown(pressed: Boolean) extends Command
case object Jump extends Command
private[player] final case class HandleMovement(
b: CharacterStats,
pressed: Boolean
) extends Command
private[player] case object Die extends Command private[player] case object Die extends Command
private[player] final case class StatsResponse( private[player] final case class StatsResponse(
@ -102,7 +109,6 @@ object PlayerActor {
Behaviors Behaviors
.supervise( .supervise(
new PlayerMovementEventListener.Props( new PlayerMovementEventListener.Props(
playerMovementActor,
ctx.self, ctx.self,
scheduler scheduler
).behavior ).behavior

View File

@ -18,6 +18,8 @@ import wow.doge.mygame.AppError
import wow.doge.mygame.executors.Schedulers import wow.doge.mygame.executors.Schedulers
import wow.doge.mygame.executors.Schedulers.AsyncScheduler import wow.doge.mygame.executors.Schedulers.AsyncScheduler
import wow.doge.mygame.game.GameApp import wow.doge.mygame.game.GameApp
import wow.doge.mygame.game.entities.CharacterStats
import wow.doge.mygame.game.entities.StatsActor
import wow.doge.mygame.implicits._ import wow.doge.mygame.implicits._
import wow.doge.mygame.math.ImVector3f import wow.doge.mygame.math.ImVector3f
import wow.doge.mygame.subsystems.events.EventsModule.GameEventBus import wow.doge.mygame.subsystems.events.EventsModule.GameEventBus
@ -26,8 +28,6 @@ import wow.doge.mygame.subsystems.events.TickEvent
import wow.doge.mygame.subsystems.movement.ImMovementActor import wow.doge.mygame.subsystems.movement.ImMovementActor
import wow.doge.mygame.types._ import wow.doge.mygame.types._
import wow.doge.mygame.utils.wrappers.jme._ import wow.doge.mygame.utils.wrappers.jme._
import wow.doge.mygame.game.entities.StatsActor
import wow.doge.mygame.game.entities.CharacterStats
object PlayerController { object PlayerController {
sealed trait Error sealed trait Error

View File

@ -2,12 +2,13 @@ package wow.doge.mygame.game.entities.player
import scala.concurrent.duration._ import scala.concurrent.duration._
import akka.actor.typed.ActorRef
import akka.actor.typed.Behavior import akka.actor.typed.Behavior
import akka.actor.typed.LogOptions import akka.actor.typed.LogOptions
import akka.actor.typed.scaladsl.ActorContext import akka.actor.typed.scaladsl.ActorContext
import akka.actor.typed.scaladsl.AskPattern._
import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.scaladsl.Behaviors
import akka.util.Timeout import akka.util.Timeout
import cats.syntax.eq._
import com.typesafe.scalalogging.Logger import com.typesafe.scalalogging.Logger
import monix.eval.Task import monix.eval.Task
import monix.execution.CancelableFuture import monix.execution.CancelableFuture
@ -17,14 +18,11 @@ import wow.doge.mygame.executors.Schedulers
import wow.doge.mygame.game.entities.CharacterStats import wow.doge.mygame.game.entities.CharacterStats
import wow.doge.mygame.implicits._ import wow.doge.mygame.implicits._
import wow.doge.mygame.subsystems.events.PlayerMovementEvent import wow.doge.mygame.subsystems.events.PlayerMovementEvent
import wow.doge.mygame.subsystems.movement.ImMovementActor
import cats.syntax.eq._
object PlayerMovementEventListener { object PlayerMovementEventListener {
final case class State(keysPressed: Int, staminaTimer: CancelableFuture[Unit]) final case class State(keysPressed: Int, staminaTimer: CancelableFuture[Unit])
class Props( class Props(
val movementActor: ActorRef[ImMovementActor.Command],
val playerActor: PlayerActor.Ref, val playerActor: PlayerActor.Ref,
val asyncScheduler: Schedulers.AsyncScheduler val asyncScheduler: Schedulers.AsyncScheduler
) { ) {
@ -97,16 +95,22 @@ class PlayerMovementEventListener(
props.playerActor ! PlayerActor.MoveLeft(pressed) props.playerActor ! PlayerActor.MoveLeft(pressed)
receive(handleStamina(pressed)) receive(handleStamina(pressed))
case PlayerMovedRight(pressed) => case PlayerMovedRight(pressed) =>
props.movementActor ! ImMovementActor.MoveRight(pressed) props.playerActor ! PlayerActor.MoveRight(pressed)
receive(handleStamina(pressed)) receive(handleStamina(pressed))
case PlayerMovedForward(pressed) => case PlayerMovedForward(pressed) =>
props.movementActor ! ImMovementActor.MoveUp(pressed) props.playerActor ! PlayerActor.MoveUp(pressed)
receive(handleStamina(pressed)) receive(handleStamina(pressed))
case PlayerMovedBackward(pressed) => case PlayerMovedBackward(pressed) =>
props.movementActor ! ImMovementActor.MoveDown(pressed) props.playerActor ! PlayerActor.MoveDown(pressed)
receive(handleStamina(pressed)) receive(handleStamina(pressed))
case PlayerJumped => case PlayerJumped =>
props.movementActor ! ImMovementActor.Jump props.playerActor ! PlayerActor.Jump
// props.playerActor
// ctx.ask(
// props.playerActor,
// PlayerActor
// .ConsumeStamina(CharacterStats.DamageStamina(1), _)
// )(_ => ())
Behaviors.same Behaviors.same
// case PlayerTurnedRight => // case PlayerTurnedRight =>
// movementActor ! ImMovementActor.RotateRight // movementActor ! ImMovementActor.RotateRight

View File

@ -23,7 +23,6 @@ class IdleBehaviorFactory(
deadState: Behavior[PlayerActor.Command], deadState: Behavior[PlayerActor.Command],
consumptionMultiplier: Int => Int consumptionMultiplier: Int => Int
)(implicit timeout: Timeout) { )(implicit timeout: Timeout) {
import IdleBehaviorFactory.IdleBehavior
import env._ import env._
implicit val sched = ctx.system.scheduler implicit val sched = ctx.system.scheduler
@ -32,11 +31,46 @@ class IdleBehaviorFactory(
IdleBehavior( IdleBehavior(
Behaviors Behaviors
.receiveMessage[PlayerActor.Command] { .receiveMessage[PlayerActor.Command] {
case PlayerActor.MoveLeft(pressed) =>
case PlayerActor.HandleMovement(curStats, pressed) =>
if (curStats.stamina.toInt > 0) {
children.movementActor ! ImMovementActor.MoveLeft(pressed) children.movementActor ! ImMovementActor.MoveLeft(pressed)
if (pressed) if (pressed) nextStateFn(AliveSubstate.Moving(Walking))
nextStateFn(AliveSubstate.Moving(Walking))
else nextStateFn(AliveSubstate.Idle) else nextStateFn(AliveSubstate.Idle)
} else Behaviors.same
case PlayerActor.MoveLeft(pressed) =>
implicit val ec = props.scheduler.value
for {
curStats <- children.statsActor.ask(StatsActor.CurrentStats)
res <- Future.successful(
ctx.self ! PlayerActor.HandleMovement(curStats, pressed)
)
} yield res
Behaviors.same
case PlayerActor.MoveRight(pressed) =>
children.movementActor ! ImMovementActor.MoveRight(pressed)
if (pressed) nextStateFn(AliveSubstate.Moving(Walking))
else nextStateFn(AliveSubstate.Idle)
case PlayerActor.MoveUp(pressed) =>
children.movementActor ! ImMovementActor.MoveUp(pressed)
if (pressed) nextStateFn(AliveSubstate.Moving(Walking))
else nextStateFn(AliveSubstate.Idle)
case PlayerActor.MoveDown(pressed) =>
children.movementActor ! ImMovementActor.MoveDown(pressed)
if (pressed) nextStateFn(AliveSubstate.Moving(Walking))
else nextStateFn(AliveSubstate.Idle)
case PlayerActor.Jump =>
children.movementActor ! ImMovementActor.Jump
ctx.self.ask(
PlayerActor.ConsumeStamina(CharacterStats.DamageStamina(10), _)
)
Behaviors.same
case PlayerActor.TakeDamage(value, replyTo) => case PlayerActor.TakeDamage(value, replyTo) =>
implicit val ec = props.scheduler.value implicit val ec = props.scheduler.value
for { for {
@ -47,6 +81,7 @@ class IdleBehaviorFactory(
) )
} yield () } yield ()
Behaviors.same Behaviors.same
case PlayerActor.ConsumeStamina(value, replyTo) => case PlayerActor.ConsumeStamina(value, replyTo) =>
implicit val ec = props.scheduler.value implicit val ec = props.scheduler.value
val newValue = val newValue =
@ -60,15 +95,19 @@ class IdleBehaviorFactory(
.StatsResponse(response, replyTo) .StatsResponse(response, replyTo)
} yield () } yield ()
Behaviors.same Behaviors.same
case PlayerActor.CurrentStats(replyTo) => case PlayerActor.CurrentStats(replyTo) =>
children.statsActor ! StatsActor.CurrentStats(replyTo) children.statsActor ! StatsActor.CurrentStats(replyTo)
Behaviors.same Behaviors.same
case PlayerActor.Heal(value) => case PlayerActor.Heal(value) =>
children.statsActor ! StatsActor.HealResult(value) children.statsActor ! StatsActor.HealResult(value)
Behaviors.same Behaviors.same
case PlayerActor.GetStatus(replyTo) => case PlayerActor.GetStatus(replyTo) =>
replyTo ! PlayerActor.Status.Alive replyTo ! PlayerActor.Status.Alive
Behaviors.same Behaviors.same
case PlayerActor.GetStatsObservable(replyTo) => case PlayerActor.GetStatsObservable(replyTo) =>
import monix.{eval => me} import monix.{eval => me}
replyTo ! replyTo !
@ -82,6 +121,7 @@ class IdleBehaviorFactory(
) )
Behaviors.same Behaviors.same
case PlayerActor.StatsResponse(response, replyTo) => case PlayerActor.StatsResponse(response, replyTo) =>
response match { response match {
case (dead, stats) => case (dead, stats) =>
@ -94,8 +134,9 @@ class IdleBehaviorFactory(
}(props.scheduler.value) }(props.scheduler.value)
} }
Behaviors.same Behaviors.same
// nextStateFn(InCombat(Moving(Walking)))
case PlayerActor.Die => deadState case PlayerActor.Die => deadState
case PlayerActor.LogError(ex) => case PlayerActor.LogError(ex) =>
ctx.log.error(ex.getMessage) ctx.log.error(ex.getMessage)
Behaviors.same Behaviors.same
@ -108,8 +149,4 @@ class IdleBehaviorFactory(
) )
} }
object IdleBehaviorFactory { final case class IdleBehavior(value: Behavior[PlayerActor.Command])
final case class IdleBehavior(
value: Behavior[PlayerActor.Command]
)
}