diff options
Diffstat (limited to 'src/engine/systems')
-rw-r--r-- | src/engine/systems/FacingDirection.ts | 1 | ||||
-rw-r--r-- | src/engine/systems/Grid.ts | 149 | ||||
-rw-r--r-- | src/engine/systems/Input.ts | 85 | ||||
-rw-r--r-- | src/engine/systems/Render.ts | 4 |
4 files changed, 187 insertions, 52 deletions
diff --git a/src/engine/systems/FacingDirection.ts b/src/engine/systems/FacingDirection.ts index f831bf6..042484a 100644 --- a/src/engine/systems/FacingDirection.ts +++ b/src/engine/systems/FacingDirection.ts @@ -51,6 +51,7 @@ export class FacingDirection extends System { : angleToDirection(angle); facingDirection.setDirection(direction); + entity.addComponent(facingDirection); const oldSprite = entity.getComponent<Sprite>(ComponentNames.Sprite); const sprite = facingDirection.directionSprites.get(direction)!; 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); }); } } diff --git a/src/engine/systems/Input.ts b/src/engine/systems/Input.ts index e9691e0..df4d651 100644 --- a/src/engine/systems/Input.ts +++ b/src/engine/systems/Input.ts @@ -1,6 +1,6 @@ import { SystemNames, System } from "."; import { Game } from ".."; -import { ComponentNames } from "../components"; +import { ComponentNames, Grid, Interactable } from "../components"; import { Control } from "../components/Control"; import { Action, KeyConstants } from "../config"; import { Entity } from "../entities"; @@ -31,11 +31,30 @@ export class Input extends System { public update(_dt: number, game: Game) { game.forEachEntityWithComponent(ComponentNames.Control, (entity) => - this.handleInput(entity), + this.handleMovement(entity), ); + game.forEachEntityWithComponent(ComponentNames.Interactable, (entity) => + this.handleInteraction(entity), + ); + } + + private handleInteraction(entity: Entity) { + const interactable = entity.getComponent<Interactable>( + ComponentNames.Interactable, + ); + + const interact = this.hasSomeKey( + KeyConstants.ActionKeys.get(Action.INTERACT), + ); + + if (!interact) { + return; + } + + interactable.interact(); } - public handleInput(entity: Entity) { + public handleMovement(entity: Entity) { const controlComponent = entity.getComponent<Control>( ComponentNames.Control, ); @@ -50,36 +69,38 @@ export class Input extends System { Action.MOVE_RIGHT, Action.MOVE_DOWN, ].map((action) => this.hasSomeKey(KeyConstants.ActionKeys.get(action))); - if (hasGrid) { - const gridComponent = entity.getComponent(ComponentNames.Grid); - if (gridComponent.movingDirection !== Direction.NONE) { - return; - } - - if (moveUp) { - gridComponent.movingDirection = Direction.UP; - KeyConstants.ActionKeys.get(Action.MOVE_UP)!.forEach((key) => - this.keyReleased(key), - ); - } else if (moveLeft) { - gridComponent.movingDirection = Direction.LEFT; - KeyConstants.ActionKeys.get(Action.MOVE_LEFT)!.forEach((key) => - this.keyReleased(key), - ); - } else if (moveRight) { - gridComponent.movingDirection = Direction.RIGHT; - KeyConstants.ActionKeys.get(Action.MOVE_RIGHT)!.forEach((key) => - this.keyReleased(key), - ); - } else if (moveDown) { - gridComponent.movingDirection = Direction.DOWN; - KeyConstants.ActionKeys.get(Action.MOVE_DOWN)!.forEach((key) => - this.keyReleased(key), - ); - } - - entity.addComponent(gridComponent); + if (!hasGrid) { + return; + } + + const gridComponent = entity.getComponent<Grid>(ComponentNames.Grid)!; + if (gridComponent.movingDirection !== Direction.NONE) { + return; } + + if (moveUp) { + gridComponent.movingDirection = Direction.UP; + KeyConstants.ActionKeys.get(Action.MOVE_UP)!.forEach((key) => + this.keyReleased(key), + ); + } else if (moveLeft) { + gridComponent.movingDirection = Direction.LEFT; + KeyConstants.ActionKeys.get(Action.MOVE_LEFT)!.forEach((key) => + this.keyReleased(key), + ); + } else if (moveRight) { + gridComponent.movingDirection = Direction.RIGHT; + KeyConstants.ActionKeys.get(Action.MOVE_RIGHT)!.forEach((key) => + this.keyReleased(key), + ); + } else if (moveDown) { + gridComponent.movingDirection = Direction.DOWN; + KeyConstants.ActionKeys.get(Action.MOVE_DOWN)!.forEach((key) => + this.keyReleased(key), + ); + } + + entity.addComponent(gridComponent); } private hasSomeKey(keys?: string[]): boolean { diff --git a/src/engine/systems/Render.ts b/src/engine/systems/Render.ts index 6f539c0..7cb5d81 100644 --- a/src/engine/systems/Render.ts +++ b/src/engine/systems/Render.ts @@ -2,6 +2,7 @@ import { System, SystemNames } from "."; import { BoundingBox, ComponentNames, Sprite } from "../components"; import { Game } from ".."; import { clamp } from "../utils"; +import { DrawArgs } from "../interfaces"; export class Render extends System { private ctx: CanvasRenderingContext2D; @@ -38,10 +39,11 @@ export class Render extends System { return; } - const drawArgs = { + const drawArgs: DrawArgs = { center: boundingBox.center, dimension: boundingBox.dimension, rotation: boundingBox.rotation, + tint: entity.hasComponent(ComponentNames.Highlight) ? "red" : undefined, }; sprite.draw(this.ctx, drawArgs); |