import { getScreen } from "./screen.ts"; import { Point } from "../datatypes.ts"; function handleKey(e: KeyboardEvent, down: boolean) { active.handleKeyDown(e.key, down); } function handleMouseOut() { active.handleMouseMove(-1, -1); } function handleMouseMove(canvas: HTMLCanvasElement, m: MouseEvent) { if (canvas.offsetWidth == 0 || canvas.offsetHeight == 0) { return; } active.handleMouseMove( m.offsetX / canvas.offsetWidth, m.offsetY / canvas.offsetHeight, ); } function handleMouseButton( canvas: HTMLCanvasElement, m: MouseEvent, down: boolean, ) { if (canvas.offsetWidth == 0 || canvas.offsetHeight == 0) { return; } active.handleMouseMove( m.offsetX / canvas.offsetWidth, m.offsetY / canvas.offsetHeight, ); let button: MouseButton | null = m.button == 0 ? "leftMouse" : m.button == 1 ? "rightMouse" : null; if (button != null) { active.handleMouseDown(button, down); } } export function setupInput(canvas: HTMLCanvasElement) { canvas.addEventListener("keyup", (k) => handleKey(k, false)); document.addEventListener("keyup", (k) => handleKey(k, false)); canvas.addEventListener("keydown", (k) => handleKey(k, true)); document.addEventListener("keydown", (k) => handleKey(k, true)); canvas.addEventListener("mouseout", (_) => handleMouseOut()); canvas.addEventListener("mousemove", (m) => handleMouseMove(canvas, m)); canvas.addEventListener("mousedown", (m) => handleMouseButton(canvas, m, true), ); canvas.addEventListener("mouseup", (m) => handleMouseButton(canvas, m, false), ); } export type MouseButton = "leftMouse" | "rightMouse"; class Input { #keyDown: Record; #previousKeyDown: Record; #mouseDown: Record; #previousMouseDown: Record; #mousePosition: Point | null; constructor() { this.#keyDown = {}; this.#previousKeyDown = {}; this.#mouseDown = {}; this.#previousMouseDown = {}; this.#mousePosition = null; } update() { this.#previousKeyDown = { ...this.#keyDown }; this.#previousMouseDown = { ...this.#mouseDown }; } handleMouseDown(name: string, down: boolean) { this.#mouseDown[name] = down; } handleKeyDown(name: string, down: boolean) { this.#keyDown[name] = down; } handleMouseMove(x: number, y: number) { let screen = getScreen(); if (x < 0.0 || x >= 1.0) { this.#mousePosition = null; } if (y < 0.0 || y >= 1.0) { this.#mousePosition = null; } let w = screen.size.w; let h = screen.size.h; this.#mousePosition = new Point(Math.floor(x * w), Math.floor(y * h)); } isMouseDown(btn: MouseButton): boolean { return this.#mouseDown[btn]; } isMouseClicked(btn: MouseButton): boolean { return this.#mouseDown[btn] && !this.#previousMouseDown[btn]; } isMouseReleased(btn: MouseButton): boolean { return !this.#mouseDown[btn] && this.#previousMouseDown[btn]; } get mousePosition(): Point | null { return this.#mousePosition; } isAnyKeyDown(...keys: string[]) : boolean { for (const k of keys) { if(this.isKeyDown(k)) { return true } } return false } isKeyDown(key: string): boolean { return this.#keyDown[key]; } isKeyPressed(key: string): boolean { return this.#keyDown[key] && !this.#previousKeyDown[key]; } isKeyReleased(key: string): boolean { return !this.#keyDown[key] && this.#previousKeyDown[key]; } isAnythingPressed(): boolean { for (let k of Object.keys(this.#keyDown)) { if (this.#keyDown[k] && !this.#previousKeyDown[k]) { return true; } } for (let k of Object.keys(this.#mouseDown)) { if (this.#mouseDown[k] && !this.#previousMouseDown[k]) { return true; } } return false; } } let active = new Input(); export function getInput(): Input { return active; }