forked from nova/jmonkey-test
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.
220 lines
6.6 KiB
220 lines
6.6 KiB
package wow.doge.mygame.game.nodes
|
|
|
|
import com.jme3.scene.Node
|
|
import com.jme3.scene.CameraNode
|
|
import com.jme3.scene.Geometry
|
|
import com.jme3.renderer.Camera
|
|
import com.jme3.asset.AssetManager
|
|
import wow.doge.mygame.state.MyMaterial
|
|
import com.jme3.scene.control.CameraControl.ControlDirection
|
|
import com.jme3.scene.shape.Box
|
|
import com.jme3.bullet.control.BetterCharacterControl
|
|
import com.jme3.bullet.BulletAppState
|
|
import wow.doge.mygame.game.GameApp
|
|
import wow.doge.mygame.implicits._
|
|
import wow.doge.mygame.math.ImVector3f
|
|
import com.jme3.math.FastMath
|
|
import monix.bio.IO
|
|
import cats.implicits._
|
|
import akka.actor.typed.ActorRef
|
|
import wow.doge.mygame.events.EventBus
|
|
import akka.actor.typed.SpawnProtocol
|
|
import wow.doge.mygame.subsystems.events.EntityMovementEvent.PlayerMovementEvent
|
|
import wow.doge.mygame.subsystems.movement.ImMovementActor
|
|
import io.odin.Logger
|
|
import akka.util.Timeout
|
|
import monix.bio.Task
|
|
import akka.actor.typed.Scheduler
|
|
import akka.actor.typed.Props
|
|
import com.softwaremill.tagging._
|
|
import wow.doge.mygame.subsystems.events.PlayerCameraEvent
|
|
import wow.doge.mygame.utils.AkkaUtils
|
|
|
|
// class PlayerNode(val name: String) extends Node(name) {}
|
|
sealed trait Player
|
|
sealed trait PlayerCameraNode
|
|
|
|
object PlayerController {
|
|
sealed trait Error
|
|
case class GenericError(reason: String) extends Error
|
|
|
|
class Props(
|
|
app: GameApp,
|
|
loggerL: Logger[Task],
|
|
assetManager: AssetManager,
|
|
bulletAppState: BulletAppState,
|
|
initialPlayerPos: ImVector3f = ImVector3f.ZERO,
|
|
modelPath: os.RelPath,
|
|
spawnProtocol: ActorRef[SpawnProtocol.Command],
|
|
playerMovementEventBus: ActorRef[
|
|
EventBus.Command[PlayerMovementEvent]
|
|
],
|
|
playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]],
|
|
_playerPhysicsControl: Option[BetterCharacterControl],
|
|
_playerNode: Option[Node with Player] = None,
|
|
_cameraNode: Option[CameraNode with PlayerCameraNode] = None
|
|
)(implicit timeout: Timeout, scheduler: Scheduler) {
|
|
import Defaults._
|
|
import Methods._
|
|
val create: IO[Error, Unit] =
|
|
// IO.raiseError(GenericError("not implemented yet"))
|
|
(for {
|
|
camNode <- IO(
|
|
_cameraNode.getOrElse(defaultCamerNode(app.camera, initialPlayerPos))
|
|
)
|
|
playerPhysicsControl <- IO(
|
|
_playerPhysicsControl
|
|
.getOrElse(defaultPlayerPhysicsControl)
|
|
.taggedWith[Player]
|
|
)
|
|
playerNode <- IO.fromEither(
|
|
_playerNode.fold(
|
|
defaultPlayerNode(
|
|
assetManager,
|
|
modelPath,
|
|
initialPlayerPos,
|
|
camNode,
|
|
playerPhysicsControl
|
|
)
|
|
)(_.asRight)
|
|
)
|
|
playerActor <- AkkaUtils.spawnActorL(
|
|
spawnProtocol,
|
|
"playerActorSupervisor",
|
|
new PlayerActorSupervisor.Props(
|
|
app,
|
|
camNode,
|
|
playerMovementEventBus,
|
|
playerCameraEventBus
|
|
).create(playerPhysicsControl)
|
|
)
|
|
_ <- IO {
|
|
bulletAppState.physicsSpace += playerNode
|
|
bulletAppState.physicsSpace += playerPhysicsControl
|
|
}
|
|
_ <- IO(app.rootNode += playerNode)
|
|
} yield ())
|
|
.onErrorHandleWith(e => IO.raiseError(GenericError(e.getMessage())))
|
|
.executeOn(app.scheduler)
|
|
|
|
}
|
|
|
|
def apply(
|
|
app: GameApp,
|
|
modelPath: os.RelPath,
|
|
cam: Camera
|
|
)(assetManager: AssetManager, bulletAppState: BulletAppState) = {
|
|
lazy val playerPos = ImVector3f.ZERO
|
|
lazy val playerPhysicsControl = new BetterCharacterControl(1.5f, 6f, 1f)
|
|
.withJumpForce(ImVector3f(0, 5f, 0))
|
|
lazy val playerNode = new Node("PlayerNode")
|
|
.withChildren(
|
|
assetManager
|
|
.loadModel(modelPath)
|
|
.asInstanceOf[Node]
|
|
.withRotate(0, FastMath.PI, 0)
|
|
)
|
|
.withLocalTranslation(playerPos)
|
|
.withControl(playerPhysicsControl)
|
|
|
|
{
|
|
bulletAppState.physicsSpace += playerNode
|
|
bulletAppState.physicsSpace += playerPhysicsControl
|
|
}
|
|
|
|
{
|
|
app.rootNode += playerNode
|
|
}
|
|
|
|
playerPhysicsControl
|
|
}
|
|
}
|
|
|
|
object Defaults {
|
|
lazy val defaultMesh = {
|
|
val b = Box(1, 1, 1)
|
|
val geom = Geometry("playerMesh", b)
|
|
geom
|
|
}
|
|
def defaultTexture(assetManager: AssetManager) =
|
|
MyMaterial(
|
|
assetManager = assetManager,
|
|
path = os.rel / "Common" / "MatDefs" / "Misc" / "Unshaded.j3md"
|
|
)
|
|
|
|
def defaultCamerNode(cam: Camera, playerPos: ImVector3f) =
|
|
new CameraNode("CameraNode", cam)
|
|
.withControlDir(ControlDirection.SpatialToCamera)
|
|
.withLocalTranslation(ImVector3f(0, 1.5f, 10))
|
|
.withLookAt(playerPos, ImVector3f.UNIT_Y)
|
|
|
|
def defaultPlayerNode(
|
|
assetManager: AssetManager,
|
|
modelPath: os.RelPath,
|
|
playerPos: ImVector3f,
|
|
camNode: CameraNode,
|
|
playerPhysicsControl: BetterCharacterControl
|
|
) =
|
|
Either.catchNonFatal(
|
|
Node("PlayerNode")
|
|
.withChildren(
|
|
camNode,
|
|
assetManager
|
|
.loadModel(modelPath)
|
|
.asInstanceOf[Node]
|
|
.withRotate(0, FastMath.PI, 0)
|
|
)
|
|
.withLocalTranslation(playerPos)
|
|
.withControl(playerPhysicsControl)
|
|
)
|
|
|
|
lazy val defaultPlayerPhysicsControl =
|
|
new BetterCharacterControl(1.5f, 6f, 1f)
|
|
.withJumpForce(ImVector3f(0, 5f, 0))
|
|
}
|
|
|
|
object Methods {
|
|
def spawnMovementActor(
|
|
app: GameApp,
|
|
spawnProtocol: ActorRef[SpawnProtocol.Command],
|
|
movable: BetterCharacterControl @@ Player,
|
|
playerMovementEventBus: ActorRef[
|
|
EventBus.Command[PlayerMovementEvent]
|
|
],
|
|
loggerL: Logger[Task]
|
|
)(implicit timeout: Timeout, scheduler: Scheduler) =
|
|
spawnProtocol.askL[ActorRef[ImMovementActor.Command]](
|
|
SpawnProtocol.Spawn(
|
|
ImMovementActor.Props(app, movable, playerMovementEventBus).create,
|
|
"imMovementActor",
|
|
Props.empty,
|
|
_
|
|
)
|
|
)
|
|
// def spawnPlayerActor(
|
|
// app: GameApp,
|
|
// spawnProtocol: ActorRef[SpawnProtocol.Command],
|
|
// movable: BetterCharacterControl @@ Player,
|
|
// playerMovementEventBus: ActorRef[
|
|
// EventBus.Command[PlayerMovementEvent]
|
|
// ]
|
|
// )(implicit timeout: Timeout, scheduler: Scheduler) =
|
|
// spawnProtocol.askL[ActorRef[PlayerActorSupervisor.Command]](
|
|
// SpawnProtocol.Spawn(
|
|
// new PlayerActorSupervisor.Props(
|
|
// app,
|
|
// movable,
|
|
// playerMovementEventBus
|
|
// ).create,
|
|
// "playerActor",
|
|
// Props.empty,
|
|
// _
|
|
// )
|
|
// )
|
|
}
|
|
// spawnPlayerActor(
|
|
// app,
|
|
// spawnProtocol,
|
|
// playerPhysicsControl,
|
|
// playerMovementEventBus
|
|
// )
|