wren/val Public Public: anyone can read this; nobody can change it.

forked from benjivers/val

workbenchthis machine
Files main
1
/**
2
 * The board from above, drawn into a canvas that writes down the colour of
3
 * every dot. What is pinned here is colour: who is drawn in which.
4
 */
5
import { expect, test } from "bun:test";
6
import { drawTopdown } from "../../static/engine/topdown.js";
7
8
function fakeContext() {
9
  const dots: { x: number; y: number; fill: string }[] = [];
10
  const rings: string[] = [];
11
  let at: { x: number; y: number } | null = null;
12
  const noop = () => {};
13
  const ctx = {
14
    dots,
15
    rings,
16
    fillStyle: "",
17
    strokeStyle: "",
18
    lineWidth: 1,
19
    font: "",
20
    textAlign: "left",
21
    globalAlpha: 1,
22
    save: noop,
23
    restore: noop,
24
    beginPath: () => {
25
      at = null;
26
    },
27
    closePath: noop,
28
    clip: noop,
29
    rect: noop,
30
    translate: noop,
31
    rotate: noop,
32
    moveTo: noop,
33
    lineTo: noop,
34
    fillRect: noop,
35
    fillText: noop,
36
    arc: (x: number, y: number) => {
37
      at = { x, y };
38
    },
39
    fill: () => {
40
      if (at) dots.push({ ...at, fill: ctx.fillStyle });
41
    },
42
    stroke: () => {
43
      if (ctx.globalAlpha < 1) rings.push(ctx.strokeStyle);
44
    },
45
  };
46
  return ctx;
47
}
48
49
const map = { rows: ["....", "....", "....", "...."], tile: 100 };
50
const box = { x: 0, y: 0, w: 400, h: 400 };
51
const me = { id: "me", name: "Me", x: 50, y: 50, angle: 0, alive: true, hp: 100, mate: true };
52
const body = (over: Record<string, unknown>) => ({ name: "B", y: 200, angle: 0, alive: true, hp: 100, mate: false, ...over });
53
const draw = (players: unknown[], marks?: unknown[]) => {
54
  const ctx = fakeContext();
55
  drawTopdown(ctx as never, map, { me, players: [me, ...players], shots: [] }, (p: unknown) => p, box, { marks, labels: false });
56
  return ctx;
57
};
58
/** Body dots, left to right; the arrow that is you is not a dot. */
59
const dots = (ctx: ReturnType<typeof fakeContext>) => [...ctx.dots].sort((a, b) => a.x - b.x).map((d) => d.fill);
60
61
test("without `side`, a mate, an enemy and a fallen mate wear exactly today's colours", () => {
62
  const ctx = draw([body({ id: "m", mate: true, x: 100 }), body({ id: "e", x: 200 }), body({ id: "d", mate: true, alive: false, x: 300 })]);
63
  expect(dots(ctx)).toEqual(["#4fb3d9", "#e35d5b"]);
64
  expect(draw([], [{ id: "e", x: 200, y: 200, angle: 0, mate: false, fade: 0.5 }]).rings).toEqual(["#e35d5b", "#e35d5b"]);
65
});
66
67
test("three enemy sides are three colours on the map, the same frame after frame", () => {
68
  const three = [
69
    body({ id: "a", side: "map-red", x: 100 }),
70
    body({ id: "b", side: "map-gold", x: 200 }),
71
    body({ id: "c", side: "map-violet", x: 300 }),
72
  ];
73
  const first = dots(draw(three));
74
  expect(new Set(first).size).toBe(3);
75
  expect(first).not.toContain("#4fb3d9");
76
  expect(dots(draw([...three].reverse()))).toEqual(first);
77
  // A last-seen ring wears its side's colour, not the default enemy's.
78
  const ring = draw([], [{ id: "c", x: 300, y: 200, angle: 0, mate: false, side: "map-violet", fade: 0.5 }]).rings;
79
  expect(ring[0]).toBe(first[2]);
80
});
↑↓ navigate ↵ open esc close
↑↓ navigate ↵ open esc close

Keyboard shortcuts