import { SystemNames, System } from "."; import { Game } from ".."; import { ComponentNames } from "../components"; import { Control } from "../components/Control"; import { Action, KeyConstants } from "../config"; import { Entity } from "../entities"; import { Coord2D, Direction } from "../interfaces"; export class Input extends System { private keys: Set; private mousePosition: Coord2D; constructor() { super(SystemNames.Input); this.keys = new Set(); this.mousePosition = { x: 0, y: 0 }; } public clearKeys() { this.keys.clear(); } public keyPressed(key: string) { this.keys.add(key); } public keyReleased(key: string) { this.keys.delete(key); } public update(_dt: number, game: Game) { game.forEachEntityWithComponent(ComponentNames.Control, (entity) => this.handleInput(entity), ); } public handleInput(entity: Entity) { const controlComponent = entity.getComponent( ComponentNames.Control, ); if (!controlComponent.isControllable) return; const hasGrid = entity.hasComponent(ComponentNames.Grid); // TODO: check grid via controlComponent to notify entity of interaction const [moveUp, moveLeft, moveRight, moveDown] = [ Action.MOVE_UP, Action.MOVE_LEFT, 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); } } private hasSomeKey(keys?: string[]): boolean { if (keys) { return keys.some((key) => this.keys.has(key)); } return false; } public setMousePosition(mousePosition: Coord2D) { this.mousePosition = mousePosition; } public getMousePosition(): Coord2D { return this.mousePosition; } }