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.
 
 

151 lines
4.5 KiB

package wow.doge.mygame.game.entities
import akka.actor.typed.ActorRef
import akka.actor.typed.DispatcherSelector
import com.jme3.bullet.control.BetterCharacterControl
import com.jme3.renderer.Camera
import com.jme3.scene.CameraNode
import com.jme3.scene.Geometry
import com.jme3.scene.Node
import com.jme3.scene.Spatial
import com.jme3.scene.shape.Box
import com.softwaremill.tagging._
import io.odin.Logger
import monix.bio.IO
import monix.bio.Task
import wow.doge.mygame.AppError
import wow.doge.mygame.executors.Schedulers.AsyncScheduler
import wow.doge.mygame.game.GameApp
import wow.doge.mygame.implicits._
import wow.doge.mygame.math.ImVector3f
import wow.doge.mygame.subsystems.events.EventsModule.GameEventBus
import wow.doge.mygame.subsystems.events.PlayerEvent
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._
object PlayerController {
sealed trait Error
case class CouldNotCreatePlayerModel(reason: AssetManager.Error) extends Error
object Tags {
sealed trait PlayerNode
sealed trait PlayerCameraNode
sealed trait PlayerCameraPivotNode
}
type PlayerNode = Node @@ Tags.PlayerNode
type PlayerCameraNode = CameraNode @@ Tags.PlayerCameraNode
type PlayerCameraPivotNode =
Node @@ Tags.PlayerCameraPivotNode
class Props(
gameApp: GameApp,
enqueueR: Function1[() => Unit, Unit],
rootNode: RootNode,
loggerL: Logger[Task],
physicsSpace: PhysicsSpace,
initialPlayerPos: ImVector3f,
playerEventBus: GameEventBus[PlayerEvent],
playerPhysicsControl: BetterCharacterControl,
// appScheduler: monix.execution.Scheduler,
scheduler: AsyncScheduler,
playerNode: PlayerNode,
cameraNode: PlayerCameraNode,
cameraPivotNode: PlayerCameraPivotNode,
tickEventBus: GameEventBus[TickEvent],
camera: Camera
) {
val playerActorBehavior = {
val movementActorBeh = new ImMovementActor.Props(
enqueueR,
camera
).behavior(playerPhysicsControl)
new PlayerActorSupervisor.Props(
playerEventBus,
tickEventBus,
movementActorBeh,
scheduler
).behavior
}
val playerActor =
gameApp.spawnGameActor(
playerActorBehavior,
// Some("playerActorSupervisor"),
props = DispatcherSelector.default()
)
val create: IO[AppError, ActorRef[PlayerActorSupervisor.Command]] =
(for {
// playerActor <-
// // AkkaUtils.spawnActorL(playerActorBehavior, "playerActorSupervisor")
// gameApp.spawnGameActor(
// playerActorBehavior,
// Some("playerActorSupervisor"),
// props = DispatcherSelector.default()
// )
pa <- playerActor
_ <- (for {
_ <- rootNode += playerNode
_ <- physicsSpace += playerNode
_ <- physicsSpace += playerPhysicsControl
_ = cameraPivotNode += cameraNode
_ <- rootNode += cameraPivotNode
} yield ()).mapError(AppError.AppNodeError)
} yield pa)
}
object Defaults {
def defaultMesh = {
val b = Box(1, 1, 1)
val geom = Geometry("playerGeom", b)
geom
}
def defaultCamerNode(
cam: Camera,
// playerNode: Node,
// cameraPivotNode: Node,
playerPos: ImVector3f
) =
new CameraNode("CameraNode", cam)
// .withControlDir(ControlDirection.SpatialToCamera)
.withLocalTranslation(ImVector3f(0, 1.5f, 10))
.withLookAt(playerPos, ImVector3f.UnitY)
def defaultPlayerNode(
playerPos: ImVector3f,
playerModel: Node,
// camNode: CameraNode,
playerPhysicsControl: BetterCharacterControl
) =
Node("PlayerNode")
.withChildren(playerModel)
.withLocalTranslation(playerPos)
.withControl(playerPhysicsControl)
.taggedWith[Tags.PlayerNode]
def defaultNpcNode(
// assetManager: AssetManager,
npcModel: Spatial,
initialPos: ImVector3f,
npcPhysicsControl: BetterCharacterControl,
npcName: String
) =
// Either
// .catchNonFatal(
Node(npcName)
.withChildren(
// defaultMesh.withMaterial(defaultTexture(assetManager))
npcModel
)
.withLocalTranslation(initialPos)
.withControl(npcPhysicsControl)
// )
def defaultPlayerPhysicsControl =
new BetterCharacterControl(1.5f, 6f, 1f)
.withJumpForce(ImVector3f(0, 5f, 0))
}
}