summaryrefslogtreecommitdiff
path: root/src/engine/systems/Grid.ts
diff options
context:
space:
mode:
authorElizabeth Hunt <elizabeth.hunt@simponic.xyz>2024-03-02 01:07:55 -0700
committerElizabeth Hunt <elizabeth.hunt@simponic.xyz>2024-03-02 01:07:55 -0700
commit1ec5a8d088f599d094f387abc6014f228607b605 (patch)
tree0d0e0271b6d5db354a56337c5de9df1a933e767b /src/engine/systems/Grid.ts
parenta333ce8845de4269d6a6f5523d2273da11fe271c (diff)
downloadthe-abstraction-engine-1ec5a8d088f599d094f387abc6014f228607b605.tar.gz
the-abstraction-engine-1ec5a8d088f599d094f387abc6014f228607b605.zip
add interactable component
Diffstat (limited to 'src/engine/systems/Grid.ts')
-rw-r--r--src/engine/systems/Grid.ts149
1 files changed, 130 insertions, 19 deletions
diff --git a/src/engine/systems/Grid.ts b/src/engine/systems/Grid.ts
index 0869fd6..c9cab6b 100644
--- a/src/engine/systems/Grid.ts
+++ b/src/engine/systems/Grid.ts
@@ -1,9 +1,12 @@
import { System, SystemNames } from ".";
import { Game } from "..";
+import { Entity } from "../entities";
import { PhysicsConstants } from "../config";
import {
BoundingBox,
ComponentNames,
+ FacingDirection,
+ Highlight,
Grid as GridComponent,
} from "../components";
import { Coord2D, Direction, Dimension2D } from "../interfaces";
@@ -28,9 +31,109 @@ export class Grid extends System {
public update(dt: number, game: Game) {
this.putUninitializedEntitiesInGrid(game);
this.rebuildGrid(game);
+
+ this.highlightEntitiesLookedAt(game);
+ this.propogateEntityMovements(game);
+
this.updateMovingEntities(dt, game);
}
+ private highlightEntitiesLookedAt(game: Game) {
+ const highlightableEntities = new Set<string>();
+
+ game.forEachEntityWithComponent(
+ ComponentNames.FacingDirection,
+ (entity) => {
+ if (!entity.hasComponent(ComponentNames.Grid)) {
+ return;
+ }
+
+ const grid = entity.getComponent<GridComponent>(ComponentNames.Grid)!;
+ const facingDirection = entity.getComponent<FacingDirection>(
+ ComponentNames.FacingDirection,
+ )!;
+ const lookingAt = this.getNewGridPosition(
+ grid.gridPosition,
+ facingDirection.currentDirection,
+ );
+ if (
+ facingDirection.currentDirection === Direction.NONE ||
+ this.isOutOfBounds(lookingAt)
+ ) {
+ return;
+ }
+
+ this.grid[lookingAt.y][lookingAt.x].forEach((id) => {
+ highlightableEntities.add(id);
+ });
+ },
+ );
+
+ highlightableEntities.forEach((id) => {
+ const entity = game.getEntity(id)!;
+ if (!entity.hasComponent(ComponentNames.Highlight)) {
+ entity.addComponent(new Highlight());
+ }
+ });
+
+ game.forEachEntityWithComponent(ComponentNames.Highlight, (entity) => {
+ if (!highlightableEntities.has(entity.id)) {
+ entity.removeComponent(ComponentNames.Highlight);
+ }
+ });
+ }
+
+ private propogateEntityMovements(game: Game) {
+ const movingEntities: Entity[] = [];
+ game.forEachEntityWithComponent(ComponentNames.Grid, (entity) => {
+ const grid = entity.getComponent<GridComponent>(ComponentNames.Grid)!;
+ if (grid.movingDirection !== Direction.NONE) {
+ movingEntities.push(entity);
+ }
+ });
+
+ // for each moving entity, check the entities in the grid cell it's moving to
+ // if they are pushable, move them in the same direction
+ // continue until no more pushable entities are found
+ for (const entity of movingEntities) {
+ const grid = entity.getComponent<GridComponent>(ComponentNames.Grid)!;
+ let nextGridPosition = this.getNewGridPosition(
+ grid.gridPosition,
+ grid.movingDirection,
+ );
+ while (!this.isOutOfBounds(nextGridPosition)) {
+ const { x, y } = nextGridPosition;
+ const entities = Array.from(this.grid[y][x]).map(
+ (id) => game.getEntity(id)!,
+ );
+
+ const pushableEntities = entities.filter((entity) => {
+ if (!entity.hasComponent(ComponentNames.Grid)) return false;
+
+ const { pushable, movingDirection } =
+ entity.getComponent<GridComponent>(ComponentNames.Grid)!;
+ return movingDirection === Direction.NONE && pushable;
+ });
+ if (pushableEntities.length === 0) {
+ break;
+ }
+
+ for (const pushableEntity of pushableEntities) {
+ const pushableGrid = pushableEntity.getComponent<GridComponent>(
+ ComponentNames.Grid,
+ )!;
+ pushableGrid.movingDirection = grid.movingDirection;
+ pushableEntity.addComponent(pushableEntity);
+ }
+
+ nextGridPosition = this.getNewGridPosition(
+ nextGridPosition,
+ grid.movingDirection,
+ );
+ }
+ }
+ }
+
private putUninitializedEntitiesInGrid(game: Game) {
game.forEachEntityWithComponent(ComponentNames.Grid, (entity) => {
const grid = entity.getComponent<GridComponent>(ComponentNames.Grid)!;
@@ -71,23 +174,10 @@ export class Grid extends System {
ComponentNames.BoundingBox,
)!;
- let { x: newX, y: newY } = grid.gridPosition;
- switch (grid.movingDirection) {
- case Direction.LEFT:
- newX -= 1;
- break;
- case Direction.UP:
- newY -= 1;
- break;
- case Direction.DOWN:
- newY += 1;
- break;
- case Direction.RIGHT:
- newX += 1;
- break;
- }
-
- const newGridPosition = { x: newX, y: newY };
+ const newGridPosition = this.getNewGridPosition(
+ grid.gridPosition,
+ grid.movingDirection,
+ );
if (this.isOutOfBounds(newGridPosition)) {
grid.movingDirection = Direction.NONE;
entity.addComponent(grid);
@@ -137,6 +227,26 @@ export class Grid extends System {
});
}
+ private getNewGridPosition(prev: Coord2D, direction: Direction) {
+ let { x: newX, y: newY } = prev;
+ switch (direction) {
+ case Direction.LEFT:
+ newX -= 1;
+ break;
+ case Direction.UP:
+ newY -= 1;
+ break;
+ case Direction.DOWN:
+ newY += 1;
+ break;
+ case Direction.RIGHT:
+ newX += 1;
+ break;
+ }
+
+ return { x: newX, y: newY };
+ }
+
private isEntityPastCenterWhenMoving(
direction: Direction,
gridPosition: Coord2D,
@@ -185,7 +295,7 @@ export class Grid extends System {
this.grid.forEach((row) =>
row.forEach((cell) => {
for (const id of cell) {
- if (!movedEntities.has(id)) {
+ if (movedEntities.has(id)) {
cell.delete(id);
}
}
@@ -194,7 +304,8 @@ export class Grid extends System {
movedEntities.forEach((id) => {
const entity = game.getEntity(id)!;
const grid = entity.getComponent<GridComponent>(ComponentNames.Grid)!;
- this.grid[grid.gridPosition.y][grid.gridPosition.x].add(id);
+ const { x, y } = grid.gridPosition;
+ this.grid[y][x].add(id);
});
}
}