summaryrefslogtreecommitdiff
path: root/src/engine/entities/Piston.ts
blob: 18b761bcbda5148e1313e607db8864f993294d27 (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
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 + .001;
    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);
  }
}