zx-kit 0.24.2 → 0.26.0

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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > **Build browser games that look and sound like a ZX Spectrum — without any of its limitations.**
4
4
 
5
- Three-channel chiptune audio. Pixel-perfect canvas rendering. Authentic 15-color palette. ROM bitmap font. Tile maps with seasonal swapping. Physics-based sprites. Collision detection. A complete retro game engine in a single zero-dependency npm package.
5
+ Three-channel chiptune audio. Pixel-perfect canvas rendering. Authentic 15-color palette. ROM bitmap font. Tile maps with seasonal swapping. Free-roaming sprites with velocity and gravity helpers. Collision detection. A complete retro game toolkit in a single zero-dependency npm package.
6
6
 
7
7
  [![npm](https://img.shields.io/npm/v/zx-kit)](https://www.npmjs.com/package/zx-kit)
8
8
  [![license](https://img.shields.io/npm/l/zx-kit)](LICENSE)
@@ -13,7 +13,7 @@ Three-channel chiptune audio. Pixel-perfect canvas rendering. Authentic 15-color
13
13
 
14
14
  The ZX Spectrum was a marvel of constraint. Its 8×8 pixel grid, 15-color palette, and 1-bit beeper defined an entire visual and sonic language. Thousands of games were made with nearly nothing — and they were unforgettable.
15
15
 
16
- zx-kit lets you build in that same visual tradition, but with everything the original hardware was too limited to provide: three-channel AY-3-8912 chiptune audio with hardware-accurate envelopes and LFSR noise, smooth canvas rendering, physics-based sprites, and collision detection — all in TypeScript, all in the browser, all with zero dependencies.
16
+ zx-kit lets you build in that same visual tradition, but with everything the original hardware was too limited to provide: three-channel AY-3-8912 chiptune audio with hardware-accurate envelopes and LFSR noise, smooth canvas rendering, free-roaming sprites with velocity and gravity helpers, and collision detection — all in TypeScript, all in the browser, all with zero dependencies.
17
17
 
18
18
  The goal is simple: **it should look and sound like a Spectrum, but run like a modern game.**
19
19
 
@@ -28,11 +28,11 @@ The goal is simple: **it should look and sound like a Spectrum, but run like a m
28
28
  - **Tile map engine** — scrollable maps, O(1) id-index, smart seasonal background swapping, solid-tile collision queries
29
29
  - **Free-roaming sprites** — position, velocity, gravity, `flipX` caching, transparent or opaque background
30
30
  - **Three-tier collision** — AABB overlap tests, generic rect-vs-tile wall resolution (any sprite size), and pixel-precise mask overlap with O(pixels) sorted-merge intersection — no allocations per frame
31
- - **Keyboard input** — configurable key-repeat, single-consume action flags, instant state reset on phase transitions
31
+ - **Keyboard and gamepad input** — configurable key-repeat, transparent gamepad polling, single-consume action flags, instant state reset on phase transitions
32
32
  - **ZX-style UI widgets** — progress bars with managed lifetime, boxes, frames, panel titles
33
33
  - **Typed save / load** — persistent saves via `localStorage` with schema versioning, migrations, slot enumeration, in-memory throttling, and discriminated Result types for every failure mode
34
34
  - **Runtime locale switching** — type-safe string-pack selection via `pickLocale()`, so a game can switch language while running — unimaginable on the original Spectrum, natural in the browser
35
- - **Zero dependencies** — only Web platform APIs: `Canvas`, `Web Audio`, `KeyboardEvent`
35
+ - **Zero dependencies** — only Web platform APIs: `Canvas`, `Web Audio`, `KeyboardEvent`, `Gamepad`
36
36
  - **Tree-shakeable** — `sideEffects: false`, so unused modules are dropped from your production bundle
37
37
  - **TypeScript-first** — strict mode, full `.d.ts` declarations, no `any`
38
38
 
@@ -44,6 +44,25 @@ The goal is simple: **it should look and sound like a Spectrum, but run like a m
44
44
 
45
45
  ---
46
46
 
47
+ ## Examples
48
+
49
+ The repository includes small static examples that import `../../dist/index.js`
50
+ directly, so each one doubles as a browser-checkable API recipe:
51
+
52
+ | Example | Shows |
53
+ |---------|-------|
54
+ | `examples/ay-music/` | AY channels A/B/C plus beeper SFX as a four-voice Spectrum-style setup |
55
+ | `examples/pixel-collision/` | AABB false positives vs `bitmapPixelMask()` / `masksOverlap()` |
56
+ | `examples/particles/` | Allocation-free particle pools for sparks, smoke, and explosions |
57
+ | `examples/i18n-runtime/` | Runtime language switching with `pickLocale()` and persisted preference |
58
+ | `examples/bitmap-attrs/` | `Bitmap`, `AttrMap`, mirroring, colour clash, and `inkOnly` rendering |
59
+ | `examples/save-slots/` | Save profiles, auto/manual slots, latest-slot restore, throttling, and delete |
60
+
61
+ Build first with `npm run build`, then serve the repository root and open any
62
+ example path in the browser.
63
+
64
+ ---
65
+
47
66
  ## Installation
48
67
 
49
68
  ### From npm (recommended)
@@ -142,7 +161,7 @@ No prior game development experience needed. You need basic JavaScript/TypeScrip
142
161
 
143
162
  | Tool | Where to get it | Why |
144
163
  |------|----------------|-----|
145
- | **Node.js 18+** | [nodejs.org](https://nodejs.org) | Runs npm — the package manager we use to install zx-kit |
164
+ | **Node.js 22+** | [nodejs.org](https://nodejs.org) | Runs npm — the package manager we use to install zx-kit |
146
165
  | **A code editor** | [code.visualstudio.com](https://code.visualstudio.com) (free) | Edits your source files |
147
166
  | **A terminal** | Built into macOS/Linux; use PowerShell on Windows | Runs commands |
148
167
 
@@ -188,7 +207,7 @@ Open `package.json` and replace it with the following. The two key additions are
188
207
  "build": "vite build"
189
208
  },
190
209
  "dependencies": {
191
- "zx-kit": "^0.15.0"
210
+ "zx-kit": "^0.25.0"
192
211
  },
193
212
  "devDependencies": {
194
213
  "vite": "^6.0.0"
@@ -535,10 +554,10 @@ requestAnimationFrame(loop)
535
554
  | Module | What it provides |
536
555
  |--------|-----------------|
537
556
  | [`ay.ts`](#ayts--ay-3-8912-melodik-audio) | AY chip emulator: 3-channel tone, LFSR noise, 16 envelope shapes |
538
- | [`renderer.ts`](#rendererts--canvas-renderer) | Canvas setup, sprites, text, scanlines, border flash |
557
+ | [`renderer.ts`](#rendererts--canvas-renderer) | Canvas setup, 8x8 sprites, arbitrary-size bitmaps, attribute maps, text, scanlines, border flash |
539
558
  | [`audio.ts`](#audiots--beeper-audio) | 1-bit beeper: square-wave notes, patterns, volume control |
540
559
  | [`ui.ts`](#uits--ui-widgets) | Boxes, frames, panel titles, progress bars + instrumentation widgets (dotted grids, segmented bars, fluid tanks, dials, text compass) |
541
- | [`input.ts`](#inputts--keyboard-input) | Movement with key-repeat, action flags, state reset |
560
+ | [`input.ts`](#inputts--keyboard--gamepad-input) | Keyboard/gamepad movement, key-repeat, action flags, state reset |
542
561
  | [`sprite.ts`](#spritets--free-roaming-sprites) | Sprites: position, velocity, gravity, flip, render |
543
562
  | [`collision.ts`](#collisionts--collision-detection) | AABB overlap + rect-based tile resolution, pixel-precise mask overlap and tile checks |
544
563
  | [`animation.ts`](#animationts--frame-timer--tween) | Frame-timer for sprite strips, position tween between two points |
@@ -552,6 +571,7 @@ requestAnimationFrame(loop)
552
571
  | [`palette.ts`](#palettets--color-constants) | 15 Spectrum colors, `SpectrumColor` type, `CELL`, `SCALE` |
553
572
  | [`font.ts`](#fontts--rom-bitmap-font) | 96-character ROM font, raw bitmap access |
554
573
  | [`i18n.ts`](#i18nts--runtime-locale-selection) | Type-safe runtime locale selection for translated string packs |
574
+ | [`lighting.ts`](#lightingts--dithered-cave-darkness) | Dithered cave darkness: pre-baked level tiles + dirty-cell buffer, one blit/frame (no per-frame putImageData) |
555
575
 
556
576
  ---
557
577
 
@@ -907,6 +927,37 @@ curveDisplay(ctx) // default strength
907
927
  curveDisplay(ctx, 256, 208, 6) // stronger warp
908
928
  ```
909
929
 
930
+ ### `Bitmap` interface
931
+
932
+ An arbitrary-size monochrome bitmap. Width must be a positive multiple of 8 so
933
+ each row is byte-aligned. `data` is row-major; bit 7 is the leftmost pixel in
934
+ each byte.
935
+
936
+ ```ts
937
+ interface Bitmap {
938
+ data: Uint8Array
939
+ width: number
940
+ height: number
941
+ }
942
+ ```
943
+
944
+ Use `Bitmap` for 16x16 enemies, 16x24 heroes, 32x32 bosses, tall objects, and
945
+ anything that outgrows the classic 8x8 `drawSprite()` format.
946
+
947
+ ### `createBitmap(data, width, height): Bitmap`
948
+
949
+ Builds a `Bitmap` from packed bytes and validates the dimensions and byte
950
+ count immediately. Throws if width is not byte-aligned, height is invalid, or
951
+ the data length does not match `(width / 8) * height`.
952
+
953
+ ```ts
954
+ const HERO = createBitmap(new Uint8Array([
955
+ 0x03, 0xC0,
956
+ 0x07, 0xE0,
957
+ // ...22 more 16px-wide rows
958
+ ]), 16, 24)
959
+ ```
960
+
910
961
  ### `createBitmapFromRows(rows): Bitmap`
911
962
 
912
963
  Builds an arbitrary-size `Bitmap` from readable pixel-art rows instead of
@@ -937,6 +988,105 @@ The returned object is the same `Bitmap` shape produced by `createBitmap()`, so
937
988
  it works with `drawBitmap`, `drawBitmapAttrs`, `mirrorBitmap`, and collision
938
989
  helpers such as `bitmapPixelMask`.
939
990
 
991
+ ### `drawBitmap(ctx, bitmap, x, y, ink, paper?, inkOnly?): void`
992
+
993
+ Draws an arbitrary-size `Bitmap`. The colour model has three modes, ordered by how much of the background they disturb:
994
+
995
+ | Call | Paints | Touches the background? |
996
+ |------|--------|-------------------------|
997
+ | `drawBitmap(ctx, bmp, x, y, ink)` | only the set ink pixels | no — transparent overlay |
998
+ | `drawBitmap(ctx, bmp, x, y, ink, paper)` | a full `width×height` paper rectangle, then ink pixels on top | yes — the whole bounding box |
999
+ | `drawBitmap(ctx, bmp, x, y, ink, paper, true)` | only the set ink pixels; `paper` is ignored | no |
1000
+
1001
+ `inkOnly` (last parameter, default `false`) **suppresses the paper rectangle even when a `paper` colour is supplied.** For `drawBitmap` this is functionally identical to omitting `paper` — its value is ergonomic: keep a sprite's configured `paper` and toggle the opaque box on or off with a boolean, instead of conditionally choosing whether to pass the argument at the call site.
1002
+
1003
+ ### `mirrorBitmap(src): Bitmap`
1004
+
1005
+ Returns a horizontally flipped copy of a `Bitmap`. The original is not
1006
+ modified. Use it at module load time to derive left-facing sprites from one
1007
+ right-facing definition.
1008
+
1009
+ ```ts
1010
+ const HERO_RIGHT = createBitmapFromRows([...])
1011
+ const HERO_LEFT = mirrorBitmap(HERO_RIGHT)
1012
+ ```
1013
+
1014
+ ### `AttrMap` interface
1015
+
1016
+ Per-8x8-cell ink and paper colours for a `Bitmap`, mirroring the ZX Spectrum
1017
+ attribute buffer. `cols` must match `bitmap.width / 8`; `rows` must match
1018
+ `bitmap.height / 8`.
1019
+
1020
+ ```ts
1021
+ interface AttrMap {
1022
+ readonly cols: number
1023
+ readonly rows: number
1024
+ readonly inks: readonly SpectrumColor[]
1025
+ readonly papers?: readonly SpectrumColor[]
1026
+ }
1027
+ ```
1028
+
1029
+ Omit `papers` for transparent per-cell ink rendering, or provide papers for
1030
+ the authentic colour-clash look.
1031
+
1032
+ ### `createAttrMap(cols, rows, inks, papers?): AttrMap`
1033
+
1034
+ Builds an `AttrMap` with validation. `inks` must contain `cols * rows` colours.
1035
+ `papers` can be omitted, supplied as a matching per-cell array, or supplied as
1036
+ one colour to fill every cell.
1037
+
1038
+ ```ts
1039
+ const HERO_ATTRS = createAttrMap(2, 3, [
1040
+ C.B_YELLOW, C.B_YELLOW,
1041
+ C.B_RED, C.B_MAGENTA,
1042
+ C.B_CYAN, C.B_GREEN,
1043
+ ], C.BLACK)
1044
+ ```
1045
+
1046
+ ### `drawBitmapAttrs(ctx, bitmap, attrs, x, y, inkOnly?): void`
1047
+
1048
+ Renders a `Bitmap` with a per-cell `AttrMap` — each 8×8 cell carries its own `(ink, paper)`, the authentic Spectrum attribute model. Here `inkOnly` is **not** redundant: it keeps every per-cell *ink* colour but skips all per-cell *paper* fills. One fully-coloured `AttrMap` (with `papers` for the boxed look on a plain background) then renders two ways — flip `inkOnly` per frame, with no second paper-less map to build and keep in sync. Dimension validation still throws under `inkOnly`: the flag changes what is painted, never the contract.
1049
+
1050
+ ```ts
1051
+ // chaosbunny — a blue rabbit with a white belly, hopping through a dark cave:
1052
+ drawBitmapAttrs(ctx, BUNNY, BUNNY_ATTRS, x, y, true)
1053
+ // → per-cell blue/white inks preserved, but no black 8×8 blocks stamped onto
1054
+ // the cave behind it. The rabbit reads by its own silhouette.
1055
+ ```
1056
+
1057
+ ### `mirrorAttrMap(attrs): AttrMap`
1058
+
1059
+ Returns a horizontally flipped copy of an `AttrMap`, reversing each attribute
1060
+ row. Pair it with `mirrorBitmap()` so a mirrored sprite keeps its colours on
1061
+ the matching 8x8 cells.
1062
+
1063
+ ```ts
1064
+ const HERO_LEFT = mirrorBitmap(HERO_RIGHT)
1065
+ const HERO_LEFT_ATTRS = mirrorAttrMap(HERO_RIGHT_ATTRS)
1066
+ ```
1067
+
1068
+ ### Why does `inkOnly` exist? (and why is it, honestly, a little bit of debt?)
1069
+
1070
+ This is the kind of decision worth writing down, because the "obvious" answer is the wrong one.
1071
+
1072
+ **Why was the box there in the first place?** Because that *is* the ZX Spectrum. The real machine had a 256×192 one-bit pixel bitmap and a *separate* 32×24 attribute map: one ink + one paper + bright + flash per 8×8 cell, nothing finer. zx-kit's `drawBitmapAttrs`, and the `paper` argument of `drawBitmap`, model exactly that constraint (added in v0.19.0, *"authentic Spectrum colour clash"*). Fill the cell's paper, draw the ink on top. That's the look, and removing it would make the engine less of a Spectrum, not more.
1073
+
1074
+ **So why fight it?** Because the hardware had a *second* technique we had quietly skipped — the **masked sprite.** Cheap games stamped attributes and lived with "colour clash," the famous bleeding of one sprite's colours onto whatever 8×8 cell it touched. The games whose movement looked clean used a *mask*: a second bitmap ANDed into the screen to punch a hole in the exact shape of the sprite, then the sprite ORed in. Only the sprite's own pixels changed — no paper block, no bleed onto the neighbour. `inkOnly` is the modern per-pixel-canvas equivalent of a masked sprite, and on a canvas it comes almost for free: painting only the set pixels already leaves everything else untouched.
1075
+
1076
+ **What broke without it?** The same character that broke collision. Picture a Dizzy-style sprite with `paper: C.BLACK` drawn next to a white leaf. The visible pixels never touch the leaf — but the paper rectangle (or the 8×8 paper cell) does, and it paints the leaf's edge black. The bounding box committed the crime; the sprite took the blame. We met this exact bounding-box sin once before, in collision (v0.21.0, *"the Dizzy problem"*): the AABB overlapped a platform the pixels didn't. Same Dizzy, same box, different subsystem — and rendering needed the same answer collision got: *stop trusting the box, trust the pixels.*
1077
+
1078
+ **Then why call it debt?** Because the truly faithful fix is bigger than a boolean. A real masking layer would carry an explicit mask bitmap per sprite, or compose against an off-screen attribute buffer the way the hardware did. `inkOnly` is the ~12-line, zero-allocation, fully backwards-compatible shortcut to 90% of that value. For a hobby engine whose stated philosophy is *less is more*, that is the right call — but it is worth being honest that it is a shortcut, not the model. The day a game needs a paper silhouette that hugs the sprite *outline* (paper behind the shape, but not the box) is the day this flag stops being enough and the masking layer earns its place.
1079
+
1080
+ ### Tested
1081
+
1082
+ Both functions are covered by the renderer suite, including the new branch and its edges:
1083
+
1084
+ - `inkOnly` suppresses the paper rectangle / per-cell paper blocks (zero fills for an all-zero sprite; ink-only fills for an all-ones sprite);
1085
+ - per-cell ink colours survive `inkOnly`;
1086
+ - the default (`false`) still fills paper — a regression guard so the flag can never silently change an existing game;
1087
+ - `drawBitmap(..., inkOnly)` matches transparent rendering, and `drawBitmapAttrs(..., inkOnly)` matches a paper-less `AttrMap`, pixel-for-pixel;
1088
+ - **exception path:** `drawBitmapAttrs` still throws on an `AttrMap`/`Bitmap` dimension mismatch with `inkOnly` set.
1089
+
940
1090
  ---
941
1091
 
942
1092
  ## `audio.ts` — Beeper Audio
@@ -1103,6 +1253,8 @@ Five stateless primitives for HUDs, dashboards and tactical displays — gauges,
1103
1253
 
1104
1254
  #### `drawDottedGrid(ctx, options): void`
1105
1255
 
1256
+ Options type: `DrawDottedGridOptions`.
1257
+
1106
1258
  Regularly-spaced dot pattern. Useful for radar / sonar screens, tactical scanner overlays, debug grids, stippled backgrounds, alien-invasion detection grids.
1107
1259
 
1108
1260
  ```ts
@@ -1129,6 +1281,8 @@ drawDottedGrid(ctx, {
1129
1281
 
1130
1282
  #### `drawSegmentedBar(ctx, options): void`
1131
1283
 
1284
+ Options type: `DrawSegmentedBarOptions`.
1285
+
1132
1286
  Discrete segmented bar — health, ammo, shield, fuel, stamina, mana, battery, damage. Computes `round(value/max * segments)` filled segments.
1133
1287
 
1134
1288
  Two colouring strategies, mutually exclusive:
@@ -1172,6 +1326,8 @@ drawSegmentedBar(ctx, {
1172
1326
 
1173
1327
  #### `drawTank(ctx, options): void`
1174
1328
 
1329
+ Options type: `DrawTankOptions`.
1330
+
1175
1331
  Fluid container — ballast tanks, fuel gauges, water reservoirs, lava levels, oil drums, chemical canisters. Liquid fills from the bottom up.
1176
1332
 
1177
1333
  ```ts
@@ -1205,6 +1361,8 @@ drawTank(ctx, {
1205
1361
 
1206
1362
  #### `drawDial(ctx, options): void`
1207
1363
 
1364
+ Options type: `DrawDialOptions`.
1365
+
1208
1366
  Circular analog gauge with movable needle — RPM, speedometer, fuel, temperature, volume knob. Decorations (face fill, rim outline, tick marks) are optional; the needle alone is the minimum visible output.
1209
1367
 
1210
1368
  ```ts
@@ -1243,6 +1401,8 @@ Angles use canvas convention: `0` = right, `π/2` = down, `π` = left, `3π/2` =
1243
1401
 
1244
1402
  #### `drawCompassText(ctx, options): void`
1245
1403
 
1404
+ Options type: `DrawCompassTextOptions`.
1405
+
1246
1406
  Text-based heading indicator in the classic 80s tactical-display style `[W [NW] N [NE] E]` — current direction in the centre, highlighted, with two neighbouring directions on each side. Heading rounds to the nearest 45° step.
1247
1407
 
1248
1408
  ```ts
@@ -1320,9 +1480,11 @@ appPhase = 'intro'
1320
1480
 
1321
1481
  ---
1322
1482
 
1323
- ## `input.ts` — Keyboard Input
1483
+ ## `input.ts` — Keyboard & Gamepad Input
1324
1484
 
1325
- Handles directional movement with configurable key-repeat (immediate on first press, configurable auto-repeat delay on hold) plus single-consume flags for action keys. Call `initInput()` once at startup, then `tickMovement(dt)` every frame.
1485
+ Handles directional movement with configurable keyboard repeat, transparent
1486
+ gamepad polling, and single-consume flags for action buttons. Call
1487
+ `initInput()` once at startup, then `tickMovement(dt)` every frame.
1326
1488
 
1327
1489
  ### `Direction` type
1328
1490
 
@@ -1336,6 +1498,11 @@ Attaches `keydown`/`keyup` listeners. Idempotent — safe to call multiple times
1336
1498
 
1337
1499
  Default key bindings: arrows = movement, `W A S D` = also movement, `F` = flag action, `P` = pause, `Ctrl+Shift+B` = debug toggle.
1338
1500
 
1501
+ Gamepad support is automatic. `tickMovement()` polls the first connected
1502
+ gamepad via the browser Gamepad API: D-pad / left stick move, button 0 maps to
1503
+ `consumeFlag()`, button 9 maps to `consumePause()`, button 3 maps to
1504
+ `consumeDebug()`, and any button triggers `consumeAnyKey()`.
1505
+
1339
1506
  ```ts
1340
1507
  initInput() // default: 150ms initial delay, 80ms repeat
1341
1508
  initInput(200, 60) // custom timing
@@ -1343,7 +1510,9 @@ initInput(200, 60) // custom timing
1343
1510
 
1344
1511
  ### `tickMovement(dtMs): Direction | null`
1345
1512
 
1346
- Returns the active movement direction for this frame, or `null`. Handles the delay/repeat state machine internally. Call exactly once per frame.
1513
+ Returns the active movement direction for this frame, or `null`. Handles the
1514
+ keyboard delay/repeat state machine and gamepad polling internally. Call
1515
+ exactly once per frame.
1347
1516
 
1348
1517
  ```ts
1349
1518
  const dir = tickMovement(dt)
@@ -1359,10 +1528,10 @@ Each function returns `true` exactly once per key press, then resets to `false`.
1359
1528
 
1360
1529
  | Function | Default key | Typical use |
1361
1530
  |----------|-------------|-------------|
1362
- | `consumeFlag()` | `F` | Flag / unflag a tile |
1363
- | `consumePause()` | `P` | Pause / unpause |
1364
- | `consumeDebug()` | `Ctrl+Shift+B` | Toggle debug overlay |
1365
- | `consumeAnyKey()` | Any key | Dismiss overlays, start game |
1531
+ | `consumeFlag()` | `F` / gamepad button 0 | Flag / unflag a tile |
1532
+ | `consumePause()` | `P` / gamepad button 9 | Pause / unpause |
1533
+ | `consumeDebug()` | `Ctrl+Shift+B` / gamepad button 3 | Toggle debug overlay |
1534
+ | `consumeAnyKey()` | Any key / any gamepad button | Dismiss overlays, start game |
1366
1535
 
1367
1536
  ```ts
1368
1537
  if (consumeFlag()) toggleFlag(playerX, playerY)
@@ -1876,6 +2045,23 @@ for (const e of enemies) {
1876
2045
  | `deadzoneW`, `deadzoneH` | Deadzone size — target may move ±`deadzoneW/2` from centre before scrolling |
1877
2046
  | `targetX`, `targetY` | Current follow target (set via `setCameraTarget`) |
1878
2047
 
2048
+ ### `CameraOptions` interface
2049
+
2050
+ Options passed to `createCamera()`. `viewW`, `viewH`, `worldW`, and `worldH`
2051
+ are required; `lerp`, `deadzoneW`, and `deadzoneH` are optional.
2052
+
2053
+ ```ts
2054
+ interface CameraOptions {
2055
+ viewW: number
2056
+ viewH: number
2057
+ worldW: number
2058
+ worldH: number
2059
+ lerp?: number
2060
+ deadzoneW?: number
2061
+ deadzoneH?: number
2062
+ }
2063
+ ```
2064
+
1879
2065
  ### `createCamera(opts): Camera`
1880
2066
 
1881
2067
  Creates a camera at world origin `(0, 0)`. `lerp` defaults to `1` (snap), deadzones default to `0`.
@@ -2332,13 +2518,23 @@ interface ParticleSystem {
2332
2518
  }
2333
2519
  ```
2334
2520
 
2521
+ ### `Ranged` type
2522
+
2523
+ Several emitter options accept either a fixed value or a `[min, max]` range.
2524
+
2525
+ ```ts
2526
+ type Ranged = number | readonly [number, number]
2527
+ ```
2528
+
2335
2529
  ### `createParticleSystem(capacity): ParticleSystem`
2336
2530
 
2337
2531
  Creates a pool of `capacity` particles, all inactive. Throws when `capacity` is not a positive integer.
2338
2532
 
2339
2533
  ### `emitParticles(ps, opts): number`
2340
2534
 
2341
- Emits up to `opts.count` particles and returns the number actually emitted (fewer when the pool is full). Throws when `count` is negative or non-integer.
2535
+ Emits up to `opts.count` particles and returns the number actually emitted
2536
+ (fewer when the pool is full). Throws when `count` is negative or non-integer.
2537
+ The options object is exported as `EmitOptions`.
2342
2538
 
2343
2539
  | Option | Type | Default | Meaning |
2344
2540
  |--------|------|---------|---------|
@@ -2424,6 +2620,55 @@ Hashes a string to an unsigned 32-bit integer (FNV-1a). Deterministic; exported
2424
2620
 
2425
2621
  ---
2426
2622
 
2623
+ ## `lighting.ts` — Dithered Cave Darkness
2624
+
2625
+ The ZX way to fake light: hard 8×8 light pools with an ordered (Bayer) **dither** edge — no alpha gradients. The look of *Knight Lore* / *Head over Heels*, not modern soft shadows.
2626
+
2627
+ Done the naive way (recompute a full-screen `ImageData` and `putImageData` it every frame) this is a real CPU/upload hog — it measured ~27% of a frame in an actual game. This module instead **pre-renders the dither for each darkness level to a tiny tile, darkens the view cell-by-cell into a persistent buffer (repainting only cells whose level changed), and blits the buffer with one `drawImage`** — no per-frame `putImageData`.
2628
+
2629
+ You own the *policy* (where it's dark) via a per-cell callback; the module owns the fast *rendering*.
2630
+
2631
+ ### `Light` interface
2632
+
2633
+ ```ts
2634
+ interface Light { x: number; y: number; radius: number; intensity: number } // intensity 0..1
2635
+ ```
2636
+
2637
+ ### `brightnessAt(px, py, lights): number`
2638
+
2639
+ Brightest attenuated light at a point — `max((1 - dist/radius) * intensity)` over all lights, clamped to `0..1`. Turn it into darkness with `1 - brightnessAt(...)`. Pure.
2640
+
2641
+ ### `ditherBlack(px, py, amount): boolean`
2642
+
2643
+ The ordered-dither rule used to bake the tiles: is pixel `(px, py)` black at darkness `amount` (0..1)? Pure and deterministic — handy for tests or custom effects.
2644
+
2645
+ ### `createDarknessLayer(width, height, levels?): DarknessLayer`
2646
+
2647
+ Builds a view-sized overlay: pre-bakes `levels` dither tiles (default **8** — more = smoother), a persistent buffer, and a per-cell level cache. Call **once**; reuse across frames. Throws if `levels < 2`.
2648
+
2649
+ ### `renderDarkness(layer, ctx, darknessAt): void`
2650
+
2651
+ Darkens `ctx` for this frame. `darknessAt(col, row)` returns the darkness of each 8×8 cell — **0 = lit, 1 = pitch black** (clamped, then quantised to the layer's levels). Only cells whose level changed since the last call are repainted; then the buffer is blitted once.
2652
+
2653
+ ```ts
2654
+ import { createDarknessLayer, renderDarkness, brightnessAt, CELL } from 'zx-kit'
2655
+
2656
+ const dark = createDarknessLayer(256, 192) // once
2657
+
2658
+ // each frame, after drawing the scene, before the HUD:
2659
+ const lights = [{ x: playerX, y: playerY, radius: 72, intensity: 1 }]
2660
+ renderDarkness(dark, ctx, (col, row) => {
2661
+ const b = brightnessAt(col * CELL + 4, row * CELL + 4, lights)
2662
+ return 1 - b // 0 = lit … 1 = dark
2663
+ })
2664
+ ```
2665
+
2666
+ The `darknessAt` callback is where you add **depth gradients** (darker the deeper you are), fog, flashing — anything; the renderer stays fast because it only repaints cells whose quantised level actually changed.
2667
+
2668
+ > Lights are in **screen** pixels (apply the camera yourself). Rendering needs a real canvas; in a headless test environment the layer degrades to a no-op blit while the level math still runs.
2669
+
2670
+ ---
2671
+
2427
2672
  ## Architecture
2428
2673
 
2429
2674
  ### Module structure
package/dist/index.d.ts CHANGED
@@ -16,4 +16,5 @@ export * from './camera.js';
16
16
  export * from './scene.js';
17
17
  export * from './save.js';
18
18
  export * from './i18n.js';
19
+ export * from './lighting.js';
19
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA;AAC5B,cAAc,SAAS,CAAA;AACvB,cAAc,WAAW,CAAA;AACzB,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,SAAS,CAAA;AACvB,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA;AAC5B,cAAc,SAAS,CAAA;AACvB,cAAc,WAAW,CAAA;AACzB,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,SAAS,CAAA;AACvB,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,eAAe,CAAA"}
package/dist/index.js CHANGED
@@ -16,4 +16,5 @@ export * from './camera.js';
16
16
  export * from './scene.js';
17
17
  export * from './save.js';
18
18
  export * from './i18n.js';
19
+ export * from './lighting.js';
19
20
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA;AAC5B,cAAc,SAAS,CAAA;AACvB,cAAc,WAAW,CAAA;AACzB,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,SAAS,CAAA;AACvB,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA;AAC5B,cAAc,SAAS,CAAA;AACvB,cAAc,WAAW,CAAA;AACzB,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,SAAS,CAAA;AACvB,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,eAAe,CAAA"}
@@ -0,0 +1,45 @@
1
+ /** A point light: position (screen px), reach `radius` (px) and `intensity` 0..1. */
2
+ export interface Light {
3
+ x: number;
4
+ y: number;
5
+ radius: number;
6
+ intensity: number;
7
+ }
8
+ /**
9
+ * The ordered-dither rule: is pixel `(px, py)` black at darkness `amount` (0..1)?
10
+ * Pure and deterministic — used to bake the level tiles, and handy to test.
11
+ */
12
+ export declare function ditherBlack(px: number, py: number, amount: number): boolean;
13
+ /**
14
+ * Brightest attenuated light at a point: `max((1 - dist/radius) * intensity)`
15
+ * over all lights, clamped to 0..1. Turn it into darkness with `1 - brightnessAt(...)`.
16
+ */
17
+ export declare function brightnessAt(px: number, py: number, lights: readonly Light[]): number;
18
+ /** A view-sized darkness overlay with pre-baked dither tiles + a cached buffer. */
19
+ export interface DarknessLayer {
20
+ readonly width: number;
21
+ readonly height: number;
22
+ readonly levels: number;
23
+ readonly cols: number;
24
+ readonly rows: number;
25
+ /** Pre-rendered 8×8 dither tiles, index 0 (lit, `null`) … levels-1 (darkest). */
26
+ readonly tiles: ReadonlyArray<HTMLCanvasElement | null>;
27
+ /** Persistent darkness buffer (view-sized), blitted each frame. */
28
+ readonly buffer: HTMLCanvasElement | null;
29
+ /** Last level drawn per cell, row-major; -1 = never drawn (forces a repaint). */
30
+ readonly cellLevel: Int16Array;
31
+ }
32
+ /**
33
+ * Creates a darkness layer sized to the view. `levels` is the number of darkness
34
+ * steps (default 8) — more is a smoother dither for a little more memory. Call
35
+ * once; reuse across frames.
36
+ */
37
+ export declare function createDarknessLayer(width: number, height: number, levels?: number): DarknessLayer;
38
+ /**
39
+ * Renders dithered darkness onto `ctx`. `darknessAt(col, row)` returns the
40
+ * darkness of each 8×8 cell: **0 = lit**, **1 = pitch black** (values are clamped
41
+ * and quantised to the layer's `levels`). Only cells whose level changed since the
42
+ * last call are repainted on the cached buffer; the buffer is then blitted once.
43
+ */
44
+ export declare function renderDarkness(layer: DarknessLayer, ctx: CanvasRenderingContext2D, darknessAt: (col: number, row: number) => number): void;
45
+ //# sourceMappingURL=lighting.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lighting.d.ts","sourceRoot":"","sources":["../src/lighting.ts"],"names":[],"mappings":"AAkCA,qFAAqF;AACrF,MAAM,WAAW,KAAK;IACpB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;CAClB;AAMD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAE3E;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,MAAM,CAarF;AAED,mFAAmF;AACnF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,iFAAiF;IACjF,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAA;IACvD,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAA;IACzC,iFAAiF;IACjF,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAA;CAC/B;AAmBD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,SAAI,GAAG,aAAa,CAkB5F;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,wBAAwB,EAC7B,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,GAC/C,IAAI,CAwBN"}
@@ -0,0 +1,138 @@
1
+ /**
2
+ * @module lighting
3
+ *
4
+ * **Dithered cave darkness** — the ZX way to fake light: hard 8×8 light pools
5
+ * with an ordered (Bayer) dither edge, no alpha gradients. Think *Knight Lore*,
6
+ * not modern soft shadows.
7
+ *
8
+ * Built for speed. The naive way (recompute a full-screen `ImageData` and
9
+ * `putImageData` it every frame) is a CPU/upload hog — it was ~27% of a frame in
10
+ * a real game. Instead:
11
+ *
12
+ * 1. The dither for each darkness **level** is pre-rendered once to a tiny 8×8
13
+ * tile ({@link createDarknessLayer}).
14
+ * 2. The view is darkened **cell by cell** into a persistent buffer, and only
15
+ * cells whose level **changed** since the last frame are repainted.
16
+ * 3. The whole buffer is blitted with **one `drawImage`** — no per-frame
17
+ * `putImageData`.
18
+ *
19
+ * The game supplies a per-cell darkness via a callback, so it owns the *policy*
20
+ * (lights, depth gradients, fog…) while this module owns the fast *rendering*.
21
+ * {@link brightnessAt} is a ready helper for the common "pools of light" case.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * const dark = createDarknessLayer(256, 192) // once, view-sized
26
+ * // each frame, after drawing the scene:
27
+ * renderDarkness(dark, ctx, (col, row) => {
28
+ * const b = brightnessAt(col * CELL + 4, row * CELL + 4, lights)
29
+ * return 1 - b // 0 = lit, 1 = pitch black
30
+ * })
31
+ * ```
32
+ */
33
+ import { CELL } from './palette.js';
34
+ // Dispersed 4×4 Bayer matrix (values 0..15), row-major — drives the stipple.
35
+ // 8×8 cells are a multiple of 4, so tiles dither seamlessly across cell borders.
36
+ const BAYER4 = [0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5];
37
+ /**
38
+ * The ordered-dither rule: is pixel `(px, py)` black at darkness `amount` (0..1)?
39
+ * Pure and deterministic — used to bake the level tiles, and handy to test.
40
+ */
41
+ export function ditherBlack(px, py, amount) {
42
+ return (BAYER4[((py & 3) << 2) | (px & 3)] + 0.5) / 16 < amount;
43
+ }
44
+ /**
45
+ * Brightest attenuated light at a point: `max((1 - dist/radius) * intensity)`
46
+ * over all lights, clamped to 0..1. Turn it into darkness with `1 - brightnessAt(...)`.
47
+ */
48
+ export function brightnessAt(px, py, lights) {
49
+ let b = 0;
50
+ for (const l of lights) {
51
+ if (l.radius <= 0)
52
+ continue;
53
+ const dx = px - l.x;
54
+ const dy = py - l.y;
55
+ const d = Math.sqrt(dx * dx + dy * dy);
56
+ if (d < l.radius) {
57
+ const c = (1 - d / l.radius) * l.intensity;
58
+ if (c > b)
59
+ b = c;
60
+ }
61
+ }
62
+ return b > 1 ? 1 : b < 0 ? 0 : b;
63
+ }
64
+ /** Bakes one 8×8 dither tile for darkness `amount`, or `null` when fully lit. */
65
+ function makeTile(amount) {
66
+ if (amount <= 0 || typeof document === 'undefined')
67
+ return null;
68
+ const c = document.createElement('canvas');
69
+ c.width = CELL;
70
+ c.height = CELL;
71
+ const ctx = c.getContext('2d');
72
+ if (!ctx)
73
+ return null;
74
+ ctx.fillStyle = '#000';
75
+ for (let y = 0; y < CELL; y++) {
76
+ for (let x = 0; x < CELL; x++) {
77
+ if (ditherBlack(x, y, amount))
78
+ ctx.fillRect(x, y, 1, 1);
79
+ }
80
+ }
81
+ return c;
82
+ }
83
+ /**
84
+ * Creates a darkness layer sized to the view. `levels` is the number of darkness
85
+ * steps (default 8) — more is a smoother dither for a little more memory. Call
86
+ * once; reuse across frames.
87
+ */
88
+ export function createDarknessLayer(width, height, levels = 8) {
89
+ if (!Number.isInteger(levels) || levels < 2) {
90
+ throw new Error(`createDarknessLayer: levels must be an integer >= 2, got ${levels}`);
91
+ }
92
+ const cols = Math.ceil(width / CELL);
93
+ const rows = Math.ceil(height / CELL);
94
+ const tiles = [];
95
+ for (let i = 0; i < levels; i++)
96
+ tiles.push(makeTile(i / (levels - 1)));
97
+ let buffer = null;
98
+ if (typeof document !== 'undefined') {
99
+ buffer = document.createElement('canvas');
100
+ buffer.width = width;
101
+ buffer.height = height;
102
+ }
103
+ const cellLevel = new Int16Array(cols * rows).fill(-1);
104
+ return { width, height, levels, cols, rows, tiles, buffer, cellLevel };
105
+ }
106
+ /**
107
+ * Renders dithered darkness onto `ctx`. `darknessAt(col, row)` returns the
108
+ * darkness of each 8×8 cell: **0 = lit**, **1 = pitch black** (values are clamped
109
+ * and quantised to the layer's `levels`). Only cells whose level changed since the
110
+ * last call are repainted on the cached buffer; the buffer is then blitted once.
111
+ */
112
+ export function renderDarkness(layer, ctx, darknessAt) {
113
+ const { buffer, tiles, levels, cols, rows, cellLevel } = layer;
114
+ const bctx = buffer ? buffer.getContext('2d') : null;
115
+ const maxLevel = levels - 1;
116
+ for (let row = 0; row < rows; row++) {
117
+ for (let col = 0; col < cols; col++) {
118
+ let a = darknessAt(col, row);
119
+ a = a < 0 ? 0 : a > 1 ? 1 : a;
120
+ const level = Math.round(a * maxLevel);
121
+ const idx = row * cols + col;
122
+ if (cellLevel[idx] === level)
123
+ continue; // unchanged → skip the repaint
124
+ cellLevel[idx] = level;
125
+ if (bctx) {
126
+ const x = col * CELL;
127
+ const y = row * CELL;
128
+ bctx.clearRect(x, y, CELL, CELL);
129
+ const tile = tiles[level];
130
+ if (tile)
131
+ bctx.drawImage(tile, x, y);
132
+ }
133
+ }
134
+ }
135
+ if (buffer)
136
+ ctx.drawImage(buffer, 0, 0);
137
+ }
138
+ //# sourceMappingURL=lighting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lighting.js","sourceRoot":"","sources":["../src/lighting.ts"],"names":[],"mappings":"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"}
@@ -189,11 +189,20 @@ export declare function createBitmapFromRows(rows: readonly string[]): Bitmap;
189
189
  * Same ink/paper applies to the whole sprite — there is no per-cell colour attribute.
190
190
  * For multi-colour effects, overlay several bitmaps at the same position.
191
191
  *
192
+ * **`inkOnly`** suppresses the `paper` fill even when a `paper` colour is supplied:
193
+ * only the set ink pixels are painted, so the sprite never modifies a single pixel
194
+ * outside its own shape. This kills the "black box bleed" — e.g. a Dizzy sprite with
195
+ * `paper: C.BLACK` sliding next to a white leaf no longer paints the leaf's edge
196
+ * black where its bounding rectangle merely *touches* the leaf's cell. For
197
+ * `drawBitmap` this equals omitting `paper`; the flag lets you keep a configured
198
+ * `paper` and toggle the opaque box on/off without rewriting the call.
199
+ *
192
200
  * @example
193
201
  * drawBitmap(ctx, JETMAN_STAND, x, y, C.B_WHITE, C.BLACK)
194
- * drawBitmap(ctx, ROCKET_BASE, x, y, C.B_YELLOW) // transparent background
202
+ * drawBitmap(ctx, ROCKET_BASE, x, y, C.B_YELLOW) // transparent background
203
+ * drawBitmap(ctx, DIZZY, x, y, C.B_WHITE, C.BLACK, true) // keep paper config, draw ink only
195
204
  */
196
- export declare function drawBitmap(ctx: CanvasRenderingContext2D, bitmap: Bitmap, x: number, y: number, ink: SpectrumColor, paper?: SpectrumColor): void;
205
+ export declare function drawBitmap(ctx: CanvasRenderingContext2D, bitmap: Bitmap, x: number, y: number, ink: SpectrumColor, paper?: SpectrumColor, inkOnly?: boolean): void;
197
206
  /**
198
207
  * Returns a horizontally-flipped copy of `src`. The original is not modified.
199
208
  * Use at module load time to derive left-facing sprites from right-facing definitions.
@@ -260,12 +269,22 @@ export declare function createAttrMap(cols: number, rows: number, inks: Spectrum
260
269
  * The attribute dimensions must match the bitmap exactly:
261
270
  * `attrs.cols * 8 === bitmap.width`, `attrs.rows * 8 === bitmap.height`.
262
271
  *
272
+ * **`inkOnly`** keeps every per-cell *ink* colour but skips all per-cell *paper*
273
+ * fills, so the sprite composites over a busy background by its own silhouette
274
+ * instead of stamping opaque 8×8 paper blocks onto neighbouring tiles. Use one
275
+ * fully-coloured {@link AttrMap} (with `papers` for the authentic boxed look on a
276
+ * plain background) and flip `inkOnly` per frame — no need to build a second
277
+ * paper-less map. This is the multi-colour answer to the "black box bleed".
278
+ *
263
279
  * @example
264
280
  * drawBitmapAttrs(ctx, HERO_BITMAP, HERO_ATTRS, hero.x, hero.y)
265
281
  * // Each 8×8 cell gets the (ink, paper) defined in HERO_ATTRS — yellow head,
266
282
  * // red body, blue legs — exactly like a Jet-Pac sprite crossing attribute cells.
283
+ *
284
+ * drawBitmapAttrs(ctx, HERO_BITMAP, HERO_ATTRS, hero.x, hero.y, true)
285
+ * // Same per-cell inks, but no paper blocks — clean over a detailed background.
267
286
  */
268
- export declare function drawBitmapAttrs(ctx: CanvasRenderingContext2D, bitmap: Bitmap, attrs: AttrMap, x: number, y: number): void;
287
+ export declare function drawBitmapAttrs(ctx: CanvasRenderingContext2D, bitmap: Bitmap, attrs: AttrMap, x: number, y: number, inkOnly?: boolean): void;
269
288
  /**
270
289
  * Returns a horizontally-flipped copy of an {@link AttrMap}. Within each row,
271
290
  * columns are swapped left↔right; row order is preserved.
@@ -1 +1 @@
1
- {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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"}
package/dist/renderer.js CHANGED
@@ -283,14 +283,23 @@ export function createBitmapFromRows(rows) {
283
283
  * Same ink/paper applies to the whole sprite — there is no per-cell colour attribute.
284
284
  * For multi-colour effects, overlay several bitmaps at the same position.
285
285
  *
286
+ * **`inkOnly`** suppresses the `paper` fill even when a `paper` colour is supplied:
287
+ * only the set ink pixels are painted, so the sprite never modifies a single pixel
288
+ * outside its own shape. This kills the "black box bleed" — e.g. a Dizzy sprite with
289
+ * `paper: C.BLACK` sliding next to a white leaf no longer paints the leaf's edge
290
+ * black where its bounding rectangle merely *touches* the leaf's cell. For
291
+ * `drawBitmap` this equals omitting `paper`; the flag lets you keep a configured
292
+ * `paper` and toggle the opaque box on/off without rewriting the call.
293
+ *
286
294
  * @example
287
295
  * drawBitmap(ctx, JETMAN_STAND, x, y, C.B_WHITE, C.BLACK)
288
- * drawBitmap(ctx, ROCKET_BASE, x, y, C.B_YELLOW) // transparent background
296
+ * drawBitmap(ctx, ROCKET_BASE, x, y, C.B_YELLOW) // transparent background
297
+ * drawBitmap(ctx, DIZZY, x, y, C.B_WHITE, C.BLACK, true) // keep paper config, draw ink only
289
298
  */
290
- export function drawBitmap(ctx, bitmap, x, y, ink, paper) {
299
+ export function drawBitmap(ctx, bitmap, x, y, ink, paper, inkOnly = false) {
291
300
  const { data, width, height } = bitmap;
292
301
  const bytesPerRow = width / 8;
293
- if (paper !== undefined) {
302
+ if (paper !== undefined && !inkOnly) {
294
303
  ctx.fillStyle = paper;
295
304
  ctx.fillRect(x, y, width, height);
296
305
  }
@@ -393,12 +402,22 @@ export function createAttrMap(cols, rows, inks, papers) {
393
402
  * The attribute dimensions must match the bitmap exactly:
394
403
  * `attrs.cols * 8 === bitmap.width`, `attrs.rows * 8 === bitmap.height`.
395
404
  *
405
+ * **`inkOnly`** keeps every per-cell *ink* colour but skips all per-cell *paper*
406
+ * fills, so the sprite composites over a busy background by its own silhouette
407
+ * instead of stamping opaque 8×8 paper blocks onto neighbouring tiles. Use one
408
+ * fully-coloured {@link AttrMap} (with `papers` for the authentic boxed look on a
409
+ * plain background) and flip `inkOnly` per frame — no need to build a second
410
+ * paper-less map. This is the multi-colour answer to the "black box bleed".
411
+ *
396
412
  * @example
397
413
  * drawBitmapAttrs(ctx, HERO_BITMAP, HERO_ATTRS, hero.x, hero.y)
398
414
  * // Each 8×8 cell gets the (ink, paper) defined in HERO_ATTRS — yellow head,
399
415
  * // red body, blue legs — exactly like a Jet-Pac sprite crossing attribute cells.
416
+ *
417
+ * drawBitmapAttrs(ctx, HERO_BITMAP, HERO_ATTRS, hero.x, hero.y, true)
418
+ * // Same per-cell inks, but no paper blocks — clean over a detailed background.
400
419
  */
401
- export function drawBitmapAttrs(ctx, bitmap, attrs, x, y) {
420
+ export function drawBitmapAttrs(ctx, bitmap, attrs, x, y, inkOnly = false) {
402
421
  if (attrs.cols * 8 !== bitmap.width || attrs.rows * 8 !== bitmap.height) {
403
422
  throw new Error(`drawBitmapAttrs: attr dimensions ${attrs.cols}×${attrs.rows} (${attrs.cols * 8}×${attrs.rows * 8} px) ` +
404
423
  `do not match bitmap ${bitmap.width}×${bitmap.height}`);
@@ -411,7 +430,7 @@ export function drawBitmapAttrs(ctx, bitmap, attrs, x, y) {
411
430
  const paper = attrs.papers ? attrs.papers[cellIdx] : undefined;
412
431
  const cellX = x + cellCol * 8;
413
432
  const cellY = y + cellRow * 8;
414
- if (paper !== undefined) {
433
+ if (paper !== undefined && !inkOnly) {
415
434
  ctx.fillStyle = paper;
416
435
  ctx.fillRect(cellX, cellY, 8, 8);
417
436
  }
@@ -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.24.2",
3
+ "version": "0.26.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/zrebec/zx-kit.git"