diff options
author | Elizabeth Hunt <elizabeth.hunt@simponic.xyz> | 2024-03-02 01:07:55 -0700 |
---|---|---|
committer | Elizabeth Hunt <elizabeth.hunt@simponic.xyz> | 2024-03-02 01:07:55 -0700 |
commit | 1ec5a8d088f599d094f387abc6014f228607b605 (patch) | |
tree | 0d0e0271b6d5db354a56337c5de9df1a933e767b /src/engine/systems/Grid.ts | |
parent | a333ce8845de4269d6a6f5523d2273da11fe271c (diff) | |
download | the-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.ts | 149 |
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); }); } } |