games need input
This commit is contained in:
parent
ab8a6b02ce
commit
d0e8f2f261
|
|
@ -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 { focusInput } from "./focus.js"
|
||||||
import { $ } from "./dom.js"
|
import { $ } from "./dom.js"
|
||||||
import { randomId } from "../shared/utils.js"
|
import { randomId } from "../shared/utils.js"
|
||||||
|
|
@ -8,7 +9,15 @@ import { browserCommands } from "./commands.js"
|
||||||
let oldMode = "cinema"
|
let oldMode = "cinema"
|
||||||
let stopGame = false
|
let stopGame = false
|
||||||
let canvas: HTMLCanvasElement
|
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) {
|
export async function handleGameStart(msg: Message) {
|
||||||
const msgId = msg.id as string
|
const msgId = msg.id as string
|
||||||
|
|
@ -35,10 +44,12 @@ export async function handleGameStart(msg: Message) {
|
||||||
canvas.focus()
|
canvas.focus()
|
||||||
setStatus(msgId, "ok")
|
setStatus(msgId, "ok")
|
||||||
canvas.addEventListener("keydown", handleKeydown)
|
canvas.addEventListener("keydown", handleKeydown)
|
||||||
|
canvas.addEventListener("keyup", handleKeyup)
|
||||||
gameLoop(new GameContext(canvas.getContext("2d")!), game)
|
gameLoop(new GameContext(canvas.getContext("2d")!), game)
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleKeydown(e: KeyboardEvent) {
|
function handleKeydown(e: KeyboardEvent) {
|
||||||
|
pressedStack.add(e.key)
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
if (e.key === "Escape" || (e.ctrlKey && e.key === "c")) {
|
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.height = canvas.height / 2 + "px"
|
||||||
canvas.style.width = canvas.width / 2 + "px"
|
canvas.style.width = canvas.width / 2 + "px"
|
||||||
focusInput()
|
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) {
|
function gameLoop(ctx: GameContext, game: Game) {
|
||||||
let last = 0
|
let last = 0
|
||||||
|
|
||||||
|
if (game.init) game.init()
|
||||||
|
|
||||||
function loop(ts: number) {
|
function loop(ts: number) {
|
||||||
if (stopGame) return
|
if (stopGame) return
|
||||||
|
|
||||||
const delta = ts - last
|
const delta = ts - last
|
||||||
if (delta >= 1000 / 30) {
|
if (delta >= 1000 / 30) {
|
||||||
if (game.update) game.update(delta)
|
if (game.update) game.update(delta, pressed)
|
||||||
if (game.draw) game.draw(ctx)
|
if (game.draw) game.draw(ctx)
|
||||||
last = ts
|
last = ts
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ export type CommandResult = {
|
||||||
output: CommandOutput
|
output: CommandOutput
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type InputState = { key: string, shift: boolean, ctrl: boolean, meta: boolean }
|
||||||
|
|
||||||
export class GameContext {
|
export class GameContext {
|
||||||
height = 540
|
height = 540
|
||||||
width = 960
|
width = 960
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user