FreshRSS

Zobrazení pro čtení

Jsou dostupné nové články, klikněte pro obnovení stránky.

Is it a bad idea to store functions inside components in ECS?

Say I have three entities: Player, Spikes, and Zombie. All of them are just rectangles and they can collide with each other. All of them have the BoxCollision component.

So, the BoxCollison system would look something like this:

function detectCollisions () {
  // for each entity with box collision
    // check if they collide
      // then do something
}

The issue is, the sole purpose of the BoxCollision component is to detect collision, and that's it. Where should I put the game rules, such as "if the Player collided with Spikes, diminish its health" or "if the Zombie collided with Spikes, instantly kill the Zombie"?

I came up with the idea that each Entity should have its onCollision function.

Programming languages such as Javascript and F# have high-order functions, so I can easily pass functions around. So when assembling my Player entity, I could do something like:

function onPlayerCollision (player) {
  return function (entity) {
    if (entity.tag === 'Zombie') {
      player.getComponent('Health').hp -= 1
    } else if (entity.tag === 'Spikes') {
      player.getComponent('Health').hp -= 5
    }
  }
}

const player = new Entity()
player.addComponent('Health', { hp: 100 })
player.addComponent('BoxCollision', { onCollision: onPlayerCollision(player) } 
// notice I store a reference to a function here, so now the BoxCollision component will execute this passing the entity the player has collided with
function detectCollisions () {
  // for each entity with box collision
    // check if they collide
      onCollision(entity)

onPlayerCollision is a curried/closure function that receives a player, and then returns a new function that wants another Entity.

Are there any flaws with this? Is it okay for components to store references to functions? What are other ways of avoiding game rules in components? Events?

Thanks!

❌