game tweaks

This commit is contained in:
Chris Wanstrath 2025-09-27 19:18:40 -07:00
parent 2c9f8a563e
commit ab8a6b02ce
2 changed files with 37 additions and 23 deletions

View File

@ -1,4 +1,4 @@
import { type Message, Context } from "../shared/types.js" import { type Message, GameContext } from "../shared/types.js"
import { focusInput } from "./focus.js" import { focusInput } from "./focus.js"
import { $ } from "./dom.js" import { $ } from "./dom.js"
import { randomId } from "../shared/utils.js" import { randomId } from "../shared/utils.js"
@ -6,40 +6,54 @@ import { setStatus, addOutput } from "./scrollback.js"
import { browserCommands } from "./commands.js" import { browserCommands } from "./commands.js"
let oldMode = "cinema" let oldMode = "cinema"
let stopGame = false
let canvas: HTMLCanvasElement
type Game = { init?: () => void, update?: (delta: number) => void, draw?: (ctx: GameContext) => void }
export async function handleGameStart(msg: Message) { export async function handleGameStart(msg: Message) {
const msgId = msg.id as string const msgId = msg.id as string
const name = msg.data as string const name = msg.data as string
const game = await import(`/command/${name}`)
const id = randomId()
let stopGame = false
addOutput(msgId, { html: `<canvas id="${id}" class="game active" height="540" width="960" tabindex="0"></canvas>` }) let game
try {
game = await import(`/command/${name}`)
} catch (err: any) {
setStatus(msgId, "error")
addOutput(msgId, `Error: ${err.message ? err.message : err}`)
return
}
const canvasId = randomId()
addOutput(msgId, { html: `<canvas id="${canvasId}" class="game active" height="540" width="960" tabindex="0"></canvas>` })
if (document.body.dataset.mode === "tall") { if (document.body.dataset.mode === "tall") {
browserCommands.mode?.() browserCommands.mode?.()
oldMode = "tall" oldMode = "tall"
} }
setStatus(msgId, "ok") canvas = $(canvasId) as HTMLCanvasElement
const canvas = $(id) as HTMLCanvasElement
const ctx = new Context(canvas.getContext("2d")!)
canvas.focus() canvas.focus()
canvas.addEventListener("keydown", e => { setStatus(msgId, "ok")
e.preventDefault() canvas.addEventListener("keydown", handleKeydown)
gameLoop(new GameContext(canvas.getContext("2d")!), game)
}
if (e.key === "Escape" || (e.ctrlKey && e.key === "c")) { function handleKeydown(e: KeyboardEvent) {
stopGame = true e.preventDefault()
if (oldMode === "tall") browserCommands.mode?.()
canvas.classList.remove("active")
canvas.style.height = canvas.height / 2 + "px"
canvas.style.width = canvas.width / 2 + "px"
focusInput()
}
})
if (e.key === "Escape" || (e.ctrlKey && e.key === "c")) {
stopGame = true
if (oldMode === "tall") browserCommands.mode?.()
canvas.classList.remove("active")
canvas.style.height = canvas.height / 2 + "px"
canvas.style.width = canvas.width / 2 + "px"
focusInput()
}
}
function gameLoop(ctx: GameContext, game: Game) {
let last = 0 let last = 0
function loop(ts: number) { function loop(ts: number) {
if (stopGame) return if (stopGame) return
@ -51,6 +65,6 @@ export async function handleGameStart(msg: Message) {
} }
requestAnimationFrame(loop) requestAnimationFrame(loop)
} }
requestAnimationFrame(loop)
}
requestAnimationFrame(loop)
}

View File

@ -16,7 +16,7 @@ export type CommandResult = {
output: CommandOutput output: CommandOutput
} }
export class Context { export class GameContext {
height = 540 height = 540
width = 960 width = 960