1681-engine 0.5.9 → 0.5.10

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.
Files changed (140) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +3 -0
  3. package/dist/1681-engine.js +501 -438
  4. package/dist/ambient/life/Birds.js +73 -0
  5. package/dist/ambient/life/Butterflies.js +43 -0
  6. package/dist/ambient/life/ChimneySmoke.js +50 -0
  7. package/dist/ambient/life/Drift.js +75 -0
  8. package/dist/ambient/life/Fireflies.js +52 -0
  9. package/dist/ambient/life/lifeMotion.js +49 -0
  10. package/dist/assets/AssetLoader.js +115 -70
  11. package/dist/assets/Prepainter.js +61 -0
  12. package/dist/assets/workerPainter.js +39 -0
  13. package/dist/cjs/electron/electronLike.d.ts +55 -0
  14. package/dist/cjs/electron/electronLike.js +7 -0
  15. package/dist/cjs/electron/index.d.ts +14 -0
  16. package/dist/cjs/electron/index.js +20 -0
  17. package/dist/cjs/electron/lockdown.d.ts +33 -0
  18. package/dist/cjs/electron/lockdown.js +69 -0
  19. package/dist/cjs/electron/lockdownRules.d.ts +28 -0
  20. package/dist/cjs/electron/lockdownRules.js +61 -0
  21. package/dist/cjs/electron/sessionStore.d.ts +40 -0
  22. package/dist/cjs/electron/sessionStore.js +77 -0
  23. package/dist/cjs/electron/shellId.d.ts +22 -0
  24. package/dist/cjs/electron/shellId.js +31 -0
  25. package/dist/cjs/electron/webFiles.d.ts +13 -0
  26. package/dist/cjs/electron/webFiles.js +52 -0
  27. package/dist/cjs/electron/webPatcher.d.ts +80 -0
  28. package/dist/cjs/electron/webPatcher.js +216 -0
  29. package/dist/cjs/electron/webPointers.d.ts +19 -0
  30. package/dist/cjs/electron/webPointers.js +35 -0
  31. package/dist/cjs/package.json +1 -0
  32. package/dist/cjs/updates/index.d.ts +8 -0
  33. package/dist/cjs/updates/index.js +21 -0
  34. package/dist/cjs/updates/manifest.d.ts +73 -0
  35. package/dist/cjs/updates/manifest.js +67 -0
  36. package/dist/cjs/updates/pickUpdate.d.ts +42 -0
  37. package/dist/cjs/updates/pickUpdate.js +52 -0
  38. package/dist/cjs/updates/webPlan.d.ts +20 -0
  39. package/dist/cjs/updates/webPlan.js +34 -0
  40. package/dist/electron/lockdown.js +31 -0
  41. package/dist/electron/lockdownRules.js +42 -0
  42. package/dist/electron/sessionStore.js +48 -0
  43. package/dist/electron/shellId.js +18 -0
  44. package/dist/electron/webFiles.js +36 -0
  45. package/dist/electron/webPatcher.js +147 -0
  46. package/dist/electron/webPointers.js +25 -0
  47. package/dist/electron.js +19 -0
  48. package/dist/input/haptics.js +50 -0
  49. package/dist/net/ApiClient.js +96 -0
  50. package/dist/pixel/lifeArt.js +83 -0
  51. package/dist/pixel.js +63 -58
  52. package/dist/react/ConfirmButton.js +24 -0
  53. package/dist/react/baseCss.js +1 -0
  54. package/dist/react/labels.js +7 -6
  55. package/dist/react/useJsonSelector.js +13 -0
  56. package/dist/react.js +73 -68
  57. package/dist/tilemap/TilemapView.js +57 -32
  58. package/dist/tilemap/autotile.js +103 -0
  59. package/dist/tilemap/collision.js +29 -18
  60. package/dist/tilemap/ldtk.js +21 -0
  61. package/dist/tilemap/ldtkParse.js +191 -0
  62. package/dist/types/ambient/life/Birds.d.ts +50 -0
  63. package/dist/types/ambient/life/Birds.d.ts.map +1 -0
  64. package/dist/types/ambient/life/Butterflies.d.ts +32 -0
  65. package/dist/types/ambient/life/Butterflies.d.ts.map +1 -0
  66. package/dist/types/ambient/life/ChimneySmoke.d.ts +37 -0
  67. package/dist/types/ambient/life/ChimneySmoke.d.ts.map +1 -0
  68. package/dist/types/ambient/life/Drift.d.ts +58 -0
  69. package/dist/types/ambient/life/Drift.d.ts.map +1 -0
  70. package/dist/types/ambient/life/Fireflies.d.ts +43 -0
  71. package/dist/types/ambient/life/Fireflies.d.ts.map +1 -0
  72. package/dist/types/ambient/life/lifeMotion.d.ts +63 -0
  73. package/dist/types/ambient/life/lifeMotion.d.ts.map +1 -0
  74. package/dist/types/assets/AssetLoader.d.ts +20 -0
  75. package/dist/types/assets/AssetLoader.d.ts.map +1 -1
  76. package/dist/types/assets/Prepainter.d.ts +64 -0
  77. package/dist/types/assets/Prepainter.d.ts.map +1 -0
  78. package/dist/types/assets/workerPainter.d.ts +21 -0
  79. package/dist/types/assets/workerPainter.d.ts.map +1 -0
  80. package/dist/types/electron/electronLike.d.ts +56 -0
  81. package/dist/types/electron/electronLike.d.ts.map +1 -0
  82. package/dist/types/electron/index.d.ts +15 -0
  83. package/dist/types/electron/index.d.ts.map +1 -0
  84. package/dist/types/electron/lockdown.d.ts +34 -0
  85. package/dist/types/electron/lockdown.d.ts.map +1 -0
  86. package/dist/types/electron/lockdownRules.d.ts +29 -0
  87. package/dist/types/electron/lockdownRules.d.ts.map +1 -0
  88. package/dist/types/electron/sessionStore.d.ts +41 -0
  89. package/dist/types/electron/sessionStore.d.ts.map +1 -0
  90. package/dist/types/electron/shellId.d.ts +23 -0
  91. package/dist/types/electron/shellId.d.ts.map +1 -0
  92. package/dist/types/electron/webFiles.d.ts +14 -0
  93. package/dist/types/electron/webFiles.d.ts.map +1 -0
  94. package/dist/types/electron/webPatcher.d.ts +81 -0
  95. package/dist/types/electron/webPatcher.d.ts.map +1 -0
  96. package/dist/types/electron/webPointers.d.ts +20 -0
  97. package/dist/types/electron/webPointers.d.ts.map +1 -0
  98. package/dist/types/index.d.ts +15 -2
  99. package/dist/types/index.d.ts.map +1 -1
  100. package/dist/types/input/haptics.d.ts +42 -0
  101. package/dist/types/input/haptics.d.ts.map +1 -0
  102. package/dist/types/net/ApiClient.d.ts +74 -0
  103. package/dist/types/net/ApiClient.d.ts.map +1 -0
  104. package/dist/types/pixel/index.d.ts +1 -0
  105. package/dist/types/pixel/index.d.ts.map +1 -1
  106. package/dist/types/pixel/lifeArt.d.ts +63 -0
  107. package/dist/types/pixel/lifeArt.d.ts.map +1 -0
  108. package/dist/types/react/ConfirmButton.d.ts +26 -0
  109. package/dist/types/react/ConfirmButton.d.ts.map +1 -0
  110. package/dist/types/react/baseCss.d.ts +1 -1
  111. package/dist/types/react/baseCss.d.ts.map +1 -1
  112. package/dist/types/react/index.d.ts +2 -0
  113. package/dist/types/react/index.d.ts.map +1 -1
  114. package/dist/types/react/labels.d.ts +2 -0
  115. package/dist/types/react/labels.d.ts.map +1 -1
  116. package/dist/types/react/useJsonSelector.d.ts +13 -0
  117. package/dist/types/react/useJsonSelector.d.ts.map +1 -0
  118. package/dist/types/tilemap/TilemapView.d.ts +17 -0
  119. package/dist/types/tilemap/TilemapView.d.ts.map +1 -1
  120. package/dist/types/tilemap/autotile.d.ts +95 -0
  121. package/dist/types/tilemap/autotile.d.ts.map +1 -0
  122. package/dist/types/tilemap/collision.d.ts +8 -0
  123. package/dist/types/tilemap/collision.d.ts.map +1 -1
  124. package/dist/types/tilemap/ldtk.d.ts +97 -0
  125. package/dist/types/tilemap/ldtk.d.ts.map +1 -0
  126. package/dist/types/tilemap/ldtkParse.d.ts +26 -0
  127. package/dist/types/tilemap/ldtkParse.d.ts.map +1 -0
  128. package/dist/types/updates/index.d.ts +9 -0
  129. package/dist/types/updates/index.d.ts.map +1 -0
  130. package/dist/types/updates/manifest.d.ts +74 -0
  131. package/dist/types/updates/manifest.d.ts.map +1 -0
  132. package/dist/types/updates/pickUpdate.d.ts +43 -0
  133. package/dist/types/updates/pickUpdate.d.ts.map +1 -0
  134. package/dist/types/updates/webPlan.d.ts +21 -0
  135. package/dist/types/updates/webPlan.d.ts.map +1 -0
  136. package/dist/updates/manifest.js +35 -0
  137. package/dist/updates/pickUpdate.js +27 -0
  138. package/dist/updates/webPlan.js +14 -0
  139. package/dist/updates.js +15 -0
  140. package/package.json +31 -3
@@ -0,0 +1,73 @@
1
+ import { birdFrame as x, flockSlot as m } from "./lifeMotion.js";
2
+ class b {
3
+ constructor(s, t) {
4
+ this.options = t, this.snap = t.snap ?? !0, this.random = t.random ?? Math.random;
5
+ const e = t.maxFlock ?? 6;
6
+ for (let i = 0; i < e; i++) {
7
+ const d = s.add.image(0, 0, t.frames[0]).setOrigin(0.5, 0.5).setDepth(t.depth ?? 95e4).setVisible(!1), n = t.shadow ? s.add.image(0, 0, t.shadow).setOrigin(0.5, 0.5).setDepth(t.shadowDepth ?? -999980).setVisible(!1) : null;
8
+ this.birds.push({ img: d, shadow: n, dx: 0, dy: 0, flap: this.random() * 1e3 });
9
+ }
10
+ }
11
+ options;
12
+ birds = [];
13
+ snap;
14
+ random;
15
+ active = 0;
16
+ nextAt = Number.NaN;
17
+ x = 0;
18
+ y = 0;
19
+ vx = 0;
20
+ vy = 0;
21
+ altitude = 60;
22
+ /** Whether a flock is crossing now. */
23
+ get flying() {
24
+ return this.active > 0;
25
+ }
26
+ update(s, t, e, i, d = !0) {
27
+ if (Number.isNaN(this.nextAt)) {
28
+ const [o, h] = this.options.firstMs ?? [3e3, 9e3];
29
+ this.nextAt = s + o + this.random() * (h - o);
30
+ }
31
+ if (!d) {
32
+ this.active && this.land();
33
+ return;
34
+ }
35
+ if (!this.active) {
36
+ s >= this.nextAt && i.night < (this.options.maxNight ?? 0.5) && this.launch(s, e, i.wind);
37
+ return;
38
+ }
39
+ const n = t / 1e3;
40
+ this.x += this.vx * n, this.y += this.vy * n;
41
+ const [c, l] = this.options.frames;
42
+ for (let o = 0; o < this.active; o++) {
43
+ const h = this.birds[o], a = this.snap ? Math.round(this.x + h.dx) : this.x + h.dx, r = this.snap ? Math.round(this.y + h.dy) : this.y + h.dy;
44
+ h.img.setTexture(x(s, h.flap) ? l : c).setFlipX(this.vx < 0), h.img.setPosition(a, r), h.shadow?.setPosition(a + Math.round(this.altitude * 0.25), r + Math.round(this.altitude));
45
+ }
46
+ (this.x < e.x - 120 || this.x > e.right + 120 || this.y < e.y - 120 || this.y > e.bottom + 120) && this.land();
47
+ }
48
+ destroy() {
49
+ for (const s of this.birds)
50
+ s.img.destroy(), s.shadow?.destroy();
51
+ this.birds.length = 0, this.active = 0;
52
+ }
53
+ launch(s, t, e) {
54
+ const i = this.random, [d, n] = this.options.flock;
55
+ this.active = Math.min(this.birds.length, d + Math.floor(i() * (n - d + 1)));
56
+ const c = i() < 0.5 + e * 0.3, l = 34 + i() * 18 + e * 14;
57
+ this.x = c ? t.x - 30 : t.right + 30, this.y = t.y + t.height * (0.1 + i() * 0.7), this.vx = c ? l : -l, this.vy = (i() - 0.5) * l * 0.35, this.altitude = 46 + i() * 40;
58
+ for (let a = 0; a < this.active; a++) {
59
+ const r = this.birds[a], f = m(a, this.vx, i(), i());
60
+ r.dx = f.dx, r.dy = f.dy, r.img.setVisible(!0), r.shadow?.setVisible(!0);
61
+ }
62
+ const [o, h] = this.options.everyS;
63
+ this.nextAt = s + (o + i() * (h - o)) * 1e3;
64
+ }
65
+ land() {
66
+ for (const s of this.birds)
67
+ s.img.setVisible(!1), s.shadow?.setVisible(!1);
68
+ this.active = 0;
69
+ }
70
+ }
71
+ export {
72
+ b as Birds
73
+ };
@@ -0,0 +1,43 @@
1
+ class g {
2
+ constructor(e, o) {
3
+ if (this.options = o, this.snap = o.snap ?? !0, this.random = o.random ?? Math.random, !!o.looks.length)
4
+ for (let s = 0; s < o.count; s++) {
5
+ const h = o.looks[s % o.looks.length], n = e.add.image(0, 0, h[0]).setOrigin(0.5, 1).setDepth(o.depth ?? 9e5).setVisible(!1);
6
+ this.flies.push({ img: n, look: h, homeX: 0, homeY: 0, x: 0, y: 0, tx: 0, ty: 0, retargetAt: 0, seed: this.random() * 1e3, home: !1 });
7
+ }
8
+ }
9
+ options;
10
+ flies = [];
11
+ snap;
12
+ random;
13
+ update(e, o, s, h, n = !0) {
14
+ const m = o / 1e3, i = this.random, a = n && h.night < (this.options.maxNight ?? 0.4);
15
+ for (const t of this.flies) {
16
+ const l = t.homeX < s.x - 40 || t.homeX > s.right + 40 || t.homeY < s.y - 40 || t.homeY > s.bottom + 40;
17
+ if (!a || t.home && l) {
18
+ t.home = !1, t.img.visible && t.img.setVisible(!1);
19
+ continue;
20
+ }
21
+ if (!t.home) {
22
+ if (i() > 0.02 || !this.settle(t, s)) continue;
23
+ t.img.setVisible(!0);
24
+ }
25
+ e >= t.retargetAt && (t.tx = t.homeX + (i() - 0.5) * 34 + h.wind * 6, t.ty = t.homeY - 4 - i() * 14, t.retargetAt = e + 500 + i() * 1400);
26
+ const r = Math.min(1, m * 2.4);
27
+ t.x += (t.tx - t.x) * r, t.y += (t.ty - t.y) * r;
28
+ const f = Math.floor((e + t.seed) / 90) % 3 !== 0, d = Math.sin((e + t.seed) / 160) > 0 ? 1 : 0;
29
+ t.img.setTexture(f ? t.look[0] : t.look[1]), t.img.setPosition(this.snap ? Math.round(t.x) : t.x, (this.snap ? Math.round(t.y) : t.y) - d);
30
+ }
31
+ }
32
+ destroy() {
33
+ for (const e of this.flies) e.img.destroy();
34
+ this.flies.length = 0;
35
+ }
36
+ settle(e, o) {
37
+ const s = this.options.home(o, this.random);
38
+ return s ? (e.homeX = s.x + (s.w ?? 0) / 2, e.homeY = s.y + (s.h ?? 0) / 2, e.x = e.tx = e.homeX + (this.random() - 0.5) * 16, e.y = e.ty = e.homeY - 6 - this.random() * 6, e.home = !0, !0) : !1;
39
+ }
40
+ }
41
+ export {
42
+ g as Butterflies
43
+ };
@@ -0,0 +1,50 @@
1
+ import { puffOffset as p } from "./lifeMotion.js";
2
+ class b {
3
+ constructor(n, t) {
4
+ if (this.options = t, this.snap = t.snap ?? !0, this.random = t.random ?? Math.random, !t.frames.length) return;
5
+ const h = t.puffs ?? 7;
6
+ for (const r of t.mouths) {
7
+ const o = [];
8
+ for (let f = 0; f < h; f++) {
9
+ const m = n.add.image(0, 0, t.frames[0]).setOrigin(0.5, 1).setDepth(t.depth ?? 9e5).setVisible(!1);
10
+ o.push({ img: m, born: -1, seed: this.random() });
11
+ }
12
+ this.chimneys.push({ x: Math.round(r.x), y: Math.round(r.y), puffs: o, next: 0 });
13
+ }
14
+ }
15
+ options;
16
+ chimneys = [];
17
+ snap;
18
+ random;
19
+ update(n, t, h, r = !0) {
20
+ const o = this.options, f = o.puffEveryMs ?? 650, m = o.lifeMs ?? 4600, u = { rise: o.rise ?? 7, drift: o.drift ?? 9 }, a = o.frames;
21
+ for (const e of this.chimneys) {
22
+ if (!(r && e.x > t.x - 40 && e.x < t.right + 40 && e.y > t.y - 20 && e.y < t.bottom + 120)) {
23
+ for (const s of e.puffs)
24
+ s.born >= 0 && s.img.setVisible(!1), s.born = -1;
25
+ continue;
26
+ }
27
+ if (n >= e.next) {
28
+ const s = e.puffs.find((i) => i.born < 0);
29
+ s && (s.born = n, s.seed = this.random(), s.img.setVisible(!0)), e.next = n + f * (0.7 + this.random() * 0.6);
30
+ }
31
+ for (const s of e.puffs) {
32
+ if (s.born < 0) continue;
33
+ const i = (n - s.born) / m;
34
+ if (i >= 1) {
35
+ s.born = -1, s.img.setVisible(!1);
36
+ continue;
37
+ }
38
+ const { dx: c, dy: d } = p((n - s.born) / 1e3, i, s.seed, h.wind, u);
39
+ s.img.setTexture(a[Math.min(a.length - 1, Math.floor(i * a.length))]), s.img.setPosition(this.snap ? Math.round(e.x + c) : e.x + c, this.snap ? Math.round(e.y + d) : e.y + d);
40
+ }
41
+ }
42
+ }
43
+ destroy() {
44
+ for (const n of this.chimneys) for (const t of n.puffs) t.img.destroy();
45
+ this.chimneys.length = 0;
46
+ }
47
+ }
48
+ export {
49
+ b as ChimneySmoke
50
+ };
@@ -0,0 +1,75 @@
1
+ class l {
2
+ constructor(t, e) {
3
+ if (this.options = e, this.kind = e.kind, this.snap = e.snap ?? !0, this.random = e.random ?? Math.random, !!e.looks.length)
4
+ for (let s = 0; s < e.count; s++) {
5
+ const n = e.looks[s % e.looks.length], i = t.add.image(0, 0, n[0]).setOrigin(0, 0).setDepth(e.depth ?? 9e5).setVisible(!1);
6
+ this.motes.push({ img: i, look: n, x: 0, y: 0, vx: 0, vy: 0, ground: 0, landedAt: -1, rising: !1, seed: this.random() * 1e3 });
7
+ }
8
+ }
9
+ options;
10
+ motes = [];
11
+ kind;
12
+ snap;
13
+ random;
14
+ /** `now` and `dt` in ms. */
15
+ update(t, e, s, n, i = !0) {
16
+ const d = e / 1e3;
17
+ for (let o = 0; o < this.motes.length; o++) {
18
+ const r = this.motes[o];
19
+ if (!i) {
20
+ r.img.visible && r.img.setVisible(!1), r.landedAt = -1;
21
+ continue;
22
+ }
23
+ const h = r.x < s.x - 40 || r.x > s.right + 40 || r.y < s.y - 60 || r.y > s.bottom + 30;
24
+ if (r.landedAt < 0 || h) {
25
+ if (this.random() > 0.08 || !this.spawn(r, s, n.wind, r.landedAt < 0 && this.random() < 0.5)) {
26
+ r.img.visible && r.img.setVisible(!1), r.landedAt = -1;
27
+ continue;
28
+ }
29
+ r.img.setVisible(!0);
30
+ }
31
+ this.step(r, t, d), r.img.setPosition(this.snap ? Math.round(r.x) : r.x, this.snap ? Math.round(r.y) : r.y);
32
+ }
33
+ }
34
+ destroy() {
35
+ for (const t of this.motes) t.img.destroy();
36
+ this.motes.length = 0;
37
+ }
38
+ /** `anywhere`: a first fill lands bodies all over the view, not only at its edge, so a scene opens already alive. */
39
+ spawn(t, e, s, n) {
40
+ const i = this.random;
41
+ t.landedAt = 0, t.rising = !1;
42
+ const d = this.options.from?.(e, i) ?? null;
43
+ return d ? this.spawnFrom(t, d, s) : this.options.sourceOnly ? !1 : (t.x = e.x - 20 + i() * (e.width + 30), this.kind === "ember" ? (t.y = n ? e.y + i() * e.height : e.bottom + 2, t.vx = s * 8 * i(), t.vy = -10 - i() * 12, t.ground = e.y + i() * e.height * 0.6) : this.kind === "mote" ? (t.y = e.y + i() * e.height, t.vx = (i() - 0.5) * 4, t.vy = (i() - 0.5) * 3, t.ground = 0) : (t.y = n ? e.y + i() * e.height : e.y - 6 - i() * 20, t.vx = 4 + s * 16 * (0.5 + i()), t.vy = 6 + i() * 8, t.ground = e.bottom + 10), !0);
44
+ }
45
+ spawnFrom(t, e, s) {
46
+ const n = this.random;
47
+ return t.x = e.x + n() * (e.w ?? 0), t.y = e.y + n() * (e.h ?? 0), this.kind === "ember" || this.kind === "ash" ? (t.rising = !0, t.vx = 2 + s * 10 * n(), this.kind === "ember" ? (t.vy = -10 - n() * 12, t.ground = t.y - 16 - n() * 30) : (t.vy = -3 - n() * 5, t.ground = t.y - 30 - n() * 40), !0) : (t.vx = 2 + s * 14 * (0.5 + n()), t.vy = 9 + n() * 7, t.ground = e.y + (e.h ?? 0) + 10 + n() * 22, !0);
48
+ }
49
+ step(t, e, s) {
50
+ const n = this.kind, i = t.look;
51
+ if (n === "leaf") {
52
+ if (t.landedAt > 0) {
53
+ e - t.landedAt > 1600 && (t.landedAt = -1);
54
+ return;
55
+ }
56
+ t.x += (t.vx + Math.sin(e / 260 + t.seed) * 10) * s, t.y += t.vy * s, t.img.setTexture(i[Math.floor(e / 140 + t.seed) % i.length]), t.y >= t.ground && (t.y = t.ground, t.landedAt = e, t.img.setTexture(i[0]));
57
+ return;
58
+ }
59
+ if (n === "ember") {
60
+ t.x += (t.vx + Math.sin(e / 300 + t.seed) * 4) * s, t.y += t.vy * s;
61
+ const o = t.y - t.ground, r = o < 0 ? 2 : o < 20 ? 1 : 0;
62
+ t.img.setTexture(i[Math.min(i.length - 1, r)]), o < -12 && (t.landedAt = -1);
63
+ return;
64
+ }
65
+ if (t.rising) {
66
+ t.x += (t.vx + Math.sin(e / 500 + t.seed) * 3) * s, t.y += t.vy * s, t.y < t.ground && (t.landedAt = -1);
67
+ return;
68
+ }
69
+ const d = n === "mote" ? 2 : 7;
70
+ t.x += (t.vx + Math.sin(e / 700 + t.seed) * d) * s, t.y += (t.vy + Math.cos(e / 900 + t.seed) * (n === "mote" ? 2 : 1)) * s, n !== "mote" && t.y > t.ground && (t.landedAt = -1), n === "mote" && this.random() < s / 9 && (t.landedAt = -1);
71
+ }
72
+ }
73
+ export {
74
+ l as Drift
75
+ };
@@ -0,0 +1,52 @@
1
+ import { Sprite as y, Container as p } from "pixi.js";
2
+ import { firefliesOut as x, fireflyOffset as g, fireflyGlow as b } from "./lifeMotion.js";
3
+ class Y {
4
+ constructor(s, e) {
5
+ this.stage = s, this.options = e, this.dim = s.textures.get(e.frames[0]), this.lit = s.textures.get(e.frames[1]), this.onScreen = (e.layer ?? "screen") === "screen", this.snap = e.snap ?? !0, this.random = e.random ?? Math.random, this.onScreen ? (s.screen.addChild(this.layer), s.cameras.main.follow(this.layer)) : (this.layer.zIndex = e.depth ?? 9e5, s.world.addChild(this.layer)), this.layer.visible = !1;
6
+ for (let i = 0; i < e.count; i++) {
7
+ const r = new y(this.dim);
8
+ r.anchor.set(0.5), r.visible = !1, this.layer.addChild(r), this.flies.push({ sprite: r, homeX: 0, homeY: 0, seed: this.random() * 1e4, home: !1 });
9
+ }
10
+ }
11
+ stage;
12
+ options;
13
+ layer = new p();
14
+ flies = [];
15
+ dim;
16
+ lit;
17
+ onScreen;
18
+ snap;
19
+ random;
20
+ update(s, e, i, r = !0) {
21
+ if (!this.flies.length) return;
22
+ const n = !r || i.night < 0.5;
23
+ if (this.layer.visible = !n, n) {
24
+ for (const h of this.flies) h.home = !1;
25
+ return;
26
+ }
27
+ const m = x(this.flies.length, i.night);
28
+ for (let h = 0; h < this.flies.length; h++) {
29
+ const t = this.flies[h], d = t.homeX < e.x - 30 || t.homeX > e.right + 30 || t.homeY < e.y - 30 || t.homeY > e.bottom + 30;
30
+ if (h >= m || t.home && d) {
31
+ t.home = !1, t.sprite.visible = !1;
32
+ continue;
33
+ }
34
+ if (!t.home && (this.random() > 0.05 || !this.settle(t, e))) continue;
35
+ const l = (s + t.seed) / 1e3, o = b(l);
36
+ if (t.sprite.visible = o > 0, !o) continue;
37
+ t.sprite.texture = o === 2 ? this.lit : this.dim;
38
+ const { dx: c, dy: u } = g(l), a = t.homeX + c, f = t.homeY + u;
39
+ t.sprite.position.set(this.snap ? Math.round(a) : a, this.snap ? Math.round(f) : f);
40
+ }
41
+ }
42
+ destroy() {
43
+ this.onScreen && this.stage.cameras.main.unfollow(this.layer), this.layer.destroy({ children: !0 }), this.flies.length = 0;
44
+ }
45
+ settle(s, e) {
46
+ const i = this.options.home(e, this.random);
47
+ return i ? (s.homeX = i.x + (i.w ?? 0) / 2 + (this.random() - 0.5) * 24, s.homeY = i.y + (i.h ?? 0) / 2 - 4 - this.random() * 16, s.home = !0, !0) : !1;
48
+ }
49
+ }
50
+ export {
51
+ Y as Fireflies
52
+ };
@@ -0,0 +1,49 @@
1
+ function i(t, n, r = 0) {
2
+ return t.x + (t.w ?? 0) >= n.x - r && t.x <= n.right + r && t.y + (t.h ?? 0) >= n.y - r && t.y <= n.bottom + r;
3
+ }
4
+ function e(t, n, r, f = 8) {
5
+ if (!t.length) return null;
6
+ for (let o = 0; o < f; o++) {
7
+ const u = t[Math.floor(r() * t.length)];
8
+ if (i(u, n)) return u;
9
+ }
10
+ return null;
11
+ }
12
+ function c(t, n = 8) {
13
+ return (r, f) => e(t, r, f, n);
14
+ }
15
+ function l(t, n, r = 110) {
16
+ const f = Math.floor((t + n) / r) % 8;
17
+ return f < 5 ? f % 2 : 0;
18
+ }
19
+ function h(t, n, r, f) {
20
+ const o = Math.ceil(t / 2), u = t % 2 ? 1 : -1;
21
+ return { dx: -Math.sign(n) * o * (6 + r * 3), dy: u * o * (4 + f * 2) };
22
+ }
23
+ function s(t) {
24
+ const n = (t * 0.45 % 1 + 1) % 1;
25
+ return n < 0.18 ? 2 : n < 0.26 || n > 0.94 ? 1 : 0;
26
+ }
27
+ function M(t) {
28
+ return { dx: Math.sin(t * 0.7) * 9 + Math.sin(t * 1.9) * 3, dy: Math.cos(t * 0.5) * 5 };
29
+ }
30
+ function a(t, n) {
31
+ return n < 0.5 ? 0 : Math.round(t * Math.min(1, (n - 0.5) / 0.35));
32
+ }
33
+ function d(t, n, r, f, o) {
34
+ return {
35
+ dx: (r - 0.5) * 2 + o.drift * (0.25 + f) * t * n * 2 + Math.sin(t * 1.3 + r * 6) * 1.2,
36
+ dy: -o.rise * t * (1 - n * 0.25)
37
+ };
38
+ }
39
+ export {
40
+ l as birdFrame,
41
+ i as boxInView,
42
+ a as firefliesOut,
43
+ s as fireflyGlow,
44
+ M as fireflyOffset,
45
+ h as flockSlot,
46
+ e as pickInView,
47
+ d as puffOffset,
48
+ c as sourceOf
49
+ };
@@ -1,35 +1,44 @@
1
- import { sound as u } from "../audio/SoundEngine.js";
2
- import { parseTiled as f } from "../tilemap/tiled.js";
3
- import { collectAtlasPages as l, duplicateFrames as w, parseAtlas as p } from "./textureAtlas.js";
4
- function c(r, t) {
1
+ import { sound as f } from "../audio/SoundEngine.js";
2
+ import { ldtkExternalLevels as w, parseLdtk as m } from "../tilemap/ldtkParse.js";
3
+ import { parseTiled as p } from "../tilemap/tiled.js";
4
+ import { collectAtlasPages as g, duplicateFrames as x, parseAtlas as v } from "./textureAtlas.js";
5
+ function l(r) {
6
+ return r instanceof Error ? r.message : String(r);
7
+ }
8
+ function h(r, t) {
5
9
  if (/^[a-z][a-z0-9+.-]*:/i.test(r) || r.startsWith("/")) return r;
6
- const a = (t.slice(0, t.lastIndexOf("/") + 1) + r).split("/"), s = [];
7
- for (const i of a)
8
- i === ".." && s.length && s[s.length - 1] !== ".." && s[s.length - 1] !== "" ? s.pop() : i !== "." && s.push(i);
9
- return s.join("/");
10
+ const s = (t.slice(0, t.lastIndexOf("/") + 1) + r).split("/"), a = [];
11
+ for (const o of s)
12
+ o === ".." && a.length && a[a.length - 1] !== ".." && a[a.length - 1] !== "" ? a.pop() : o !== "." && a.push(o);
13
+ return a.join("/");
14
+ }
15
+ function A(r, t, e) {
16
+ const s = r;
17
+ return [...s.levels ?? [], ...(s.worlds ?? []).flatMap((o) => o.levels ?? [])].some((o) => o.externalRelPath === t && o.identifier !== void 0 && e.has(o.identifier));
10
18
  }
11
- async function m(r) {
19
+ async function $(r) {
12
20
  const t = await createImageBitmap(r), e = document.createElement("canvas");
13
21
  e.width = t.width, e.height = t.height;
14
- const a = e.getContext("2d");
15
- if (!a) throw new Error("AssetLoader: no 2D context (out of canvas memory?)");
16
- return a.drawImage(t, 0, 0), t.close(), e;
22
+ const s = e.getContext("2d");
23
+ if (!s) throw new Error("AssetLoader: no 2D context (out of canvas memory?)");
24
+ return s.drawImage(t, 0, 0), t.close(), e;
17
25
  }
18
- async function g(r, t, e) {
26
+ async function b(r, t, e) {
19
27
  if (typeof FontFace > "u" || typeof document > "u" || !document.fonts)
20
28
  throw new Error(`AssetLoader: this browser cannot load the font "${r}" (no FontFace)`);
21
- const a = new FontFace(r, t, e);
22
- await a.load(), document.fonts.add(a);
29
+ const s = new FontFace(r, t, e);
30
+ await s.load(), document.fonts.add(s);
23
31
  }
24
- class $ {
32
+ class B {
25
33
  constructor(t, e = {}) {
26
- this.textures = t, this.options = e, this.fetcher = e.fetch ?? ((a) => fetch(a)), this.toCanvas = e.toCanvas ?? m;
34
+ this.textures = t, this.options = e, this.fetcher = e.fetch ?? ((s) => fetch(s)), this.toCanvas = e.toCanvas ?? $;
27
35
  }
28
36
  textures;
29
37
  options;
30
38
  queue = [];
31
39
  data = /* @__PURE__ */ new Map();
32
40
  maps = /* @__PURE__ */ new Map();
41
+ ldtks = /* @__PURE__ */ new Map();
33
42
  atlases = /* @__PURE__ */ new Map();
34
43
  /** Decoded audio by key; a key with bytes only waits for a context (`decodeAudio`). */
35
44
  audioBuffers = /* @__PURE__ */ new Map();
@@ -41,13 +50,13 @@ class $ {
41
50
  done = 0;
42
51
  image(t, e) {
43
52
  return this.add(t, async () => {
44
- this.textures.addCanvas(t, await this.toCanvas(await this.blob(e)));
53
+ this.textures.addCanvas(t, await this.canvas(e));
45
54
  });
46
55
  }
47
56
  /** An image cut into equal frames named 0, 1, 2…, left to right, then row by row. */
48
- spritesheet(t, e, a) {
57
+ spritesheet(t, e, s) {
49
58
  return this.add(t, async () => {
50
- this.textures.addSpriteSheet(t, await this.toCanvas(await this.blob(e)), a);
59
+ this.textures.addSpriteSheet(t, await this.canvas(e), s);
51
60
  });
52
61
  }
53
62
  json(t, e) {
@@ -61,14 +70,33 @@ class $ {
61
70
  });
62
71
  }
63
72
  /** A Tiled JSON map, then every tileset image it names (resolved beside the map file). */
64
- tilemap(t, e, a = {}) {
73
+ tilemap(t, e, s = {}) {
65
74
  return this.add(t, async () => {
66
- const s = f(await (await this.request(e)).json());
67
- this.maps.set(t, s);
68
- const i = a.textureKey ?? ((n) => n.name);
69
- for (const n of s.tilesets) this.image(i(n), c(n.image, e));
75
+ const a = p(await (await this.request(e)).json());
76
+ this.maps.set(t, a);
77
+ const o = s.textureKey ?? ((i) => i.name);
78
+ for (const i of a.tilesets) this.image(o(i), h(i.image, e));
70
79
  });
71
80
  }
81
+ /**
82
+ * An LDtk project: the `.ldtk` file, the `.ldtkl` file of each level it saves apart (resolved beside the project),
83
+ * then every tileset image (resolved beside the project, as LDtk writes `relPath`). Counts as one asset, plus one
84
+ * per tileset image. Read it back with `ldtkProject(key)`; each level's `map` goes to `TilemapView` as it is.
85
+ */
86
+ ldtk(t, e, s = {}) {
87
+ return this.add(t, async () => {
88
+ const a = await (await this.request(e)).json(), o = s.levels ? new Set(s.levels) : null, i = w(a).filter((d) => !o || A(a, d, o)), c = await Promise.all(i.map(async (d) => [d, await (await this.request(h(d, e))).json()])), n = m(a, { levels: Object.fromEntries(c) });
89
+ this.ldtks.set(t, n);
90
+ const u = s.textureKey ?? ((d) => d.name);
91
+ for (const d of n.tilesets) this.image(u(d), h(d.image, e));
92
+ });
93
+ }
94
+ /** A loaded LDtk project. */
95
+ ldtkProject(t) {
96
+ const e = this.ldtks.get(t);
97
+ if (!e) throw new Error(`AssetLoader: no LDtk project loaded as "${t}"`);
98
+ return e;
99
+ }
72
100
  /**
73
101
  * A TexturePacker (or Pixi) JSON atlas, hash or array format: its page image, and for a multipack atlas every page
74
102
  * named in `meta.related_multi_packs` (each resolved beside the file naming it). The first page is the texture
@@ -77,27 +105,32 @@ class $ {
77
105
  */
78
106
  atlas(t, e) {
79
107
  return this.add(t, async () => {
80
- const a = this.textures.addAtlas?.bind(this.textures);
81
- if (!a) throw new Error(`AssetLoader: the texture sink cannot take atlases (no addAtlas) for "${t}"`);
82
- const s = await l(
108
+ const s = this.textures.addAtlas?.bind(this.textures);
109
+ if (!s) throw new Error(`AssetLoader: the texture sink cannot take atlases (no addAtlas) for "${t}"`);
110
+ const a = await g(
83
111
  e,
84
- async (o) => p(await (await this.request(o)).json(), o),
85
- c
86
- ), i = await Promise.all(s.map((o) => this.blob(c(o.page.image, o.url)).then((h) => this.toCanvas(h)))), n = w(s.map((o) => o.page));
87
- n.length && console.warn(`[assets] atlas "${t}" names ${n.length} frame(s) on more than one page: ${n.slice(0, 5).join(", ")}`), a(t, s.map((o, h) => ({ canvas: i[h], frames: o.page.frames })));
88
- const d = {};
89
- for (const o of s) Object.assign(d, o.page.animations);
90
- this.atlases.set(t, { frames: [...new Set(s.flatMap((o) => o.page.frames.map((h) => h.name)))], animations: d, pages: s.length });
112
+ async (n) => v(await (await this.request(n)).json(), n),
113
+ h
114
+ ), o = await Promise.all(a.map((n) => this.canvas(h(n.page.image, n.url)))), i = x(a.map((n) => n.page));
115
+ i.length && console.warn(`[assets] atlas "${t}" names ${i.length} frame(s) on more than one page: ${i.slice(0, 5).join(", ")}`), s(t, a.map((n, u) => ({ canvas: o[u], frames: n.page.frames })));
116
+ const c = {};
117
+ for (const n of a) Object.assign(c, n.page.animations);
118
+ this.atlases.set(t, { frames: [...new Set(a.flatMap((n) => n.page.frames.map((u) => u.name)))], animations: c, pages: a.length });
91
119
  });
92
120
  }
93
121
  /**
94
122
  * A web font (woff2, woff, ttf) under `family`, added to `document.fonts` once loaded so canvas text and the DOM can
95
123
  * use it at once — load fonts before the first `Text` is drawn, or it measures with the fallback.
96
124
  */
97
- font(t, e, a) {
98
- const s = this.options.addFont ?? g;
125
+ font(t, e, s) {
126
+ const a = this.options.addFont ?? b;
99
127
  return this.add(t, async () => {
100
- await s(t, await this.bytes(e), a);
128
+ const o = await this.bytes(e);
129
+ try {
130
+ await a(t, o, s);
131
+ } catch (i) {
132
+ throw new Error(`AssetLoader: could not load font "${t}" from ${this.full(e)}: ${l(i)}`);
133
+ }
101
134
  });
102
135
  }
103
136
  /**
@@ -107,10 +140,10 @@ class $ {
107
140
  */
108
141
  audio(t, e) {
109
142
  return this.add(t, async () => {
110
- const a = await this.bytes(e);
143
+ const s = await this.bytes(e);
111
144
  this.audioBuffers.delete(t), this.decoding.delete(t);
112
- const s = (this.options.audioContext ?? (() => u.audioContext))();
113
- s ? this.audioBuffers.set(t, await this.decode(s, a, e)) : this.audioBytes.set(t, a);
145
+ const a = (this.options.audioContext ?? (() => f.audioContext))();
146
+ a ? this.audioBuffers.set(t, await this.decode(a, s, e)) : this.audioBytes.set(t, s);
114
147
  });
115
148
  }
116
149
  /** A loaded sound, decoded; null while it waits for an audio context (`decodeAudio`). */
@@ -122,21 +155,21 @@ class $ {
122
155
  }
123
156
  /** A loaded sound, decoding its kept bytes through `ctx` (default: the loader's context) the first time. */
124
157
  decodeAudio(t, e) {
125
- const a = this.audioBuffers.get(t);
126
- if (a) return Promise.resolve(a);
127
- const s = this.decoding.get(t);
128
- if (s) return s;
129
- const i = this.audioBytes.get(t);
130
- if (!i) return Promise.reject(new Error(`AssetLoader: no audio loaded as "${t}"`));
131
- const n = e ?? (this.options.audioContext ?? (() => u.audioContext))();
132
- if (!n) return Promise.reject(new Error(`AssetLoader: no audio context to decode "${t}" yet`));
133
- const d = this.decode(n, i, t).then(
134
- (o) => (this.audioBuffers.set(t, o), this.audioBytes.delete(t), this.decoding.delete(t), o),
135
- (o) => {
136
- throw this.decoding.delete(t), o;
158
+ const s = this.audioBuffers.get(t);
159
+ if (s) return Promise.resolve(s);
160
+ const a = this.decoding.get(t);
161
+ if (a) return a;
162
+ const o = this.audioBytes.get(t);
163
+ if (!o) return Promise.reject(new Error(`AssetLoader: no audio loaded as "${t}"`));
164
+ const i = e ?? (this.options.audioContext ?? (() => f.audioContext))();
165
+ if (!i) return Promise.reject(new Error(`AssetLoader: no audio context to decode "${t}" yet`));
166
+ const c = this.decode(i, o, t).then(
167
+ (n) => (this.audioBuffers.set(t, n), this.audioBytes.delete(t), this.decoding.delete(t), n),
168
+ (n) => {
169
+ throw this.decoding.delete(t), n;
137
170
  }
138
171
  );
139
- return this.decoding.set(t, d), d;
172
+ return this.decoding.set(t, c), c;
140
173
  }
141
174
  /** What a loaded atlas holds: its frame names and animations. */
142
175
  getAtlas(t) {
@@ -146,11 +179,11 @@ class $ {
146
179
  }
147
180
  /** Runs everything queued; `onProgress` after each asset. Safe to call again after queueing more. */
148
181
  async load(t) {
149
- const e = Math.max(1, this.options.concurrency ?? 6), a = async () => {
150
- for (let s = this.queue.shift(); s; s = this.queue.shift())
151
- await s.run(), this.done++, t?.({ done: this.done, total: this.total, key: s.key });
182
+ const e = Math.max(1, this.options.concurrency ?? 6), s = async () => {
183
+ for (let a = this.queue.shift(); a; a = this.queue.shift())
184
+ await a.run(), this.done++, t?.({ done: this.done, total: this.total, key: a.key });
152
185
  };
153
- for (; this.queue.length; ) await Promise.all(Array.from({ length: e }, a));
186
+ for (; this.queue.length; ) await Promise.all(Array.from({ length: e }, s));
154
187
  }
155
188
  /** A loaded JSON value. */
156
189
  getJson(t) {
@@ -170,33 +203,45 @@ class $ {
170
203
  add(t, e) {
171
204
  return this.queue.push({ key: t, run: e }), this.total++, this;
172
205
  }
206
+ full(t) {
207
+ return h(t, this.options.baseUrl ?? "");
208
+ }
173
209
  async request(t) {
174
- const e = c(t, this.options.baseUrl ?? "");
175
- let a;
210
+ const e = this.full(t);
211
+ let s;
176
212
  try {
177
- a = await this.fetcher(e);
178
- } catch (s) {
179
- throw new Error(`AssetLoader: could not fetch ${e}: ${s instanceof Error ? s.message : String(s)}`);
213
+ s = await this.fetcher(e);
214
+ } catch (a) {
215
+ throw new Error(`AssetLoader: could not fetch ${e}: ${l(a)}`);
180
216
  }
181
- if (!a.ok) throw new Error(`AssetLoader: ${e} answered ${a.status}`);
182
- return a;
217
+ if (!s.ok) throw new Error(`AssetLoader: ${e} answered ${s.status}`);
218
+ return s;
183
219
  }
184
220
  async blob(t) {
185
221
  return (await this.request(t)).blob();
186
222
  }
223
+ /** An image file decoded into a canvas; a file that is not an image fails naming its URL. */
224
+ async canvas(t) {
225
+ const e = await this.blob(t);
226
+ try {
227
+ return await this.toCanvas(e);
228
+ } catch (s) {
229
+ throw new Error(`AssetLoader: could not decode image ${this.full(t)}: ${l(s)}`);
230
+ }
231
+ }
187
232
  async bytes(t) {
188
233
  const e = await this.request(t);
189
234
  return typeof e.arrayBuffer == "function" ? e.arrayBuffer() : (await e.blob()).arrayBuffer();
190
235
  }
191
- async decode(t, e, a) {
236
+ async decode(t, e, s) {
192
237
  try {
193
238
  return await t.decodeAudioData(e.slice(0));
194
- } catch (s) {
195
- throw new Error(`AssetLoader: could not decode audio ${a}: ${s instanceof Error ? s.message : String(s)}`);
239
+ } catch (a) {
240
+ throw new Error(`AssetLoader: could not decode audio ${s}: ${l(a)}`);
196
241
  }
197
242
  }
198
243
  }
199
244
  export {
200
- $ as AssetLoader,
201
- c as resolveUrl
245
+ B as AssetLoader,
246
+ h as resolveUrl
202
247
  };