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

4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
  1. package wow.doge.mygame.game.subsystems.level
  2. import cats.effect.Resource
  3. import com.jme3.bullet.control.RigidBodyControl
  4. import com.jme3.light.AmbientLight
  5. import com.jme3.light.DirectionalLight
  6. import com.jme3.scene.Node
  7. import com.jme3.scene.Spatial
  8. import com.softwaremill.tagging._
  9. import monix.bio.IO
  10. import monix.bio.Task
  11. import monix.bio.UIO
  12. import wow.doge.mygame.game.GameAppTags
  13. import wow.doge.mygame.utils.wrappers.jme.AppNode
  14. import wow.doge.mygame.utils.wrappers.jme.AssetManager
  15. import wow.doge.mygame.utils.wrappers.jme.CollisionShapeFactory
  16. import wow.doge.mygame.utils.wrappers.jme.PhysicsSpace
  17. class GameLevel(
  18. val model: Spatial,
  19. val physicsControl: RigidBodyControl,
  20. val ambientLight: AmbientLight,
  21. val directionalLight: DirectionalLight
  22. ) {
  23. def addToGame(
  24. rootNode: AppNode[Task] @@ GameAppTags.RootNode,
  25. physicsSpace: PhysicsSpace[Task]
  26. ) = {
  27. for {
  28. _ <- rootNode += model
  29. _ <- rootNode += ambientLight
  30. _ <- rootNode += directionalLight
  31. _ <- physicsSpace += model
  32. _ <- physicsSpace += physicsControl
  33. } yield ()
  34. }
  35. def removeFromGame(
  36. rootNode: AppNode[Task] @@ GameAppTags.RootNode,
  37. physicsSpace: PhysicsSpace[Task]
  38. ) = {
  39. for {
  40. _ <- rootNode -= model
  41. _ <- rootNode -= ambientLight
  42. _ <- rootNode -= directionalLight
  43. _ <- physicsSpace -= model
  44. _ <- physicsSpace -= physicsControl
  45. } yield ()
  46. }
  47. def resource(
  48. rootNode: AppNode[Task] @@ GameAppTags.RootNode,
  49. physicsSpace: PhysicsSpace[Task]
  50. ) =
  51. Resource.make(this.addToGame(rootNode, physicsSpace))(_ =>
  52. this.removeFromGame(rootNode, physicsSpace)
  53. )
  54. }
  55. object GameLevel {
  56. sealed trait Error
  57. case class AssetLoadError(err: AssetManager.Error) extends Error
  58. case class CollisionShapeCreationFailed(err: CollisionShapeFactory.Error)
  59. extends Error
  60. def apply(
  61. modelPath: os.RelPath,
  62. al: AmbientLight,
  63. dl: DirectionalLight
  64. )(implicit
  65. assetManager: wow.doge.mygame.utils.wrappers.jme.AssetManager
  66. ): IO[Error, GameLevel] =
  67. for {
  68. sceneModel <-
  69. assetManager
  70. .loadModelAs[Node](modelPath)
  71. .mapError(AssetLoadError)
  72. sceneShape <-
  73. CollisionShapeFactory
  74. .createMeshShape(sceneModel)
  75. .mapError(CollisionShapeCreationFailed)
  76. landscape <- UIO(new RigidBodyControl(sceneShape, 0))
  77. } yield new GameLevel(
  78. model = sceneModel,
  79. physicsControl = landscape,
  80. ambientLight = al,
  81. directionalLight = dl
  82. )
  83. }