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.
|
|
package wow.doge.mygame.game.entities
import akka.actor.typed.ActorRef import akka.actor.typed.Behavior import akka.actor.typed.scaladsl.ActorContext import akka.actor.typed.scaladsl.Behaviors import io.estatico.newtype.macros.newtype import wow.doge.mygame.game.entities.CharacterStats.HealHealth
case class CharacterStats(hp: CharacterStats.Health, stamina: Int) object CharacterStats { @newtype case class HealHealth(toInt: Int) @newtype case class DamageHealth(toInt: Int) @newtype case class Health(toInt: Int) object Health { implicit class HealthOps(private val h: Health) extends AnyVal { // def +(v: Int): Health = Health(h.toInt + v)
// def -(v: Int): Health = Health(h.toInt - v)
// def *(v: Int): Health = Health(h.toInt * v)
// def /(v: Int): Health = Health(h.toInt / v)
def :+(v: HealHealth): Health = Health(h.toInt + v.toInt) def -(v: DamageHealth): Health = Health(h.toInt - v.toInt) } } @newtype case class HealStamina(toInt: Int) @newtype case class DamageStamina(toInt: Int) @newtype case class Stamina(toInt: Int) object Stamina { implicit class StaminaOps(private val h: Stamina) extends AnyVal { // def +(v: Int): Stamina = Stamina(h.toInt + v)
// def -(v: Int): Stamina = Stamina(h.toInt - v)
// def *(v: Int): Stamina = Stamina(h.toInt * v)
// def /(v: Int): Stamina = Stamina(h.toInt / v)
def :+(v: HealStamina): Stamina = Stamina(h.toInt + v.toInt) def -(v: DamageStamina): Stamina = Stamina(h.toInt - v.toInt) } } // object Stamina {
// implicit class StaminaOps(private val h: Stamina) extends AnyVal {
// def +(v: Health): Stamina = Stamina(h.toInt + v.toInt)
// def -(v: Health): Stamina = Stamina(h.toInt - v.toInt)
// def *(v: Health): Stamina = Stamina(h.toInt * v.toInt)
// def /(v: Health): Stamina = Stamina(h.toInt / v.toInt)
// }
// }
// object Damage {
// implicit class DamageOps(private val h: Damage) extends AnyVal {
// def +(v: Health): Damage = Damage(h.toInt + v.toInt)
// def -(v: Health): Damage = Damage(h.toInt - v.toInt)
// def *(v: Health): Damage = Damage(h.toInt * v.toInt)
// def /(v: Health): Damage = Damage(h.toInt / v.toInt)
// }
// }
}
object StatsActor {
sealed trait Command // case class TakeDamage(value: Int) extends Command
case class TakeDamageResult( value: CharacterStats.DamageHealth, replyTo: ActorRef[(Boolean, CharacterStats)] ) extends Command case class HealResult(value: HealHealth) extends Command case class CurrentStats(replyTo: ActorRef[CharacterStats]) extends Command
class Props( startingHealth: CharacterStats.Health, startingStamina: CharacterStats.Stamina ) { def behavior = Behaviors.setup[Command] { ctx => new StatsActor(ctx, this) .receive( State(CharacterStats(startingHealth, startingStamina.toInt)) ) } }
case class State(stats: CharacterStats) } class StatsActor( ctx: ActorContext[StatsActor.Command], props: StatsActor.Props ) { import StatsActor._ import CharacterStats._ import com.softwaremill.quicklens._ def receive(state: State): Behavior[Command] = Behaviors.receiveMessage[Command] { // Todo add min max values
// case TakeDamage(value) =>
// val nextState =
// if (state.stats.hp - value <= 0)
// state.modify(_.stats.hp).setTo(0)
// else
// state.modify(_.stats.hp).using(_ - value)
// receive(nextState)
case TakeDamageResult(value, replyTo) => val nextState = if ((state.stats.hp - value).toInt <= 0) { replyTo ! true -> state.stats state.modify(_.stats.hp).setTo(Health(0)) } else { replyTo ! false -> state.stats state.modify(_.stats.hp).using(_ - value) } receive(nextState) case HealResult(value) => receive(state.modify(_.stats.hp).using(_ :+ value)) case CurrentStats(replyTo) => replyTo ! state.stats Behaviors.same } }
|