I think the big drawback to using an entity component system is that it takes a lot of boilerplate to get a project up and running. So, I also have a command line tool to help me with that, entitas-cli. Entitas-cli requires nodejs, and uses Liquid templates to generate code from a json configuration file.
To install entitas-cli: 'npm install -g entitas-cli'
I will need an existing project, so using the tutorial at https://www.scala-js.org/tutorial/basic/, I've created a basic HelloWorld application. I only followed the first three steps, and then I add my dependencies, so now my build.sbt looks like this:
scalaJSUseRhino in Global := false
enablePlugins(ScalaJSPlugin)
name := "Scala.js Tutorial"
scalaVersion := "2.11.7" // or any other Scala version >= 2.10.2
libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "0.9.0"
libraryDependencies += "com.darkoverlordofdata" %%% "entitas" % "0.0.0-SNAPSHOT"
resolvers += "Artifactory" at "https://oss.jfrog.org/artifactory/oss-snapshot-local/"
libraryDependencies += "co.technius.scalajs-pixi" %%% "core" % "0.0.1-SNAPSHOT"
jsDependencies += "org.webjars" % "pixi.js" % "3.0.7" / "pixi.js"
jsDependencies += RuntimeDOM
skip in packageJSDependencies := false
persistLauncher in Compile := true
I'll have to reload my sbt configuration. So while it's doing that, I open another terminal window in the project root, and type the following commands :
entitas init helloworld
entitas create -c Destroy
entitas create -c Player
entitas create -c Position x:Float y:Float
entitas create -c Velocity x:Float y:Float
entitas create -c View sprite:co.technius.scalajs.pixi.Sprite
entitas create -s Destroy IExecuteSystem
entitas create -s Physics IExecuteSystem
entitas create -s Render IInitializeSystem IExecuteSystem
{
"namespace": "helloworld",
"src": "lib/src",
"output": {
"javascript": "web/src/helloworld/generatedExtensions.js",
"typescript": "lib/src/generatedComponents.ts",
"declaration": "lib/ext/helloworld.d.ts"
},
...}
These defaults are for a typescript project, so I make the following changes for scala:
"namespace": "tutorial.webapp",
"src": "src/main/scala",
"output": {
"generated": "components.scala"
},
entitas generate -p scala mutable=var
I also need some assets. I've downloaded Kenney's SpaceShooterRedux package from http://opengameart.org/content/space-shooter-redux
The main TutorialApp class should load the assets and start the game loop:
package tutorial.webapp
import co.technius.scalajs.pixi.Container
import co.technius.scalajs.pixi.Pixi
import co.technius.scalajs.pixi.loaders.{ResourceDictionary, Loader}
import com.darkoverlordofdata.entitas.{Systems, Pool}
import tutorial.webapp.systems._
import org.scalajs.dom.document
import org.scalajs.dom.window
import scala.scalajs.js.JSApp
object TutorialApp extends JSApp {
lazy val width = window.innerWidth
lazy val height = window.innerHeight
lazy val renderer = Pixi.autoDetectRenderer(width, height)
lazy val stage = new Container
lazy val pool: Pool = { new Pool(Component.TotalComponents.id) }
lazy val systems: Systems = { new Systems() }
def main(): Unit = {
Pixi.loader
.add("black", "images/black.png")
.add("ship", "images/ship.png")
.load(loaded)
document.body.appendChild(renderer.view)
window.requestAnimationFrame(render)
}
lazy val loaded = (loader:Loader, res:ResourceDictionary) => {
systems
.add(pool.createSystem(new RenderSystem(pool)))
.add(pool.createSystem(new PhysicsSystem(pool)))
.add(pool.createSystem(new DestroySystem(pool)))
systems.initialize()
}
lazy val render: (Double) => Unit = { time =>
systems.execute()
window.requestAnimationFrame(render)
}
}
Now I just need to fill in the systems and create entities. The full version is here
https://github.com/darkoverlordofdata/invaders-scala-js
Try it live here, at https://darkoverlordofdata.com/invaders-scala-js. Be kind, it is just started.