Player actor changes
Rename PlayerActorSupervisor to PlayerActor Make PlayerEventListener able to handle multiple inputs
This commit is contained in:
parent
67201c8f7e
commit
be9acf81d5
@ -52,7 +52,7 @@ import wow.doge.mygame.game.entities.CharacterStats
|
||||
import wow.doge.mygame.game.entities.EntityIds
|
||||
import wow.doge.mygame.game.entities.NpcActorSupervisor
|
||||
import wow.doge.mygame.game.entities.NpcMovementActor
|
||||
import wow.doge.mygame.game.entities.player.PlayerActorSupervisor
|
||||
import wow.doge.mygame.game.entities.player.PlayerActor
|
||||
import wow.doge.mygame.game.entities.player.PlayerController
|
||||
import wow.doge.mygame.game.subsystems.input.GameInputHandler
|
||||
import wow.doge.mygame.game.subsystems.input.PlayerCameraInput
|
||||
@ -203,7 +203,7 @@ class MainApp(
|
||||
.use(_ => launchSignal.get)
|
||||
.hideErrors
|
||||
tickEventBus <-
|
||||
eventsModule.tickEventBus.hideErrorsWith(e => DummyException(e.toString))
|
||||
eventsModule.tickEventBus.hideErrorsWith(e => new Exception(e.toString))
|
||||
_ <-
|
||||
/**
|
||||
* User chose to quit
|
||||
@ -288,7 +288,7 @@ class MainAppDelegate(
|
||||
(loggerL.debug(show"Received Damage Event $event") >>
|
||||
(if (event.victimName === "PlayerNode")
|
||||
playerActor
|
||||
.askL(PlayerActorSupervisor.TakeDamage(event.amount, _))
|
||||
.askL(PlayerActor.TakeDamage(event.amount, _))
|
||||
.onErrorHandle { case ex: TimeoutException => () }
|
||||
else IO.unit)).toTask
|
||||
)
|
||||
@ -377,7 +377,7 @@ class MainAppDelegate(
|
||||
// .startAndForget
|
||||
statsObs <-
|
||||
playerActor
|
||||
.askL(PlayerActorSupervisor.GetStatsObservable(_))
|
||||
.askL(PlayerActor.GetStatsObservable(_))
|
||||
.onErrorHandleWith(TimeoutError.from)
|
||||
.flatten
|
||||
playerHud <-
|
||||
@ -480,7 +480,7 @@ class MainAppDelegate(
|
||||
|
||||
def createPlayerController(
|
||||
// appScheduler: monix.execution.Scheduler
|
||||
): IO[AppError, PlayerActorSupervisor.Ref] = {
|
||||
): IO[AppError, PlayerActor.Ref] = {
|
||||
val playerPos = ImVector3f.Zero
|
||||
val modelPath = os.rel / "Models" / "Jaime" / "Jaime.j3o"
|
||||
// val modelPath = os.rel / "Models" / "Oto" / "Oto.mesh.xml"
|
||||
|
@ -30,10 +30,9 @@ import wow.doge.mygame.subsystems.events.TickEvent
|
||||
import wow.doge.mygame.subsystems.events.TickEvent.RenderTick
|
||||
import wow.doge.mygame.subsystems.movement.ImMovementActor
|
||||
|
||||
//TODO: Change name to PlayerActor
|
||||
object PlayerActorSupervisor {
|
||||
object PlayerActor {
|
||||
|
||||
type Ref = ActorRef[PlayerActorSupervisor.Command]
|
||||
type Ref = ActorRef[PlayerActor.Command]
|
||||
|
||||
sealed trait Status
|
||||
object Status {
|
||||
@ -71,6 +70,7 @@ object PlayerActorSupervisor {
|
||||
val playerEventBus: GameEventBus[PlayerEvent],
|
||||
val tickEventBus: GameEventBus[TickEvent],
|
||||
val imMovementActorBehavior: Behavior[ImMovementActor.Command],
|
||||
val statsActorBehavior: Behavior[StatsActor.Command],
|
||||
val scheduler: AsyncScheduler,
|
||||
val fxScheduler: Schedulers.FxScheduler,
|
||||
val statsQueue: AsyncQueue[CharacterStats]
|
||||
@ -79,20 +79,14 @@ object PlayerActorSupervisor {
|
||||
Behaviors.logMessages(
|
||||
LogOptions()
|
||||
.withLevel(Level.DEBUG)
|
||||
.withLogger(Logger[PlayerActorSupervisor].underlying),
|
||||
.withLogger(Logger[PlayerActor].underlying),
|
||||
Behaviors
|
||||
.setup[Command] { ctx =>
|
||||
ctx.log.infoP("Starting PlayerActor")
|
||||
|
||||
// spawn children actors
|
||||
|
||||
val playerStatsActor =
|
||||
ctx.spawnN(
|
||||
new StatsActor.Props(
|
||||
CharacterStats.Health(100),
|
||||
CharacterStats.Stamina(100)
|
||||
).behavior
|
||||
)
|
||||
val playerStatsActor = ctx.spawnN(statsActorBehavior)
|
||||
|
||||
val playerMovementActor =
|
||||
ctx.spawnN(
|
||||
@ -141,7 +135,7 @@ object PlayerActorSupervisor {
|
||||
playerEventBus ! EventBus.Subscribe(playerMovementEl)
|
||||
tickEventBus ! EventBus.Subscribe(renderTickEl)
|
||||
|
||||
new PlayerActorSupervisor(
|
||||
new PlayerActor(
|
||||
ctx,
|
||||
this,
|
||||
Children(playerMovementActor, playerStatsActor)
|
||||
@ -157,18 +151,18 @@ object PlayerActorSupervisor {
|
||||
)
|
||||
|
||||
final case class Env(
|
||||
ctx: ActorContext[PlayerActorSupervisor.Command],
|
||||
props: PlayerActorSupervisor.Props,
|
||||
children: PlayerActorSupervisor.Children
|
||||
ctx: ActorContext[PlayerActor.Command],
|
||||
props: PlayerActor.Props,
|
||||
children: PlayerActor.Children
|
||||
)
|
||||
}
|
||||
|
||||
class PlayerActorSupervisor(
|
||||
ctx: ActorContext[PlayerActorSupervisor.Command],
|
||||
props: PlayerActorSupervisor.Props,
|
||||
children: PlayerActorSupervisor.Children
|
||||
class PlayerActor(
|
||||
ctx: ActorContext[PlayerActor.Command],
|
||||
props: PlayerActor.Props,
|
||||
children: PlayerActor.Children
|
||||
) {
|
||||
import PlayerActorSupervisor._
|
||||
import PlayerActor._
|
||||
implicit val timeout = Timeout(1.second)
|
||||
|
||||
val env = Env(ctx, props, children)
|
@ -26,6 +26,8 @@ import wow.doge.mygame.subsystems.events.TickEvent
|
||||
import wow.doge.mygame.subsystems.movement.ImMovementActor
|
||||
import wow.doge.mygame.types._
|
||||
import wow.doge.mygame.utils.wrappers.jme._
|
||||
import wow.doge.mygame.game.entities.StatsActor
|
||||
import wow.doge.mygame.game.entities.CharacterStats
|
||||
|
||||
object PlayerController {
|
||||
sealed trait Error
|
||||
@ -65,10 +67,15 @@ object PlayerController {
|
||||
enqueueR,
|
||||
camera
|
||||
).behavior(playerPhysicsControl)
|
||||
new PlayerActorSupervisor.Props(
|
||||
val statsActorBeh = new StatsActor.Props(
|
||||
CharacterStats.Health(100),
|
||||
CharacterStats.Stamina(100)
|
||||
).behavior
|
||||
new PlayerActor.Props(
|
||||
playerEventBus,
|
||||
tickEventBus,
|
||||
movementActorBeh,
|
||||
statsActorBeh,
|
||||
scheduler,
|
||||
fxScheduler,
|
||||
AsyncQueue.bounded(10)(scheduler.value)
|
||||
@ -77,10 +84,9 @@ object PlayerController {
|
||||
val playerActor =
|
||||
gameApp.spawnGameActor(
|
||||
playerActorBehavior,
|
||||
// Some("playerActorSupervisor"),
|
||||
props = DispatcherSelector.default()
|
||||
)
|
||||
val create: IO[AppError, ActorRef[PlayerActorSupervisor.Command]] =
|
||||
val create: IO[AppError, ActorRef[PlayerActor.Command]] =
|
||||
(for {
|
||||
// playerActor <-
|
||||
// // AkkaUtils.spawnActorL(playerActorBehavior, "playerActorSupervisor")
|
||||
|
@ -18,19 +18,20 @@ import wow.doge.mygame.game.entities.CharacterStats
|
||||
import wow.doge.mygame.implicits._
|
||||
import wow.doge.mygame.subsystems.events.PlayerMovementEvent
|
||||
import wow.doge.mygame.subsystems.movement.ImMovementActor
|
||||
import cats.syntax.eq._
|
||||
|
||||
object PlayerMovementEventListener {
|
||||
final case class State(staminaTimer: CancelableFuture[Unit])
|
||||
final case class State(keysPressed: Int, staminaTimer: CancelableFuture[Unit])
|
||||
|
||||
class Props(
|
||||
val movementActor: ActorRef[ImMovementActor.Command],
|
||||
val playerActor: PlayerActorSupervisor.Ref,
|
||||
val playerActor: PlayerActor.Ref,
|
||||
val asyncScheduler: Schedulers.AsyncScheduler
|
||||
) {
|
||||
def behavior =
|
||||
Behaviors.setup[PlayerMovementEvent] { ctx =>
|
||||
new PlayerMovementEventListener(ctx, this)
|
||||
.receive(State(CancelableFuture.unit))
|
||||
.receive(State(0, CancelableFuture.unit))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -40,6 +41,7 @@ class PlayerMovementEventListener(
|
||||
) {
|
||||
import PlayerMovementEventListener._
|
||||
import PlayerMovementEvent._
|
||||
import com.softwaremill.quicklens._
|
||||
def receive(state: State): Behavior[PlayerMovementEvent] =
|
||||
Behaviors.logMessages(
|
||||
LogOptions()
|
||||
@ -57,28 +59,42 @@ class PlayerMovementEventListener(
|
||||
.interval(250.millis)
|
||||
.doOnNextF(_ =>
|
||||
props.playerActor.askL(
|
||||
PlayerActorSupervisor
|
||||
PlayerActor
|
||||
.ConsumeStamina(CharacterStats.DamageStamina(1), _)
|
||||
)
|
||||
)
|
||||
.completedL
|
||||
)
|
||||
|
||||
@SuppressWarnings(Array("org.wartremover.warts.Equals"))
|
||||
def handleStamina(pressed: Boolean) =
|
||||
if (pressed)
|
||||
if (state.staminaTimer == CancelableFuture.unit)
|
||||
State(makeStaminaTimer.runToFuture(props.asyncScheduler.value))
|
||||
else state
|
||||
else {
|
||||
state.staminaTimer.cancel()
|
||||
State(CancelableFuture.unit)
|
||||
if (pressed) {
|
||||
val nextState1 =
|
||||
if (state.keysPressed === 0)
|
||||
state
|
||||
.modify(_.staminaTimer)
|
||||
.setTo(
|
||||
makeStaminaTimer.runToFuture(props.asyncScheduler.value)
|
||||
)
|
||||
else state
|
||||
val nextState2 = nextState1
|
||||
.modify(_.keysPressed)
|
||||
.using(_ + 1)
|
||||
nextState2
|
||||
} else {
|
||||
val nextState1 = state
|
||||
.modify(_.keysPressed)
|
||||
.using(_ - 1)
|
||||
if (nextState1.keysPressed === 0) {
|
||||
nextState1.staminaTimer.cancel()
|
||||
nextState1
|
||||
} else
|
||||
nextState1
|
||||
}
|
||||
|
||||
Behaviors.receiveMessage {
|
||||
case PlayerMovedLeft(pressed) =>
|
||||
// props.movementActor ! ImMovementActor.MoveLeft(pressed)
|
||||
props.playerActor ! PlayerActorSupervisor.MoveLeft(pressed)
|
||||
props.playerActor ! PlayerActor.MoveLeft(pressed)
|
||||
receive(handleStamina(pressed))
|
||||
case PlayerMovedRight(pressed) =>
|
||||
props.movementActor ! ImMovementActor.MoveRight(pressed)
|
||||
|
@ -13,14 +13,14 @@ import monix.reactive.Observable
|
||||
import wow.doge.mygame.game.entities.CharacterStats
|
||||
import wow.doge.mygame.game.entities.StatsActor
|
||||
import wow.doge.mygame.game.entities.character.CharacterStates._
|
||||
import wow.doge.mygame.game.entities.player.PlayerActorSupervisor
|
||||
import wow.doge.mygame.game.entities.player.PlayerActor
|
||||
import wow.doge.mygame.implicits._
|
||||
import wow.doge.mygame.subsystems.movement.ImMovementActor
|
||||
|
||||
class IdleBehaviorFactory(
|
||||
env: PlayerActorSupervisor.Env,
|
||||
nextStateFn: AliveSubstate => Behavior[PlayerActorSupervisor.Command],
|
||||
deadState: Behavior[PlayerActorSupervisor.Command],
|
||||
env: PlayerActor.Env,
|
||||
nextStateFn: AliveSubstate => Behavior[PlayerActor.Command],
|
||||
deadState: Behavior[PlayerActor.Command],
|
||||
consumptionMultiplier: Int => Int
|
||||
)(implicit timeout: Timeout) {
|
||||
import IdleBehaviorFactory.IdleBehavior
|
||||
@ -31,23 +31,23 @@ class IdleBehaviorFactory(
|
||||
def behavior =
|
||||
IdleBehavior(
|
||||
Behaviors
|
||||
.receiveMessage[PlayerActorSupervisor.Command] {
|
||||
case PlayerActorSupervisor.MoveLeft(pressed) =>
|
||||
.receiveMessage[PlayerActor.Command] {
|
||||
case PlayerActor.MoveLeft(pressed) =>
|
||||
children.movementActor ! ImMovementActor.MoveLeft(pressed)
|
||||
if (pressed)
|
||||
nextStateFn(AliveSubstate.Moving(Walking))
|
||||
else nextStateFn(AliveSubstate.Idle)
|
||||
case PlayerActorSupervisor.TakeDamage(value, replyTo) =>
|
||||
case PlayerActor.TakeDamage(value, replyTo) =>
|
||||
implicit val ec = props.scheduler.value
|
||||
for {
|
||||
res <-
|
||||
children.statsActor.ask(StatsActor.TakeDamageResult(value, _))
|
||||
_ <- Future.successful(
|
||||
ctx.self ! PlayerActorSupervisor.StatsResponse(res, replyTo)
|
||||
ctx.self ! PlayerActor.StatsResponse(res, replyTo)
|
||||
)
|
||||
} yield ()
|
||||
Behaviors.same
|
||||
case PlayerActorSupervisor.ConsumeStamina(value, replyTo) =>
|
||||
case PlayerActor.ConsumeStamina(value, replyTo) =>
|
||||
implicit val ec = props.scheduler.value
|
||||
val newValue =
|
||||
CharacterStats.DamageStamina(consumptionMultiplier(value.toInt))
|
||||
@ -56,20 +56,20 @@ class IdleBehaviorFactory(
|
||||
StatsActor.ConsumeStaminaResult(newValue, _)
|
||||
)
|
||||
_ =
|
||||
ctx.self ! PlayerActorSupervisor
|
||||
ctx.self ! PlayerActor
|
||||
.StatsResponse(response, replyTo)
|
||||
} yield ()
|
||||
Behaviors.same
|
||||
case PlayerActorSupervisor.CurrentStats(replyTo) =>
|
||||
case PlayerActor.CurrentStats(replyTo) =>
|
||||
children.statsActor ! StatsActor.CurrentStats(replyTo)
|
||||
Behaviors.same
|
||||
case PlayerActorSupervisor.Heal(value) =>
|
||||
case PlayerActor.Heal(value) =>
|
||||
children.statsActor ! StatsActor.HealResult(value)
|
||||
Behaviors.same
|
||||
case PlayerActorSupervisor.GetStatus(replyTo) =>
|
||||
replyTo ! PlayerActorSupervisor.Status.Alive
|
||||
case PlayerActor.GetStatus(replyTo) =>
|
||||
replyTo ! PlayerActor.Status.Alive
|
||||
Behaviors.same
|
||||
case PlayerActorSupervisor.GetStatsObservable(replyTo) =>
|
||||
case PlayerActor.GetStatsObservable(replyTo) =>
|
||||
import monix.{eval => me}
|
||||
replyTo !
|
||||
UIO(
|
||||
@ -82,10 +82,10 @@ class IdleBehaviorFactory(
|
||||
)
|
||||
|
||||
Behaviors.same
|
||||
case PlayerActorSupervisor.StatsResponse(response, replyTo) =>
|
||||
case PlayerActor.StatsResponse(response, replyTo) =>
|
||||
response match {
|
||||
case (dead, stats) =>
|
||||
if (dead) ctx.self ! PlayerActorSupervisor.Die
|
||||
if (dead) ctx.self ! PlayerActor.Die
|
||||
props.statsQueue
|
||||
.offer(stats)
|
||||
.foreach { _ =>
|
||||
@ -95,8 +95,8 @@ class IdleBehaviorFactory(
|
||||
}
|
||||
Behaviors.same
|
||||
// nextStateFn(InCombat(Moving(Walking)))
|
||||
case PlayerActorSupervisor.Die => deadState
|
||||
case PlayerActorSupervisor.LogError(ex) =>
|
||||
case PlayerActor.Die => deadState
|
||||
case PlayerActor.LogError(ex) =>
|
||||
ctx.log.error(ex.getMessage)
|
||||
Behaviors.same
|
||||
}
|
||||
@ -110,6 +110,6 @@ class IdleBehaviorFactory(
|
||||
|
||||
object IdleBehaviorFactory {
|
||||
final case class IdleBehavior(
|
||||
value: Behavior[PlayerActorSupervisor.Command]
|
||||
value: Behavior[PlayerActor.Command]
|
||||
)
|
||||
}
|
||||
|
27
src/test/scala/wow/doge/mygame/WebsocketTest.scala
Normal file
27
src/test/scala/wow/doge/mygame/WebsocketTest.scala
Normal file
@ -0,0 +1,27 @@
|
||||
package wow.doge.mygame
|
||||
|
||||
import sttp.capabilities.monix.MonixStreams
|
||||
import sttp.client3._
|
||||
import sttp.client3.asynchttpclient.monix._
|
||||
|
||||
import monix.eval.Task
|
||||
import monix.reactive.Observable
|
||||
import scala.concurrent.duration.Duration
|
||||
|
||||
class WebsocketTest {
|
||||
// : Task[Response[Either[String, Observable[Array[Byte]]]]]
|
||||
|
||||
val s = AsyncHttpClientMonixBackend().flatMap { backend =>
|
||||
val response =
|
||||
basicRequest
|
||||
.post(uri"...")
|
||||
.response(
|
||||
asStream(MonixStreams)(
|
||||
_.doOnNext(i => Task(println(s"$i"))).completedL
|
||||
)
|
||||
)
|
||||
.readTimeout(Duration.Inf)
|
||||
.send(backend)
|
||||
response
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user