summaryrefslogtreecommitdiff
path: root/src/systems/collision.js
blob: 0070ee73ec4ee20c14c1173f309df3677a1d7132 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
game.system.Collision = (entitiesGrid) => {
  const update = (elapsedTime, entities, changedIds) => {
    const thisChangedIds = new Set();
    for (let entity of Object.keys(entities).map((id) => entities[id])) {
      if (entity.hasComponent("controllable") && entity.hasComponent("gridPosition") && entity.hasComponent("momentum")) {
        const momentum = unitize(entity.components.momentum);

        let found;
        const proposed = {x: entity.components.gridPosition.x + momentum.dx, y: entity.components.gridPosition.y + momentum.dy};
        const entitiesToPush = [];
        let wall = false;
        do {
          const proposedClampedInBounds = clamp(proposed, game.config.xDim-1, game.config.yDim-1);
          if (!equivalence(proposed, proposedClampedInBounds)) {
            break;
          }

          found = false;

          const entitiesInCell = entitiesGrid[proposed.y][proposed.x];

          for (let next of entitiesInCell.values()) {
            if (next.hasComponent("stop")) {
              wall = next;
              found = false;
              break;
            }
            if (next.hasComponent("pushable")) {
              entitiesToPush.push(next);
              found = true;
            }
          }

          proposed.x += momentum.dx;
          proposed.y += momentum.dy;
        } while(found);

        if (wall) {
          entity.removeComponent("momentum");
        } else {
          entitiesToPush.map((e) => {
            const pushedParticleSpawner = game.createBorderParticles();
            pushedParticleSpawner.addComponent(game.components.Position(e.components.position));
            pushedParticleSpawner.addComponent(game.components.Appearance({width: game.canvas.width / game.config.xDim, height: game.canvas.height / game.config.yDim}));
            game.entities[pushedParticleSpawner.id] = pushedParticleSpawner;

            e.addComponent(game.components.Momentum({...momentum}))
          });
        }
      }
    }
    return thisChangedIds;
  };
  return { update };
};