/// export const game = true import type { GameContext, InputState } from "@/shared/game" import { rng } from "@/shared/utils.ts" const CELL = 20 const WIDTH = 30 const HEIGHT = 20 const TICK = 5 let snake: { x: number; y: number }[] = [{ x: 5, y: 5 }] let dir = { x: 1, y: 0 } let food = { x: rng(WIDTH) - 1, y: rng(HEIGHT) - 1 } let dead = false let tick = 0 export function init() { snake = [{ x: 5, y: 5 }] dir = { x: 1, y: 0 } food = { x: rng(WIDTH) - 1, y: rng(HEIGHT) - 1 } dead = false tick = 0 } export function update(_delta: number, input: InputState) { if (dead) return const keys = input.pressed if (keys.has("ArrowUp") || keys.has("w")) dir = { x: 0, y: -1 } if (keys.has("ArrowDown") || keys.has("s")) dir = { x: 0, y: 1 } if (keys.has("ArrowLeft") || keys.has("a")) dir = { x: -1, y: 0 } if (keys.has("ArrowRight") || keys.has("d")) dir = { x: 1, y: 0 } // move every $TICK ticks if (++tick % TICK !== 0) return const head = { x: snake[0]!.x + dir.x, y: snake[0]!.y + dir.y } // death checks if ( head.x < 0 || head.x >= WIDTH || head.y < 0 || head.y >= HEIGHT || snake.some(s => s.x === head.x && s.y === head.y) ) { dead = true return } snake.unshift(head) // eat if (head.x === food.x && head.y === food.y) { food = { x: rng(WIDTH) - 1, y: rng(HEIGHT) - 1 } } else { snake.pop() } } export function draw(ctx: GameContext) { ctx.clear() ctx.rectfill(0, 0, ctx.width, ctx.height, "black") const boardW = WIDTH * CELL const boardH = HEIGHT * CELL // move board center → canvas center const offsetX = (ctx.width - boardW) / 2 const offsetY = (ctx.height - boardH) / 2 console.log("X", offsetX) console.log("Y", offsetY) const c = ctx.ctx c.save() c.translate(offsetX, offsetY) // board background (now local 0,0 is board top-left) ctx.rectfill(0, 0, boardW, boardH, "green") // food ctx.rectfill( food.x * CELL, food.y * CELL, (food.x + 1) * CELL, (food.y + 1) * CELL, "lime" ) // snake for (const s of snake) { ctx.rectfill( s.x * CELL, s.y * CELL, ((s.x + 1) * CELL) + .5, ((s.y + 1) * CELL) + .5, "magenta" ) } // score! ctx.text(`Score: ${snake.length - 1}`, 5, boardH - 18, "cyan", 12) c.restore() if (dead) { ctx.centerText("GAME OVER", ctx.height / 2, "red", 50) } }