summaryrefslogtreecommitdiff
path: root/src/systems/collision.js
blob: 152dcd62b5ecc63c0eea1282c08504184cdb0aaa (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
56
57
58
59
60
61
62
game.system.Collision = (entitiesGrid) => {
  const update = (elapsedTime, entities, changedIds) => {
    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 particles = game.createBorderParticles({
              colors: ["#16f7c9", "#0d6e5a", "#2fa18a", "#48cfb4", "#58877d", "#178054", "#2cdb92"],
              maxSpeed: 0.20,
              minRadius: 1,
              maxRadius: 3,
              minLife: 100,
              maxLife: 300,
              minAmount: 20,
              maxAmount: 50,
            });
            particles.addComponent(game.components.Position(e.components.position));
            particles.addComponent(game.components.Appearance({width: game.canvas.width / game.config.xDim, height: game.canvas.height / game.config.yDim}));
            game.entities[particles.id] = particles;
            e.addComponent(game.components.Momentum({...momentum}))
          });
        }
      }
    }
    return new Set();
  };
  return { update };
};