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.
171 lines
5.0 KiB
171 lines
5.0 KiB
package wow.doge.mygame.subsystems.movement
|
|
|
|
import akka.actor.typed.Behavior
|
|
import akka.actor.typed.scaladsl.ActorContext
|
|
import akka.actor.typed.scaladsl.Behaviors
|
|
import com.jme3.math.Vector3f
|
|
import com.jme3.renderer.Camera
|
|
import com.softwaremill.quicklens._
|
|
import wow.doge.mygame.game.subsystems.movement.CanMove
|
|
import wow.doge.mygame.implicits._
|
|
import wow.doge.mygame.math.ImVector3f
|
|
import wow.doge.mygame.state.CardinalDirection
|
|
|
|
sealed trait RotateDir
|
|
object RotateDir {
|
|
case object Left extends RotateDir
|
|
case object Right extends RotateDir
|
|
}
|
|
|
|
object ImMovementActor {
|
|
sealed trait Command
|
|
// final case class Tick(tpf: Float) extends Command
|
|
final case object Tick extends Command
|
|
|
|
sealed trait Movement extends Command
|
|
final case class MovedLeft(pressed: Boolean) extends Movement
|
|
final case class MovedUp(pressed: Boolean) extends Movement
|
|
final case class MovedRight(pressed: Boolean) extends Movement
|
|
final case class MovedDown(pressed: Boolean) extends Movement
|
|
final case object Jump extends Movement
|
|
// final case object RotateRight extends Movement
|
|
// final case object RotateLeft extends Movement
|
|
|
|
final class Props[T: CanMove](
|
|
val enqueueR: Function1[() => Unit, Unit],
|
|
val movable: T,
|
|
// playerMovementEventBus: ActorRef[
|
|
// EventBus.Command[PlayerMovementEvent]
|
|
// ]
|
|
val camera: Camera
|
|
) {
|
|
def behavior: Behavior[Command] =
|
|
Behaviors.setup(ctx => new ImMovementActor(ctx, this).receive(State()))
|
|
}
|
|
|
|
/**
|
|
* Internal state of the actor
|
|
*
|
|
* @param cardinalDir The four directions the character can move
|
|
*/
|
|
final case class State(cardinalDir: CardinalDirection = CardinalDirection())
|
|
|
|
}
|
|
|
|
class ImMovementActor[T](
|
|
ctx: ActorContext[ImMovementActor.Command],
|
|
props: ImMovementActor.Props[T]
|
|
) {
|
|
import ImMovementActor._
|
|
import Methods._
|
|
|
|
def receive(
|
|
state: ImMovementActor.State
|
|
)(implicit cm: CanMove[T]): Behavior[Command] =
|
|
Behaviors.receiveMessage {
|
|
case m: Movement =>
|
|
m match {
|
|
case MovedLeft(pressed) =>
|
|
props.enqueueR(() => stopIfNotPressed(pressed, props.movable))
|
|
receive(state = state.modify(_.cardinalDir.left).setTo(pressed))
|
|
case MovedUp(pressed) =>
|
|
props.enqueueR(() => stopIfNotPressed(pressed, props.movable))
|
|
receive(state = state.modify(_.cardinalDir.up).setTo(pressed))
|
|
case MovedRight(pressed) =>
|
|
props.enqueueR(() => stopIfNotPressed(pressed, props.movable))
|
|
receive(state = state.modify(_.cardinalDir.right).setTo(pressed))
|
|
case MovedDown(pressed) =>
|
|
props.enqueueR(() => stopIfNotPressed(pressed, props.movable))
|
|
receive(state = state.modify(_.cardinalDir.down).setTo(pressed))
|
|
case Jump =>
|
|
props.enqueueR(() => cm.jump(props.movable))
|
|
Behaviors.same
|
|
}
|
|
|
|
case Tick =>
|
|
val walkDir =
|
|
getDirection2(state.cardinalDir, ctx.log.trace)
|
|
// if (walkDir != ImVector3f.ZERO) {
|
|
val tmp = walkDir * 25f * (1f / 144)
|
|
props.enqueueR { () =>
|
|
cm.move(props.movable, tmp)
|
|
}
|
|
// }
|
|
Behaviors.same
|
|
}
|
|
|
|
def getDirection2(cardinalDir: CardinalDirection, debug: String => Unit) = {
|
|
val camDir =
|
|
props.camera.getDirection().clone().normalizeLocal.multLocal(0.6f)
|
|
val camLeft = props.camera.getLeft().clone().normalizeLocal.multLocal(0.4f)
|
|
val dir = cardinalDir
|
|
val walkDir = {
|
|
val mutWalkDir = new Vector3f()
|
|
if (dir.up) {
|
|
debug("up")
|
|
mutWalkDir += camDir
|
|
}
|
|
if (dir.left) {
|
|
debug("left")
|
|
mutWalkDir += camLeft
|
|
}
|
|
if (dir.right) {
|
|
debug("right")
|
|
mutWalkDir += -camLeft
|
|
}
|
|
if (dir.down) {
|
|
debug("down")
|
|
mutWalkDir += -camDir
|
|
}
|
|
mutWalkDir.immutable
|
|
}
|
|
walkDir
|
|
}
|
|
}
|
|
object Methods {
|
|
def getDirection(cardinalDir: CardinalDirection, trace: String => Unit) = {
|
|
val zero = ImVector3f.ZERO
|
|
val dir = cardinalDir
|
|
val walkDir = {
|
|
val mutWalkDir = new Vector3f()
|
|
if (dir.left) {
|
|
trace("left")
|
|
mutWalkDir += zero +=: new Vector3f(-1, 0, 0)
|
|
}
|
|
if (dir.right) {
|
|
trace("right")
|
|
mutWalkDir += zero +=: new Vector3f(1, 0, 0)
|
|
}
|
|
if (dir.up) {
|
|
trace("up")
|
|
mutWalkDir += zero +=: new Vector3f(0, 0, -1)
|
|
}
|
|
if (dir.down) {
|
|
trace("down")
|
|
mutWalkDir += zero +=: new Vector3f(0, 0, 1)
|
|
}
|
|
mutWalkDir.immutable
|
|
}
|
|
walkDir
|
|
}
|
|
|
|
def stopIfNotPressed[T](pressed: Boolean, movable: T)(implicit
|
|
cm: CanMove[T]
|
|
) =
|
|
if (!pressed) cm.stop(movable)
|
|
}
|
|
|
|
// props.app
|
|
// .enqueueScala { () =>
|
|
// 1
|
|
// }
|
|
// .map(println)(scala.concurrent.ExecutionContext.global)
|
|
// monix.eval.Task
|
|
// .fromFuture(
|
|
// props.app
|
|
// .enqueueScala { () =>
|
|
// 1
|
|
// }
|
|
// )
|
|
// .flatMap(i => monix.eval.Task(println(i)))
|
|
// .runToFuture(monix.execution.Scheduler.Implicits.global)
|