it's alive
This commit is contained in:
parent
68db4a923f
commit
419a8328fc
|
|
@ -1,7 +1,8 @@
|
|||
/// <reference lib="dom" />
|
||||
export const game = true
|
||||
|
||||
import type { GameContext, InputState } from "@/shared/types"
|
||||
import type { InputState } from "@/shared/types"
|
||||
import type { GameContext } from "@/shared/game"
|
||||
import { rng } from "@/shared/utils.ts"
|
||||
|
||||
const WIDTH = 960
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { Message, InputState } from "../shared/types.js"
|
||||
import { GameContext } from "../shared/types.js"
|
||||
import { GameContext } from "../shared/game.js"
|
||||
import { focusInput } from "./focus.js"
|
||||
import { $ } from "./dom.js"
|
||||
import { randomId } from "../shared/utils.js"
|
||||
|
|
@ -8,7 +8,7 @@ import { browserCommands } from "./commands.js"
|
|||
|
||||
const FPS = 30
|
||||
let oldMode = "cinema"
|
||||
let stopGame = false
|
||||
let running = false
|
||||
let canvas: HTMLCanvasElement
|
||||
type Game = { init?: () => void, update?: (delta: number, input: InputState) => void, draw?: (ctx: GameContext) => void }
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ function handleKeydown(e: KeyboardEvent) {
|
|||
e.preventDefault()
|
||||
|
||||
if (e.key === "Escape" || (e.ctrlKey && e.key === "c")) {
|
||||
stopGame = true
|
||||
running = false
|
||||
if (oldMode === "tall") browserCommands.mode?.()
|
||||
canvas.classList.remove("active")
|
||||
canvas.style.height = canvas.height / 2 + "px"
|
||||
|
|
@ -81,12 +81,13 @@ function handleKeyup(e: KeyboardEvent) {
|
|||
}
|
||||
|
||||
function gameLoop(ctx: GameContext, game: Game) {
|
||||
running = true
|
||||
let last = 0
|
||||
|
||||
if (game.init) game.init()
|
||||
|
||||
function loop(ts: number) {
|
||||
if (stopGame) return
|
||||
if (!running) return
|
||||
|
||||
const delta = ts - last
|
||||
if (delta >= 1000 / FPS) {
|
||||
|
|
|
|||
143
app/src/shared/game.ts
Normal file
143
app/src/shared/game.ts
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
|
||||
export class GameContext {
|
||||
constructor(public ctx: CanvasRenderingContext2D) { }
|
||||
|
||||
get width() { return this.ctx.canvas.width }
|
||||
get height() { return this.ctx.canvas.height }
|
||||
|
||||
clear() {
|
||||
this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height)
|
||||
}
|
||||
|
||||
circ(x: number, y: number, r: number, color = "black") {
|
||||
const c = this.ctx
|
||||
c.save()
|
||||
c.beginPath()
|
||||
c.strokeStyle = color
|
||||
c.arc(x, y, r, 0, Math.PI * 2)
|
||||
c.stroke()
|
||||
c.restore()
|
||||
}
|
||||
|
||||
circfill(x: number, y: number, r: number, color = "black") {
|
||||
const c = this.ctx
|
||||
c.save()
|
||||
c.beginPath()
|
||||
c.fillStyle = color
|
||||
c.arc(x, y, r, 0, Math.PI * 2)
|
||||
c.fill()
|
||||
c.restore()
|
||||
}
|
||||
|
||||
line(x0: number, y0: number, x1: number, y1: number, color = "black") {
|
||||
const c = this.ctx
|
||||
c.save()
|
||||
c.beginPath()
|
||||
c.strokeStyle = color
|
||||
c.moveTo(x0, y0)
|
||||
c.lineTo(x1, y1)
|
||||
c.stroke()
|
||||
c.restore()
|
||||
}
|
||||
|
||||
oval(x0: number, y0: number, x1: number, y1: number, color = "black") {
|
||||
const c = this.ctx
|
||||
const w = x1 - x0
|
||||
const h = y1 - y0
|
||||
c.save()
|
||||
c.beginPath()
|
||||
c.strokeStyle = color
|
||||
c.ellipse(x0 + w / 2, y0 + h / 2, Math.abs(w) / 2, Math.abs(h) / 2, 0, 0, Math.PI * 2)
|
||||
c.stroke()
|
||||
c.restore()
|
||||
}
|
||||
|
||||
ovalfill(x0: number, y0: number, x1: number, y1: number, color = "black") {
|
||||
const c = this.ctx
|
||||
const w = x1 - x0
|
||||
const h = y1 - y0
|
||||
c.save()
|
||||
c.beginPath()
|
||||
c.fillStyle = color
|
||||
c.ellipse(x0 + w / 2, y0 + h / 2, Math.abs(w) / 2, Math.abs(h) / 2, 0, 0, Math.PI * 2)
|
||||
c.fill()
|
||||
c.restore()
|
||||
}
|
||||
|
||||
rect(x0: number, y0: number, x1: number, y1: number, color = "black") {
|
||||
const c = this.ctx
|
||||
c.save()
|
||||
c.beginPath()
|
||||
c.strokeStyle = color
|
||||
c.rect(x0, y0, x1 - x0, y1 - y0)
|
||||
c.stroke()
|
||||
c.restore()
|
||||
}
|
||||
|
||||
rectfill(x0: number, y0: number, x1: number, y1: number, color = "black") {
|
||||
const c = this.ctx
|
||||
c.save()
|
||||
this.ctx.fillStyle = color
|
||||
this.ctx.fillRect(x0, y0, x1 - x0, y1 - y0)
|
||||
c.restore()
|
||||
}
|
||||
|
||||
rrect(x: number, y: number, w: number, h: number, r: number, color = "black") {
|
||||
const c = this.ctx
|
||||
c.save()
|
||||
c.beginPath()
|
||||
c.strokeStyle = color
|
||||
this.roundRectPath(x, y, w, h, r)
|
||||
c.stroke()
|
||||
c.restore()
|
||||
}
|
||||
|
||||
rrectfill(x: number, y: number, w: number, h: number, r: number, color = "black") {
|
||||
const c = this.ctx
|
||||
c.save()
|
||||
c.beginPath()
|
||||
c.fillStyle = color
|
||||
this.roundRectPath(x, y, w, h, r)
|
||||
c.fill()
|
||||
c.restore()
|
||||
}
|
||||
|
||||
trianglefill(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, color = "black") {
|
||||
return this.polygonfill(
|
||||
[
|
||||
[x0, y0],
|
||||
[x1, y1],
|
||||
[x2, y2]
|
||||
],
|
||||
color
|
||||
)
|
||||
}
|
||||
|
||||
polygonfill(points: [number, number][], color = "black") {
|
||||
if (points.length < 3) return // need at least a triangle
|
||||
const c = this.ctx
|
||||
c.save()
|
||||
c.beginPath()
|
||||
c.fillStyle = color
|
||||
c.moveTo(points[0]![0], points[0]![1])
|
||||
for (let i = 1; i < points.length; i++) {
|
||||
c.lineTo(points[i]![0], points[i]![1])
|
||||
}
|
||||
c.closePath()
|
||||
c.fill()
|
||||
c.restore()
|
||||
}
|
||||
|
||||
private roundRectPath(x: number, y: number, w: number, h: number, r: number) {
|
||||
const c = this.ctx
|
||||
c.moveTo(x + r, y)
|
||||
c.lineTo(x + w - r, y)
|
||||
c.quadraticCurveTo(x + w, y, x + w, y + r)
|
||||
c.lineTo(x + w, y + h - r)
|
||||
c.quadraticCurveTo(x + w, y + h, x + w - r, y + h)
|
||||
c.lineTo(x + r, y + h)
|
||||
c.quadraticCurveTo(x, y + h, x, y + h - r)
|
||||
c.lineTo(x, y + r)
|
||||
c.quadraticCurveTo(x, y, x + r, y)
|
||||
}
|
||||
}
|
||||
|
|
@ -17,146 +17,3 @@ export type CommandResult = {
|
|||
}
|
||||
|
||||
export type InputState = { key: string, shift: boolean, ctrl: boolean, meta: boolean, pressed: Set<string> }
|
||||
|
||||
export class GameContext {
|
||||
constructor(public ctx: CanvasRenderingContext2D) { }
|
||||
|
||||
get width() { return this.ctx.canvas.width }
|
||||
get height() { return this.ctx.canvas.height }
|
||||
|
||||
clear() {
|
||||
this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height)
|
||||
}
|
||||
|
||||
circ(x: number, y: number, r: number, color = "black") {
|
||||
const c = this.ctx
|
||||
c.save()
|
||||
c.beginPath()
|
||||
c.strokeStyle = color
|
||||
c.arc(x, y, r, 0, Math.PI * 2)
|
||||
c.stroke()
|
||||
c.restore()
|
||||
}
|
||||
|
||||
circfill(x: number, y: number, r: number, color = "black") {
|
||||
const c = this.ctx
|
||||
c.save()
|
||||
c.beginPath()
|
||||
c.fillStyle = color
|
||||
c.arc(x, y, r, 0, Math.PI * 2)
|
||||
c.fill()
|
||||
c.restore()
|
||||
}
|
||||
|
||||
line(x0: number, y0: number, x1: number, y1: number, color = "black") {
|
||||
const c = this.ctx
|
||||
c.save()
|
||||
c.beginPath()
|
||||
c.strokeStyle = color
|
||||
c.moveTo(x0, y0)
|
||||
c.lineTo(x1, y1)
|
||||
c.stroke()
|
||||
c.restore()
|
||||
}
|
||||
|
||||
oval(x0: number, y0: number, x1: number, y1: number, color = "black") {
|
||||
const c = this.ctx
|
||||
const w = x1 - x0
|
||||
const h = y1 - y0
|
||||
c.save()
|
||||
c.beginPath()
|
||||
c.strokeStyle = color
|
||||
c.ellipse(x0 + w / 2, y0 + h / 2, Math.abs(w) / 2, Math.abs(h) / 2, 0, 0, Math.PI * 2)
|
||||
c.stroke()
|
||||
c.restore()
|
||||
}
|
||||
|
||||
ovalfill(x0: number, y0: number, x1: number, y1: number, color = "black") {
|
||||
const c = this.ctx
|
||||
const w = x1 - x0
|
||||
const h = y1 - y0
|
||||
c.save()
|
||||
c.beginPath()
|
||||
c.fillStyle = color
|
||||
c.ellipse(x0 + w / 2, y0 + h / 2, Math.abs(w) / 2, Math.abs(h) / 2, 0, 0, Math.PI * 2)
|
||||
c.fill()
|
||||
c.restore()
|
||||
}
|
||||
|
||||
rect(x0: number, y0: number, x1: number, y1: number, color = "black") {
|
||||
const c = this.ctx
|
||||
c.save()
|
||||
c.beginPath()
|
||||
c.strokeStyle = color
|
||||
c.rect(x0, y0, x1 - x0, y1 - y0)
|
||||
c.stroke()
|
||||
c.restore()
|
||||
}
|
||||
|
||||
rectfill(x0: number, y0: number, x1: number, y1: number, color = "black") {
|
||||
const c = this.ctx
|
||||
c.save()
|
||||
this.ctx.fillStyle = color
|
||||
this.ctx.fillRect(x0, y0, x1 - x0, y1 - y0)
|
||||
c.restore()
|
||||
}
|
||||
|
||||
rrect(x: number, y: number, w: number, h: number, r: number, color = "black") {
|
||||
const c = this.ctx
|
||||
c.save()
|
||||
c.beginPath()
|
||||
c.strokeStyle = color
|
||||
this.roundRectPath(x, y, w, h, r)
|
||||
c.stroke()
|
||||
c.restore()
|
||||
}
|
||||
|
||||
rrectfill(x: number, y: number, w: number, h: number, r: number, color = "black") {
|
||||
const c = this.ctx
|
||||
c.save()
|
||||
c.beginPath()
|
||||
c.fillStyle = color
|
||||
this.roundRectPath(x, y, w, h, r)
|
||||
c.fill()
|
||||
c.restore()
|
||||
}
|
||||
|
||||
trianglefill(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, color = "black") {
|
||||
return this.polygonfill(
|
||||
[
|
||||
[x0, y0],
|
||||
[x1, y1],
|
||||
[x2, y2]
|
||||
],
|
||||
color
|
||||
)
|
||||
}
|
||||
|
||||
polygonfill(points: [number, number][], color = "black") {
|
||||
if (points.length < 3) return // need at least a triangle
|
||||
const c = this.ctx
|
||||
c.save()
|
||||
c.beginPath()
|
||||
c.fillStyle = color
|
||||
c.moveTo(points[0]![0], points[0]![1])
|
||||
for (let i = 1; i < points.length; i++) {
|
||||
c.lineTo(points[i]![0], points[i]![1])
|
||||
}
|
||||
c.closePath()
|
||||
c.fill()
|
||||
c.restore()
|
||||
}
|
||||
|
||||
private roundRectPath(x: number, y: number, w: number, h: number, r: number) {
|
||||
const c = this.ctx
|
||||
c.moveTo(x + r, y)
|
||||
c.lineTo(x + w - r, y)
|
||||
c.quadraticCurveTo(x + w, y, x + w, y + r)
|
||||
c.lineTo(x + w, y + h - r)
|
||||
c.quadraticCurveTo(x + w, y + h, x + w - r, y + h)
|
||||
c.lineTo(x + r, y + h)
|
||||
c.quadraticCurveTo(x, y + h, x, y + h - r)
|
||||
c.lineTo(x, y + r)
|
||||
c.quadraticCurveTo(x, y, x + r, y)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user