zx-kit 0.1.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/renderer.js CHANGED
@@ -1,6 +1,34 @@
1
- import { CELL } from './palette.js';
1
+ import { C, CELL } from './palette.js';
2
2
  import { getCharRow } from './font.js';
3
- // Flip an 8×8 sprite horizontally
3
+ /**
4
+ * Initialises a canvas element for pixel-perfect ZX Spectrum rendering.
5
+ * Sets canvas dimensions, disables image smoothing, and returns the 2D context.
6
+ * Call once at game startup — replaces the manual canvas + `imageSmoothingEnabled` boilerplate.
7
+ *
8
+ * @param canvas - The `<canvas>` element to configure
9
+ * @param width - Canvas width in game pixels (e.g. `COLS * CELL`)
10
+ * @param height - Canvas height in game pixels (e.g. `(ROWS + STATUS_ROWS) * CELL`)
11
+ * @returns The configured `CanvasRenderingContext2D`
12
+ *
13
+ * @example
14
+ * const canvas = document.getElementById('game') as HTMLCanvasElement
15
+ * const ctx = setupCanvas(canvas, 256, 192)
16
+ */
17
+ export function setupCanvas(canvas, width, height) {
18
+ canvas.width = width;
19
+ canvas.height = height;
20
+ const ctx = canvas.getContext('2d');
21
+ ctx.imageSmoothingEnabled = false;
22
+ return ctx;
23
+ }
24
+ /**
25
+ * Flips an 8×8 sprite horizontally. Returns a new `Uint8Array`.
26
+ * Use to derive left-facing sprites from right-facing definitions at module load time.
27
+ *
28
+ * @example
29
+ * export const PLAYER_RIGHT = new Uint8Array([0x18, 0x3C, ...])
30
+ * export const PLAYER_LEFT = mirrorSprite(PLAYER_RIGHT)
31
+ */
4
32
  export function mirrorSprite(src) {
5
33
  const out = new Uint8Array(8);
6
34
  for (let r = 0; r < 8; r++) {
@@ -13,6 +41,20 @@ export function mirrorSprite(src) {
13
41
  }
14
42
  return out;
15
43
  }
44
+ /**
45
+ * Draws an 8×8 sprite at game coordinates `(x, y)`.
46
+ * Always fills the full `CELL×CELL` area with `paper` first, then renders `ink` pixels.
47
+ *
48
+ * @param ctx - Target canvas context
49
+ * @param sprite - 8-byte sprite bitmap (one byte per row, bit 7 = leftmost pixel)
50
+ * @param x - Left edge in game pixels
51
+ * @param y - Top edge in game pixels
52
+ * @param ink - Foreground color (`C.*` palette value)
53
+ * @param paper - Background color (`C.*` palette value)
54
+ *
55
+ * @example
56
+ * drawSprite(ctx, MINE_SPRITE, col * CELL, row * CELL, C.B_RED, C.BLACK)
57
+ */
16
58
  export function drawSprite(ctx, sprite, x, y, ink, paper) {
17
59
  ctx.fillStyle = paper;
18
60
  ctx.fillRect(x, y, CELL, CELL);
@@ -25,6 +67,21 @@ export function drawSprite(ctx, sprite, x, y, ink, paper) {
25
67
  }
26
68
  }
27
69
  }
70
+ /**
71
+ * Draws a single ASCII character at game coordinates using the ROM font.
72
+ * If `paper` is omitted the background is not cleared (transparent).
73
+ *
74
+ * @param ctx - Target canvas context
75
+ * @param code - ASCII character code (32–127); 127 = solid block █
76
+ * @param x - Left edge in game pixels
77
+ * @param y - Top edge in game pixels
78
+ * @param ink - Foreground color
79
+ * @param paper - Optional background color; omit for transparent background
80
+ *
81
+ * @example
82
+ * drawChar(ctx, 127, x, y, C.B_GREEN, C.BLACK) // solid block █
83
+ * drawChar(ctx, 'A'.charCodeAt(0), x, y, C.B_WHITE) // transparent bg
84
+ */
28
85
  export function drawChar(ctx, code, x, y, ink, paper) {
29
86
  if (paper !== undefined) {
30
87
  ctx.fillStyle = paper;
@@ -39,14 +96,71 @@ export function drawChar(ctx, code, x, y, ink, paper) {
39
96
  }
40
97
  }
41
98
  }
99
+ /**
100
+ * Draws a string left-to-right starting at game coordinates `(x, y)`.
101
+ * Each character occupies one `CELL`-wide slot.
102
+ *
103
+ * @param ctx - Target canvas context
104
+ * @param text - ASCII string to render
105
+ * @param x - Left edge in game pixels
106
+ * @param y - Top edge in game pixels
107
+ * @param ink - Foreground color
108
+ * @param paper - Optional background color
109
+ *
110
+ * @example
111
+ * drawText(ctx, 'SCORE:00000', 0, statusY, C.B_WHITE, C.BLACK)
112
+ */
42
113
  export function drawText(ctx, text, x, y, ink, paper) {
43
114
  for (let i = 0; i < text.length; i++) {
44
115
  drawChar(ctx, text.charCodeAt(i), x + i * CELL, y, ink, paper);
45
116
  }
46
117
  }
47
- // cols = total character columns of the canvas (e.g. 32 for standard Spectrum)
118
+ /**
119
+ * Draws a string centered horizontally within a canvas of `cols` character columns.
120
+ *
121
+ * @param ctx - Target canvas context
122
+ * @param text - ASCII string to render
123
+ * @param y - Top edge in game pixels
124
+ * @param cols - Total character columns (canvas width ÷ `CELL`, e.g. 32 for standard Spectrum)
125
+ * @param ink - Foreground color
126
+ * @param paper - Optional background color
127
+ *
128
+ * @example
129
+ * // Bind cols once to avoid passing it every time:
130
+ * const centered = (ctx: CanvasRenderingContext2D, text: string, y: number, ink: string) =>
131
+ * drawTextCentered(ctx, text, y, COLS, ink)
132
+ * centered(ctx, 'GAME OVER', y, C.B_RED)
133
+ */
48
134
  export function drawTextCentered(ctx, text, y, cols, ink, paper) {
49
135
  const x = Math.floor((cols - text.length) / 2) * CELL;
50
136
  drawText(ctx, text, x, y, ink, paper);
51
137
  }
138
+ /**
139
+ * Flashes `document.body.style.backgroundColor` between `color` and `resetColor`.
140
+ * Fire-and-forget — does not block. Uses `setInterval` internally.
141
+ * One "flash" = one `color → resetColor` cycle; total steps = `times * 2`.
142
+ * Always resets to `resetColor` on completion.
143
+ *
144
+ * @param color - Flash color (`C.*` palette value or any CSS color string)
145
+ * @param times - Number of flashes
146
+ * @param intervalMs - Duration of each half-cycle in milliseconds
147
+ * @param resetColor - Final color after flashing (default `C.BLACK`)
148
+ *
149
+ * @example
150
+ * flashBorder(C.B_RED, 3, 150) // explosion — 3 red flashes → black
151
+ * flashBorder(C.B_GREEN, 2, 200) // level complete
152
+ * flashBorder(C.B_CYAN, 2, 120, C.BLUE) // flash → reset to blue border
153
+ */
154
+ export function flashBorder(color, times, intervalMs, resetColor = C.BLACK) {
155
+ let step = 0;
156
+ const totalSteps = times * 2;
157
+ const id = setInterval(() => {
158
+ document.body.style.backgroundColor = step % 2 === 0 ? color : resetColor;
159
+ step++;
160
+ if (step >= totalSteps) {
161
+ clearInterval(id);
162
+ document.body.style.backgroundColor = resetColor;
163
+ }
164
+ }, intervalMs);
165
+ }
52
166
  //# sourceMappingURL=renderer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zx-kit",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "description": "Reusable ZX Spectrum primitives: font, palette, renderer, audio, input",
5
5
  "type": "module",
6
6
  "exports": {