37 lines
1.2 KiB
JavaScript
37 lines
1.2 KiB
JavaScript
// Browser glue: turns a canvas and a window into a Platform. Impure by nature; not part of the exercises' logic.
|
|
|
|
const PREVENT = new Set(['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', ' '])
|
|
|
|
export const browserPlatform = (canvas, win) => {
|
|
const ctx = canvas.getContext('2d')
|
|
// Keys that scroll the page should only steer the game.
|
|
const onKey = (cb) => (e) => {
|
|
if (PREVENT.has(e.key)) e.preventDefault()
|
|
cb(e.key)
|
|
}
|
|
return {
|
|
fillRect: (x, y, w, h, color) => {
|
|
ctx.fillStyle = color
|
|
ctx.fillRect(x, y, w, h)
|
|
},
|
|
fillText: (x, y, text, color, size, align) => {
|
|
ctx.fillStyle = color
|
|
ctx.font = `${size}px monospace`
|
|
ctx.textAlign = align
|
|
ctx.fillText(text, x, y)
|
|
},
|
|
randomSeed: () => crypto.getRandomValues(new Uint32Array(1))[0],
|
|
// t is the number of milliseconds since the first frame.
|
|
startClock: (onTime) => {
|
|
const frame = (start) => (now) => {
|
|
const t0 = start ?? now
|
|
onTime(now - t0)
|
|
win.requestAnimationFrame(frame(t0))
|
|
}
|
|
win.requestAnimationFrame(frame(undefined))
|
|
},
|
|
onKeyDown: (cb) => win.addEventListener('keydown', onKey(cb)),
|
|
onKeyUp: (cb) => win.addEventListener('keyup', onKey(cb)),
|
|
}
|
|
}
|