zx-kit 0.2.0 → 0.2.2

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,40 @@
1
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 scaled rendering.
5
+ * Sets canvas dimensions, applies CSS size, disables image smoothing, applies `ctx.scale()`,
6
+ * and returns the 2D context. All subsequent draw calls use game-pixel coordinates.
7
+ * Call once at game startup.
8
+ *
9
+ * @param canvas - The `<canvas>` element to configure
10
+ * @param scale - CSS pixels per game pixel (e.g. `4` for standard ZX Spectrum display)
11
+ * @param width - Canvas width in game pixels (default `256`)
12
+ * @param height - Canvas height in game pixels (default `192`)
13
+ * @returns The configured `CanvasRenderingContext2D` (already scaled — draw in game pixels)
14
+ *
15
+ * @example
16
+ * const canvas = document.getElementById('game') as HTMLCanvasElement
17
+ * const ctx = setupCanvas(canvas, 4) // 256×192 game px → 1024×768 CSS px
18
+ * const ctx = setupCanvas(canvas, 4, 256, 208) // taller canvas for status rows
19
+ */
20
+ export function setupCanvas(canvas, scale, width = 256, height = 192) {
21
+ canvas.width = width * scale;
22
+ canvas.height = height * scale;
23
+ canvas.style.width = `${width * scale}px`;
24
+ canvas.style.height = `${height * scale}px`;
25
+ const ctx = canvas.getContext('2d');
26
+ ctx.imageSmoothingEnabled = false;
27
+ ctx.scale(scale, scale);
28
+ return ctx;
29
+ }
30
+ /**
31
+ * Flips an 8×8 sprite horizontally. Returns a new `Uint8Array`.
32
+ * Use to derive left-facing sprites from right-facing definitions at module load time.
33
+ *
34
+ * @example
35
+ * export const PLAYER_RIGHT = new Uint8Array([0x18, 0x3C, ...])
36
+ * export const PLAYER_LEFT = mirrorSprite(PLAYER_RIGHT)
37
+ */
4
38
  export function mirrorSprite(src) {
5
39
  const out = new Uint8Array(8);
6
40
  for (let r = 0; r < 8; r++) {
@@ -13,6 +47,20 @@ export function mirrorSprite(src) {
13
47
  }
14
48
  return out;
15
49
  }
50
+ /**
51
+ * Draws an 8×8 sprite at game coordinates `(x, y)`.
52
+ * Always fills the full `CELL×CELL` area with `paper` first, then renders `ink` pixels.
53
+ *
54
+ * @param ctx - Target canvas context
55
+ * @param sprite - 8-byte sprite bitmap (one byte per row, bit 7 = leftmost pixel)
56
+ * @param x - Left edge in game pixels
57
+ * @param y - Top edge in game pixels
58
+ * @param ink - Foreground color (`C.*` palette value)
59
+ * @param paper - Background color (`C.*` palette value)
60
+ *
61
+ * @example
62
+ * drawSprite(ctx, MINE_SPRITE, col * CELL, row * CELL, C.B_RED, C.BLACK)
63
+ */
16
64
  export function drawSprite(ctx, sprite, x, y, ink, paper) {
17
65
  ctx.fillStyle = paper;
18
66
  ctx.fillRect(x, y, CELL, CELL);
@@ -25,6 +73,21 @@ export function drawSprite(ctx, sprite, x, y, ink, paper) {
25
73
  }
26
74
  }
27
75
  }
76
+ /**
77
+ * Draws a single ASCII character at game coordinates using the ROM font.
78
+ * If `paper` is omitted the background is not cleared (transparent).
79
+ *
80
+ * @param ctx - Target canvas context
81
+ * @param code - ASCII character code (32–127); 127 = solid block █
82
+ * @param x - Left edge in game pixels
83
+ * @param y - Top edge in game pixels
84
+ * @param ink - Foreground color
85
+ * @param paper - Optional background color; omit for transparent background
86
+ *
87
+ * @example
88
+ * drawChar(ctx, 127, x, y, C.B_GREEN, C.BLACK) // solid block █
89
+ * drawChar(ctx, 'A'.charCodeAt(0), x, y, C.B_WHITE) // transparent bg
90
+ */
28
91
  export function drawChar(ctx, code, x, y, ink, paper) {
29
92
  if (paper !== undefined) {
30
93
  ctx.fillStyle = paper;
@@ -39,19 +102,60 @@ export function drawChar(ctx, code, x, y, ink, paper) {
39
102
  }
40
103
  }
41
104
  }
105
+ /**
106
+ * Draws a string left-to-right starting at game coordinates `(x, y)`.
107
+ * Each character occupies one `CELL`-wide slot.
108
+ *
109
+ * @param ctx - Target canvas context
110
+ * @param text - ASCII string to render
111
+ * @param x - Left edge in game pixels
112
+ * @param y - Top edge in game pixels
113
+ * @param ink - Foreground color
114
+ * @param paper - Optional background color
115
+ *
116
+ * @example
117
+ * drawText(ctx, 'SCORE:00000', 0, statusY, C.B_WHITE, C.BLACK)
118
+ */
42
119
  export function drawText(ctx, text, x, y, ink, paper) {
43
120
  for (let i = 0; i < text.length; i++) {
44
121
  drawChar(ctx, text.charCodeAt(i), x + i * CELL, y, ink, paper);
45
122
  }
46
123
  }
47
124
  /**
48
- * Flash document.body background between `color` and `resetColor`.
49
- * Fire-and-forget — does not block.
125
+ * Draws a string centered horizontally within a canvas of `cols` character columns.
126
+ *
127
+ * @param ctx - Target canvas context
128
+ * @param text - ASCII string to render
129
+ * @param y - Top edge in game pixels
130
+ * @param cols - Total character columns (canvas width ÷ `CELL`, e.g. 32 for standard Spectrum)
131
+ * @param ink - Foreground color
132
+ * @param paper - Optional background color
50
133
  *
51
134
  * @example
52
- * flashBorder(C.B_RED, 3, 150) // explosion 3 red flashes
135
+ * // Bind cols once to avoid passing it every time:
136
+ * const centered = (ctx: CanvasRenderingContext2D, text: string, y: number, ink: string) =>
137
+ * drawTextCentered(ctx, text, y, COLS, ink)
138
+ * centered(ctx, 'GAME OVER', y, C.B_RED)
139
+ */
140
+ export function drawTextCentered(ctx, text, y, cols, ink, paper) {
141
+ const x = Math.floor((cols - text.length) / 2) * CELL;
142
+ drawText(ctx, text, x, y, ink, paper);
143
+ }
144
+ /**
145
+ * Flashes `document.body.style.backgroundColor` between `color` and `resetColor`.
146
+ * Fire-and-forget — does not block. Uses `setInterval` internally.
147
+ * One "flash" = one `color → resetColor` cycle; total steps = `times * 2`.
148
+ * Always resets to `resetColor` on completion.
149
+ *
150
+ * @param color - Flash color (`C.*` palette value or any CSS color string)
151
+ * @param times - Number of flashes
152
+ * @param intervalMs - Duration of each half-cycle in milliseconds
153
+ * @param resetColor - Final color after flashing (default `C.BLACK`)
154
+ *
155
+ * @example
156
+ * flashBorder(C.B_RED, 3, 150) // explosion — 3 red flashes → black
53
157
  * flashBorder(C.B_GREEN, 2, 200) // level complete
54
- * flashBorder(C.B_CYAN, 2, 120, C.BLUE) // reset to blue border
158
+ * flashBorder(C.B_CYAN, 2, 120, C.BLUE) // flash → reset to blue border
55
159
  */
56
160
  export function flashBorder(color, times, intervalMs, resetColor = C.BLACK) {
57
161
  let step = 0;
@@ -65,9 +169,4 @@ export function flashBorder(color, times, intervalMs, resetColor = C.BLACK) {
65
169
  }
66
170
  }, intervalMs);
67
171
  }
68
- // cols = total character columns of the canvas (e.g. 32 for standard Spectrum)
69
- export function drawTextCentered(ctx, text, y, cols, ink, paper) {
70
- const x = Math.floor((cols - text.length) / 2) * CELL;
71
- drawText(ctx, text, x, y, ink, paper);
72
- }
73
172
  //# 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.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Reusable ZX Spectrum primitives: font, palette, renderer, audio, input",
5
5
  "type": "module",
6
6
  "exports": {