From 44f0538b8b50bf29331c1dd0969fa8647661ee09 Mon Sep 17 00:00:00 2001 From: Rohan Sircar Date: Tue, 9 Mar 2021 19:14:17 +0530 Subject: [PATCH] Player cannot walk when stamina is 0 --- src/main/scala/wow/doge/mygame/MainApp.scala | 2 +- .../game/entities/player/PlayerActor.scala | 14 +++-- .../player/PlayerEventListeners.scala | 34 ++++++++-- .../player/behaviors/IdleBehavior.scala | 63 ++++++++++--------- .../subsystems/movement/MovementActor.scala | 5 ++ .../doge/mygame/utils/MovementDirection.scala | 18 ++++++ 6 files changed, 93 insertions(+), 43 deletions(-) create mode 100644 src/main/scala/wow/doge/mygame/utils/MovementDirection.scala diff --git a/src/main/scala/wow/doge/mygame/MainApp.scala b/src/main/scala/wow/doge/mygame/MainApp.scala index ed16f23..8f1bbba 100644 --- a/src/main/scala/wow/doge/mygame/MainApp.scala +++ b/src/main/scala/wow/doge/mygame/MainApp.scala @@ -175,7 +175,7 @@ class MainApp( 15.seconds ).toTask .void - case _ => monix.eval.Task.unit + case _ => me.Task.unit } _ <- Resource.make(obs.completedL.toIO.hideErrors.start)(_.cancel) // _ <- diff --git a/src/main/scala/wow/doge/mygame/game/entities/player/PlayerActor.scala b/src/main/scala/wow/doge/mygame/game/entities/player/PlayerActor.scala index 157dfe7..f0276e7 100644 --- a/src/main/scala/wow/doge/mygame/game/entities/player/PlayerActor.scala +++ b/src/main/scala/wow/doge/mygame/game/entities/player/PlayerActor.scala @@ -29,6 +29,7 @@ import wow.doge.mygame.subsystems.events.PlayerEvent import wow.doge.mygame.subsystems.events.TickEvent import wow.doge.mygame.subsystems.events.TickEvent.RenderTick import wow.doge.mygame.subsystems.movement.ImMovementActor +import wow.doge.mygame.utils.MovementDirection object PlayerActor { @@ -64,14 +65,15 @@ object PlayerActor { replyTo: ActorRef[UIO[Observable[CharacterStats]]] ) extends Command - final case class MoveLeft(pressed: Boolean) extends Command - final case class MoveUp(pressed: Boolean) extends Command - final case class MoveRight(pressed: Boolean) extends Command - final case class MoveDown(pressed: Boolean) extends Command + final case class Walk(pressed: Boolean, dir: MovementDirection) + extends Command + case object StopMoving extends Command case object Jump extends Command - private[player] final case class HandleMovement( + + private[player] final case class HandleWalk( b: CharacterStats, - pressed: Boolean + pressed: Boolean, + direction: MovementDirection ) extends Command private[player] case object Die extends Command diff --git a/src/main/scala/wow/doge/mygame/game/entities/player/PlayerEventListeners.scala b/src/main/scala/wow/doge/mygame/game/entities/player/PlayerEventListeners.scala index c849e33..e57d2a8 100644 --- a/src/main/scala/wow/doge/mygame/game/entities/player/PlayerEventListeners.scala +++ b/src/main/scala/wow/doge/mygame/game/entities/player/PlayerEventListeners.scala @@ -18,6 +18,7 @@ import wow.doge.mygame.executors.Schedulers import wow.doge.mygame.game.entities.CharacterStats import wow.doge.mygame.implicits._ import wow.doge.mygame.subsystems.events.PlayerMovementEvent +import wow.doge.mygame.utils.MovementDirection object PlayerMovementEventListener { final case class State( @@ -60,14 +61,19 @@ class PlayerMovementEventListener( Observable .interval(250.millis) .doOnNext(_ => Task(pprint.log("Sending Stamina Consume Item"))) - .doOnNextF(_ => + .mapEvalF(_ => props.playerActor .askL( PlayerActor .ConsumeStamina(CharacterStats.DamageStamina(25), _) ) - .void ) + .doOnNext(stats => + if (stats.stamina.toInt === 0) + Task(props.playerActor ! PlayerActor.StopMoving) + else Task.unit + ) + .takeWhile(_.stamina.toInt >= 0) .completedL ) @@ -121,16 +127,32 @@ class PlayerMovementEventListener( Behaviors.receiveMessage { case PlayerMovedLeft(pressed) => // props.movementActor ! ImMovementActor.MoveLeft(pressed) - props.playerActor ! PlayerActor.MoveLeft(pressed) + // props.playerActor ! PlayerActor.MoveLeft(pressed) + props.playerActor ! PlayerActor.Walk( + pressed, + MovementDirection.Left + ) receive(handleStamina(pressed)) case PlayerMovedRight(pressed) => - props.playerActor ! PlayerActor.MoveRight(pressed) + // props.playerActor ! PlayerActor.MoveRight(pressed) + props.playerActor ! PlayerActor.Walk( + pressed, + MovementDirection.Right + ) receive(handleStamina(pressed)) case PlayerMovedForward(pressed) => - props.playerActor ! PlayerActor.MoveUp(pressed) + // props.playerActor ! PlayerActor.MoveUp(pressed) + props.playerActor ! PlayerActor.Walk( + pressed, + MovementDirection.Forward + ) receive(handleStamina(pressed)) case PlayerMovedBackward(pressed) => - props.playerActor ! PlayerActor.MoveDown(pressed) + // props.playerActor ! PlayerActor.MoveDown(pressed) + props.playerActor ! PlayerActor.Walk( + pressed, + MovementDirection.Backward + ) receive(handleStamina(pressed)) case PlayerJumped => props.playerActor ! PlayerActor.Jump diff --git a/src/main/scala/wow/doge/mygame/game/entities/player/behaviors/IdleBehavior.scala b/src/main/scala/wow/doge/mygame/game/entities/player/behaviors/IdleBehavior.scala index 174c48a..af2eb66 100644 --- a/src/main/scala/wow/doge/mygame/game/entities/player/behaviors/IdleBehavior.scala +++ b/src/main/scala/wow/doge/mygame/game/entities/player/behaviors/IdleBehavior.scala @@ -16,6 +16,7 @@ import wow.doge.mygame.game.entities.character.CharacterStates._ import wow.doge.mygame.game.entities.player.PlayerActor import wow.doge.mygame.implicits._ import wow.doge.mygame.subsystems.movement.ImMovementActor +import wow.doge.mygame.utils.MovementDirection class IdleBehaviorFactory( env: PlayerActor.Env, @@ -32,41 +33,43 @@ class IdleBehaviorFactory( Behaviors .receiveMessage[PlayerActor.Command] { - case PlayerActor.HandleMovement(curStats, pressed) => + case PlayerActor.HandleWalk(curStats, pressed, direction) => if (curStats.stamina.toInt > 0) { - children.movementActor ! ImMovementActor.MoveLeft(pressed) + children.movementActor ! (direction match { + case MovementDirection.Forward => + ImMovementActor.MoveUp(pressed) + case MovementDirection.Backward => + ImMovementActor.MoveDown(pressed) + case MovementDirection.Left => ImMovementActor.MoveLeft(pressed) + case MovementDirection.Right => + ImMovementActor.MoveRight(pressed) + }) if (pressed) nextStateFn(AliveSubstate.Moving(Walking)) else nextStateFn(AliveSubstate.Idle) } else { - children.movementActor ! ImMovementActor.MoveLeft(false) + children.movementActor ! ImMovementActor.StopMoving Behaviors.same } - case PlayerActor.MoveLeft(pressed) => + // case PlayerActor.Walk(pressed, Direction.Up) => Behaviors.same + // case PlayerActor.Walk(pressed, Direction.Down) => Behaviors.same + // case PlayerActor.Walk(pressed, Direction.Left) => Behaviors.same + // case PlayerActor.Walk(pressed, Direction.Right) => Behaviors.same + + case PlayerActor.StopMoving => + children.movementActor ! ImMovementActor.StopMoving + Behaviors.same + + case PlayerActor.Walk(pressed, direction) => implicit val ec = props.scheduler.value for { curStats <- children.statsActor.ask(StatsActor.CurrentStats) - res <- Future.successful( - ctx.self ! PlayerActor.HandleMovement(curStats, pressed) + _ <- Future.successful( + ctx.self ! PlayerActor.HandleWalk(curStats, pressed, direction) ) - } yield res + } yield () 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( @@ -151,15 +154,15 @@ class IdleBehaviorFactory( response match { case (status, stats) => status match { - case StatsActor.Status.Dead => ctx.self ! PlayerActor.Die - case StatsActor.Status.Alive => - props.statsQueue - .offer(stats) - .foreach { _ => - pprint.log(show"Published stats $stats") - replyTo ! stats - }(props.scheduler.value) + case StatsActor.Status.Dead => ctx.self ! PlayerActor.Die + case StatsActor.Status.Alive => () } + props.statsQueue + .offer(stats) + .foreach { _ => + pprint.log(show"Published stats $stats") + replyTo ! stats + }(props.scheduler.value) } Behaviors.same diff --git a/src/main/scala/wow/doge/mygame/game/subsystems/movement/MovementActor.scala b/src/main/scala/wow/doge/mygame/game/subsystems/movement/MovementActor.scala index 4fdd34d..78e862b 100644 --- a/src/main/scala/wow/doge/mygame/game/subsystems/movement/MovementActor.scala +++ b/src/main/scala/wow/doge/mygame/game/subsystems/movement/MovementActor.scala @@ -36,6 +36,7 @@ object ImMovementActor { final case class MoveUp(pressed: Boolean) extends Movement final case class MoveRight(pressed: Boolean) extends Movement final case class MoveDown(pressed: Boolean) extends Movement + case object StopMoving extends Movement case object Jump extends Movement class Props( @@ -77,6 +78,10 @@ class ImMovementActor[T]( .receiveMessage[Command] { case m: Movement => m match { + case StopMoving => + cm.stop(movable) + receive(State(CardinalDirection.default), new Vector3f) + case MoveLeft(pressed) => stopIfNotPressed(pressed) receive( diff --git a/src/main/scala/wow/doge/mygame/utils/MovementDirection.scala b/src/main/scala/wow/doge/mygame/utils/MovementDirection.scala new file mode 100644 index 0000000..3633271 --- /dev/null +++ b/src/main/scala/wow/doge/mygame/utils/MovementDirection.scala @@ -0,0 +1,18 @@ +package wow.doge.mygame.utils + +import enumeratum._ +import cats.kernel.Eq +import cats.Show + +sealed trait MovementDirection extends EnumEntry + +object MovementDirection extends Enum[MovementDirection] { + val values = findValues + case object Forward extends MovementDirection + case object Backward extends MovementDirection + case object Left extends MovementDirection + case object Right extends MovementDirection + + implicit val eq = Eq.fromUniversalEquals[MovementDirection] + implicit val show = Show.fromToString[MovementDirection] +}