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

forked from benjivers/val

workbenchthis machine
Files 1c30034c602bf5aa8777f1246b20f6bc05dd22e0
1
/**
2
 * The banner: the one moment a round turns, said big, on the view itself.
3
 *
4
 * Somebody sitting down in front of the game for two minutes meets a round
5
 * ending before they meet anything else, and the view used to freeze with no
6
 * word of who took it or why — the answer was three lines below the canvas at
7
 * eighty percent opacity. So for the few seconds a round is over, the match is
8
 * over, or a round is starting, the view carries a title and one line under
9
 * it. A pure function decides the words; the drawing is a band and two texts.
10
 */
11
12
import { roundOutcome } from "./prompt.js";
13
14
/** The buy phase is fourteen seconds; the round card shows for its first three. */
15
const BUY_TIME = 14;
16
const CARD_FOR = 3;
17
const FADE = 0.5;
18
19
const secs = (n) => Math.max(0, Math.ceil(n));
20
21
/**
22
 * What the banner says right now, or null for nothing. `alpha` is how solid it
23
 * is: a card that leaves by fading is not a card that blinked off.
24
 */
25
export function banner(snap) {
26
  if (!snap) return null;
27
  if (snap.phase === "over")
28
    return {
29
      title: snap.result ? `${snap.result}` : "Match over",
30
      sub: `match over · a new match starts in ${secs(snap.clock)}s`,
31
      alpha: 1,
32
    };
33
  if (snap.phase === "end") {
34
    const outcome = roundOutcome(snap);
35
    const next = `next round in ${secs(snap.clock)}s`;
36
    if (!outcome) return { title: "Round over", sub: next, alpha: 1 };
37
    return { title: outcome.title, sub: `${outcome.why} · ${next}`, alpha: 1 };
38
  }
39
  if (snap.phase === "buy" && snap.me) {
40
    const shownFor = BUY_TIME - Number(snap.clock);
41
    if (!(shownFor < CARD_FOR)) return null;
42
    const alpha = Math.max(0, Math.min(1, (CARD_FOR - shownFor) / FADE));
43
    const side = snap.me.side === "atk" ? "you attack — plant the spike on A or B" : "you defend — hold A and B";
44
    return { title: `Round ${snap.round}`, sub: side, alpha };
45
  }
46
  return null;
47
}
48
49
/** A dark band across the view with the title and the line under it. */
50
export function drawBanner(ctx, words, width, height) {
51
  if (!words || words.alpha <= 0.01) return;
52
  const unit = Math.min(width / 900, height / 570);
53
  const mid = width / 2;
54
  const top = height * 0.2;
55
  const band = 92 * unit;
56
  ctx.save();
57
  ctx.globalAlpha = words.alpha;
58
  ctx.fillStyle = "rgba(8,10,14,0.78)";
59
  ctx.fillRect(0, top, width, band);
60
  ctx.textAlign = "center";
61
  ctx.fillStyle = "#f2f3f6";
62
  ctx.font = `700 ${Math.round(34 * unit)}px system-ui, sans-serif`;
63
  ctx.fillText(words.title, mid, top + 44 * unit);
64
  ctx.fillStyle = "#b9c0cf";
65
  ctx.font = `${Math.round(17 * unit)}px system-ui, sans-serif`;
66
  ctx.fillText(words.sub, mid, top + 74 * unit);
67
  ctx.restore();
68
}
↑↓ navigate ↵ open esc close
↑↓ navigate ↵ open esc close

Keyboard shortcuts