diff --git a/app/src/js/game.ts b/app/src/js/game.ts index 11987ce..642760e 100644 --- a/app/src/js/game.ts +++ b/app/src/js/game.ts @@ -1,4 +1,5 @@ -import { type Message, GameContext } from "../shared/types.js" +import type { Message, InputState } from "../shared/types.js" +import { GameContext } from "../shared/types.js" import { focusInput } from "./focus.js" import { $ } from "./dom.js" import { randomId } from "../shared/utils.js" @@ -8,7 +9,15 @@ import { browserCommands } from "./commands.js" let oldMode = "cinema" let stopGame = false let canvas: HTMLCanvasElement -type Game = { init?: () => void, update?: (delta: number) => void, draw?: (ctx: GameContext) => void } +type Game = { init?: () => void, update?: (delta: number, input: InputState) => void, draw?: (ctx: GameContext) => void } + +const pressedStack = new Set() +let pressed: InputState = { + key: "", + shift: false, + ctrl: false, + meta: false, +} export async function handleGameStart(msg: Message) { const msgId = msg.id as string @@ -35,10 +44,12 @@ export async function handleGameStart(msg: Message) { canvas.focus() setStatus(msgId, "ok") canvas.addEventListener("keydown", handleKeydown) + canvas.addEventListener("keyup", handleKeyup) gameLoop(new GameContext(canvas.getContext("2d")!), game) } function handleKeydown(e: KeyboardEvent) { + pressedStack.add(e.key) e.preventDefault() if (e.key === "Escape" || (e.ctrlKey && e.key === "c")) { @@ -48,18 +59,35 @@ function handleKeydown(e: KeyboardEvent) { canvas.style.height = canvas.height / 2 + "px" canvas.style.width = canvas.width / 2 + "px" focusInput() + } else { + pressed.key = e.key + pressed.ctrl = e.ctrlKey + pressed.shift = e.shiftKey + pressed.meta = e.metaKey + } +} + +function handleKeyup(e: KeyboardEvent) { + pressedStack.delete(e.key) + if (pressedStack.size === 0) { + pressed.key = "" + pressed.ctrl = false + pressed.shift = false + pressed.meta = false } } function gameLoop(ctx: GameContext, game: Game) { let last = 0 + if (game.init) game.init() + function loop(ts: number) { if (stopGame) return const delta = ts - last if (delta >= 1000 / 30) { - if (game.update) game.update(delta) + if (game.update) game.update(delta, pressed) if (game.draw) game.draw(ctx) last = ts } diff --git a/app/src/shared/types.ts b/app/src/shared/types.ts index fd868b5..4d3f8f3 100644 --- a/app/src/shared/types.ts +++ b/app/src/shared/types.ts @@ -16,6 +16,8 @@ export type CommandResult = { output: CommandOutput } +export type InputState = { key: string, shift: boolean, ctrl: boolean, meta: boolean } + export class GameContext { height = 540 width = 960