154 lines
3.8 KiB
TypeScript

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<string, boolean>;
#previousKeyDown: Record<string, boolean>;
#mouseDown: Record<string, boolean>;
#previousMouseDown: Record<string, boolean>;
#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;
}