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.
 
 

89 lines
2.5 KiB

package wow.doge.mygame.game.subsystems.level
import cats.effect.Resource
import com.jme3.bullet.control.RigidBodyControl
import com.jme3.light.AmbientLight
import com.jme3.light.DirectionalLight
import com.jme3.scene.Node
import com.jme3.scene.Spatial
import com.softwaremill.tagging._
import monix.bio.IO
import monix.bio.Task
import monix.bio.UIO
import wow.doge.mygame.game.GameAppTags
import wow.doge.mygame.utils.wrappers.jme.AppNode
import wow.doge.mygame.utils.wrappers.jme.AssetManager
import wow.doge.mygame.utils.wrappers.jme.CollisionShapeFactory
import wow.doge.mygame.utils.wrappers.jme.PhysicsSpace
class GameLevel(
val model: Spatial,
val physicsControl: RigidBodyControl,
val ambientLight: AmbientLight,
val directionalLight: DirectionalLight
) {
def addToGame(
rootNode: AppNode[Task] @@ GameAppTags.RootNode,
physicsSpace: PhysicsSpace[Task]
) = {
for {
_ <- rootNode += model
_ <- rootNode += ambientLight
_ <- rootNode += directionalLight
_ <- physicsSpace += model
_ <- physicsSpace += physicsControl
} yield ()
}
def removeFromGame(
rootNode: AppNode[Task] @@ GameAppTags.RootNode,
physicsSpace: PhysicsSpace[Task]
) = {
for {
_ <- rootNode -= model
_ <- rootNode -= ambientLight
_ <- rootNode -= directionalLight
_ <- physicsSpace -= model
_ <- physicsSpace -= physicsControl
} yield ()
}
def resource(
rootNode: AppNode[Task] @@ GameAppTags.RootNode,
physicsSpace: PhysicsSpace[Task]
) =
Resource.make(this.addToGame(rootNode, physicsSpace))(_ =>
this.removeFromGame(rootNode, physicsSpace)
)
}
object GameLevel {
sealed trait Error
case class AssetLoadError(err: AssetManager.Error) extends Error
case class CollisionShapeCreationFailed(err: CollisionShapeFactory.Error)
extends Error
def apply(
modelPath: os.RelPath,
al: AmbientLight,
dl: DirectionalLight
)(implicit
assetManager: wow.doge.mygame.utils.wrappers.jme.AssetManager
): IO[Error, GameLevel] =
for {
sceneModel <-
assetManager
.loadModelAs[Node](modelPath)
.mapError(AssetLoadError)
sceneShape <-
CollisionShapeFactory
.createMeshShape(sceneModel)
.mapError(CollisionShapeCreationFailed)
landscape <- UIO(new RigidBodyControl(sceneShape, 0))
} yield new GameLevel(
model = sceneModel,
physicsControl = landscape,
ambientLight = al,
directionalLight = dl
)
}