Created
October 16, 2014 19:51
-
-
Save bartosz-witkowski/eb359d51852015a1f281 to your computer and use it in GitHub Desktop.
"Entity component system" with type classes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
case class Map( | |
// in real code use something that has better copy characteristics like some tree | |
walls: List[Wall], | |
boundaries: MapBoundaries) | |
case class World( | |
player: PlayerCharacter, | |
map: Map, | |
enemies: List[Enemy]) | |
case class BoundingBox(x: Int, y: Int, width: Int, height: Int) | |
trait HasBoundingBox[T] { | |
def bbox(t: T): BoundingBox | |
} | |
trait Movable[T] { | |
def move(t: T, dx: Int, dy: Int): T | |
} | |
trait PlayerOwned[T] { | |
def react(t: T, input: PlayerInput): T | |
} | |
trait Renderable[T] { | |
def render(t: T): Unit // or IO[Unit] if you want to | |
} | |
trait AiControlled[T] { | |
def takeAction(t: T): T | |
} | |
case class PlayerCharacter(x: Int, y: Int) | |
object PlayerCharacter extends PlayerCharacterInstances | |
trait PlayerCharacterInstances { | |
val PlayerSize = 10 | |
implicit val instance = new HasBoundingBox[Player] with Movable[Player] with PlayerOwned[Player] with Renderable[Player] { | |
override def bbox(player: Player): BoundingBox = | |
BoundingBox(player.x - (PlayerSize / 2), player.y - (PlayerSize/ 2), PlayerSize, PlayerSize) | |
override def move(player: Player, dx: Int, dy: Int): Player = { | |
// for more complicated objects and logics look at lenses / monocle project | |
Player.copy(x = x + dx, y = y + dy) | |
} | |
override def render(player: Player): Unit = { | |
println(s"rendering: ${player}") | |
} | |
override def react(t: T, input: PlayerInput) | |
} | |
} | |
case class Wall(x1: Int, y1: Int, x2: Int, y2: Int) | |
object Wall extends WallInstances | |
trait WallInstances { | |
implicit val instance = new HasBoundingBox[Wall] with Movable[Wall] with Renderable[Wall] { | |
// blah | |
} | |
} | |
case class MapBoundaries(path: Path) | |
object MapBoundaries extends MapBoundariesInstances | |
trait MapBoundariesInstances { | |
implicit val instance = new HasBoundingBox[Wall] { | |
// blah | |
} | |
} | |
case class Enemy(x: Int, y: Int, hp: Int) | |
object Enemy extends EnemyInstances | |
trait EnemyInstances { | |
implicit val instance = new HasBoundingBox[Enemy] with Movable[Enemy] with AiControlled[Enemy] with Renderable[Enemy] { | |
// blah | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment