diff options
Diffstat (limited to 'src/spectate/main.ts')
-rw-r--r-- | src/spectate/main.ts | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/src/spectate/main.ts b/src/spectate/main.ts new file mode 100644 index 0000000..4d508b6 --- /dev/null +++ b/src/spectate/main.ts @@ -0,0 +1,93 @@ +/// <reference lib="dom" /> + +const ws = new WebSocket("/events") + +type Packet = "tick" + | { pos: { id: number, x: number, y: number } } + | { game: { width: number, height: number } } + | { player: { id: number, name: string } } + +class Snake { + parts: { x: number, y: number, dx: number, dy: number }[] = [] + constructor(public name: string) { } + add_part(x: number, y: number) { + if (!this.parts.length) return this.parts.push({ x, y, dx: 0, dy: 0 }) + const last = this.parts[this.parts.length - 1] + let dx = x - last.x, dy = y - last.y; + if (x > last.x + 1 || x < last.x - 1) dx *= -1, dx /= Math.abs(dx) + if (y > last.y + 1 || y < last.y - 1) dy *= -1, dy /= Math.abs(dy) + this.parts.push({ x, y, dx, dy }) + console.log(this.parts); + + } +} +let size = 0 +let snakes = new Map<number, Snake>() + +let canvas: HTMLCanvasElement +let ctx: CanvasRenderingContext2D + +document.addEventListener("DOMContentLoaded", () => { + canvas = document.createElement("canvas") + ctx = canvas.getContext("2d")! + document.body.append(canvas) + canvas.width = 1000; + canvas.height = 1000; + redraw() +}) + +function redraw() { + ctx.fillStyle = "black" + ctx.fillRect(0, 0, canvas.width, canvas.height); + + ctx.save() + const scale = canvas.width / size + ctx.scale(scale, scale) + for (let x = 0; x < size; x++) { + for (let y = 0; y < size; y++) { + ctx.strokeStyle = "grey" + ctx.lineWidth = 0.02 + ctx.strokeRect(x, y, 1, 1) + } + } + ctx.translate(0.5, 0.5) + for (const [xo, yo] of [[0, 0], [-size, 0], [size, 0], [0, -size], [0, size]]) { + ctx.save() + ctx.translate(xo, yo) + for (const snake of snakes.values()) { + ctx.beginPath(); + for (let i = 0; i < snake.parts.length; i++) { + const p = snake.parts[i]; + ctx.moveTo(p.x - p.dx, p.y - p.dy) + ctx.lineTo(p.x, p.y) + } + ctx.lineCap = "round" + ctx.lineJoin = "round" + ctx.lineWidth = 0.6; + ctx.strokeStyle = "red" + ctx.stroke() + } + ctx.restore() + } + ctx.restore() + + requestAnimationFrame(redraw) +} + +ws.onerror = console.error +ws.onmessage = message => { + const p = JSON.parse(message.data) as Packet + console.log(p); + if (p == "tick") { + + } else if ("game" in p) { + snakes.clear() + size = p.game.width + } else if ("player" in p) { + snakes.set(p.player.id, new Snake(p.player.name)) + } else if ("pos" in p) { + snakes.get(p.pos.id)?.add_part(p.pos.x, p.pos.y) + } + +} + |