diff --git a/src/components/GameCanvas.tsx b/src/components/GameCanvas.tsx index 0ea7180..09351e3 100644 --- a/src/components/GameCanvas.tsx +++ b/src/components/GameCanvas.tsx @@ -1,5 +1,6 @@ import { useState, useEffect, useRef } from "react"; import { TheAbstractionEngine, Game } from "../engine"; +import { Miscellaneous } from "../engine/config"; export interface GameCanvasProps { width: number; @@ -21,6 +22,8 @@ export const GameCanvas = ({ width, height }: GameCanvasProps) => { theAbstractionEngine.init().then(() => { theAbstractionEngine.play(); setGame(theAbstractionEngine); + + canvas.focus(); }); return () => theAbstractionEngine.stop(); @@ -30,7 +33,13 @@ export const GameCanvas = ({ width, height }: GameCanvasProps) => { return (
- +
); }; diff --git a/src/engine/TheAbstractionEngine.ts b/src/engine/TheAbstractionEngine.ts index e84093f..9ea5b90 100644 --- a/src/engine/TheAbstractionEngine.ts +++ b/src/engine/TheAbstractionEngine.ts @@ -94,19 +94,19 @@ export class TheAbstractionEngine { } private addWindowEventListenersToInputSystem(input: Input) { - window.addEventListener("keydown", (e) => { + this.ctx.canvas.addEventListener("keydown", (e) => { if (!e.repeat) { input.keyPressed(e.key.toLowerCase()); } }); - window.addEventListener("keyup", (e) => + this.ctx.canvas.addEventListener("keyup", (e) => input.keyReleased(e.key.toLowerCase()), ); - window.addEventListener("blur", () => input.clearKeys()); + this.ctx.canvas.addEventListener("blur", () => input.clearKeys()); - window.addEventListener("mousemove", (e) => { + this.ctx.canvas.addEventListener("mousemove", (e) => { const canvas = this.ctx.canvas; const rect = canvas.getBoundingClientRect(); diff --git a/src/engine/config/constants.ts b/src/engine/config/constants.ts index 288513a..c6b592e 100644 --- a/src/engine/config/constants.ts +++ b/src/engine/config/constants.ts @@ -10,15 +10,19 @@ export enum Action { export namespace KeyConstants { export const KeyActions: Record = { a: Action.MOVE_LEFT, + h: Action.MOVE_LEFT, arrowleft: Action.MOVE_LEFT, d: Action.MOVE_RIGHT, + l: Action.MOVE_RIGHT, arrowright: Action.MOVE_RIGHT, w: Action.MOVE_UP, + k: Action.MOVE_UP, arrowup: Action.MOVE_UP, s: Action.MOVE_DOWN, + j: Action.MOVE_DOWN, arrowdown: Action.MOVE_DOWN, " ": Action.INTERACT, @@ -56,4 +60,5 @@ export namespace Miscellaneous { export const GRID_CELL_HEIGHT = Math.floor(HEIGHT / GRID_ROWS); export const MODAL_ID = "modal"; + export const CANVAS_ID = "canvas"; } diff --git a/src/engine/entities/LambdaFactory.ts b/src/engine/entities/LambdaFactory.ts index 1483b9d..4861c6b 100644 --- a/src/engine/entities/LambdaFactory.ts +++ b/src/engine/entities/LambdaFactory.ts @@ -1,4 +1,10 @@ -import { IMAGES, SPRITE_SPECS, SpriteSpec, Sprites } from "../config"; +import { + IMAGES, + Miscellaneous, + SPRITE_SPECS, + SpriteSpec, + Sprites, +} from "../config"; import { Entity, EntityNames } from "."; import { BoundingBox, @@ -94,16 +100,45 @@ export class LambdaFactory extends Entity { } let modalOpen = false; + const close = () => { + modalOpen = false; + closeModal(); + + const spawner = this.getComponent( + ComponentNames.LambdaSpawn, + ); + spawner.code = ( + document.getElementById("code") as HTMLTextAreaElement + ).value; + this.addComponent(spawner); + + document.getElementById(Miscellaneous.CANVAS_ID)!.focus(); + return; + }; + const interaction = () => { if (modalOpen) { - modalOpen = false; - closeModal(); + close(); return; } + modalOpen = true; - openModal(this.code); + openModal(this.codeEditor(this.code)); + + document.getElementById("close-modal")!.addEventListener("click", close); }; this.addComponent(new Interactable(interaction)); } + + private codeEditor(code: string) { + return ` +
+ + +
+ `; + } } diff --git a/src/engine/systems/Collision.ts b/src/engine/systems/Collision.ts index 7b1b963..1912fb6 100644 --- a/src/engine/systems/Collision.ts +++ b/src/engine/systems/Collision.ts @@ -1,7 +1,7 @@ import { System, SystemNames } from "."; import { Game } from ".."; import { Entity, EntityNames } from "../entities"; -import { BoundingBox, Colliding, ComponentNames, Grid } from "../components"; +import { BoundingBox, ComponentNames, Grid } from "../components"; const collisionMap: Record> = { [EntityNames.Key]: new Set([EntityNames.LockedDoor]),