Hi,
I think, you will need to deviate quite a lot from a typical way this would 
be structured in an OOP language. It is also woth noting that for a 2D 
physics-based game, immutable data structures will incur performance 
penalties that may not be acceptable if your game is more demanding. 
Remember that you can only store the actual entities in a single structure: 
the only way to have an entity list AND a quad tree is to store some 
integer IDs of the entities in the quad tree, but then working with the 
quad tree involves an ID lookup, which may be expensive-ish (hashtables 
cannot be efficiently implemented as immutable data structures, so Elm 
falls back to trees). Pure languages such as Elm do not have pointers. It 
may well turn out that it is faster to check collisions naively than to 
maintain a quad tree.

Nevertheless, I think 2D game is an interesting project to start with and 
it will teach you a lot of how Elm work and you will also get some intution 
on what is hard vs. what is easy in Elm (which differs a lot from what is 
easy/hard in OOP).

With that cleared, the way I would do it (which may not be the best, I 
consider myself an Elm beginner, but I tried to do a game in Elm ;-) would 
be to have separate data structures for various aspects of the entities:
type alias CollisionData =
  {x: Float, y: Float, radius: float}

type alias AIData =
  {targetEntityId: Int, ... }

then compose them to form data for the actual entity types:
type alias EnemyData =
  { id: Int, collision: CollisionData, ai: AIData, ... }

type alias ObstacleData =
  { id: Int, collision: CollisionData, ... }

then you have a union type for a game entity
type GameEntity 
  = Enemy EnemyData 
  | Obstacle ObstacleData 
  | ...

now your update logic would look like:
updateCollisions : CollisionData -> CollisionData
updateCollisions collision = 
  yourCodeHere

updateAI : AIData -> AIData
updateAI ai =
  moreCodeHere

updateEnemy : EnemyData -> EnemyData
updateEnemy enemy =
  { enemy 
    | collision = updateCollisions enemy.collision
    , ai = updateAI enemy.ai
    , ...
  }

updateEntity : GameEntity -> GameEntity
updateEntity entity =
  case entity of
    Enemy enemyData -> Enemy (updateEnemy enemyData)
    Obstacle obstacleData -> Obstacle (updateObstacle obstacleData)
    ...


I think this is only slightly more boilerplate than what you would write in 
an OOP language...

Does this answer your question?

Best
Martin

On Monday, 2 January 2017 20:58:29 UTC+1, Yoav Luft wrote:
>
> Hello Elm people!
>
> I'm making a 2D video game to familiarize myself with Elm and I have a 
> design issue I would like to hear your advice on.
>
> In my game I have different UI entities with different behaviours, for 
> example:
>
>    - Some are collidable with the player / other entities, but other are 
>    not.
>    - Some move in the game world while other not (the view port might 
>    change, but their game world position does not).
>    - Some have AI logic that controls how they move, others are dumb.
>    - Some interact with the mouse cursor while others do not.
>
> I'm not sure how to model the different entities. In OOP scenario I would 
> use a hierarchy of types and mixin types. In Aspect oriented programming I 
> would compose them from different aspects. I'm not sure what I should do in 
> Elm.
>
> I have some constraints, for example, I need to hold all entities (accept, 
> maybe, background entities without any interaction at all) in one data 
> structure that will make collision detection easy, like a quadtree. They 
> all need to be rendered when they are in the view port. I might need to 
> implement some kind of path-finding algorithm.
>
>
> I tried using this syntax:
>
> type alias Positioned a =
>   { a | x : Float, y : Float }
>
> But I can't make a List or Tree of "Positioned a" and then pattern match 
> on "a". Or at least, if I can I couldn't figure out a way to make it work.
>
>
> Any suggestions would be appreciated!
>
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to