summaryrefslogtreecommitdiff
path: root/src/engine/entities/Piston.ts
blob: 214eaac7dd970400a8f0b8695fefe74f0688d4db (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
import { Entity, EntityNames } from ".";
import {
  Colliding,
  ComponentNames,
  FacingDirection,
  Grid,
  RadialObserve,
} from "../components";
import { Game } from "../Game";
import { Coord2D, Direction } from "../interfaces";

export class Piston extends Entity {
  constructor(gridPosition: Coord2D, direction: Direction) {
    super(EntityNames.Piston);

    const radius = 1;
    this.addComponent(new RadialObserve(this.onObservation.bind(this), radius));

    this.addComponent(new FacingDirection(direction));

    this.addComponent(new Grid(gridPosition));

    this.addComponent(new Colliding());
  }

  private onObservation(_game: Game, entity: Entity) {
    const facingDirection = this.getComponent<FacingDirection>(
      ComponentNames.FacingDirection,
    );

    const myPosition = this.getComponent<Grid>(
      ComponentNames.Grid,
    ).gridPosition;
    const observingGrid = entity.getComponent<Grid>(ComponentNames.Grid);
    const observingPosition = observingGrid.gridPosition;

    const [dx, dy] = [
      myPosition.x - observingPosition.x,
      myPosition.y - observingPosition.y,
    ].map((x) => Math.round(x));
    const v: Record<typeof dx, Record<typeof dy, Direction>> = {
      [-1]: {
        [dy]: Direction.RIGHT,
      },
      [1]: {
        [dy]: Direction.LEFT,
      },
      [0]: {
        [-1]: Direction.UP,
        [1]: Direction.DOWN,
      },
    };

    if (facingDirection.currentDirection !== v[dx][dy]) {
      return;
    }

    observingGrid.movingDirection = facingDirection.currentDirection;
    entity.addComponent(observingGrid);
  }
}