@litecanvas/utils 0.3.2 → 0.5.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
@@ -6,6 +6,8 @@ Small collection of tools for developing games with [Litecanvas](https://github.
6
6
 
7
7
  - **Camera**: Move-, zoom- and rotatable camera with shake. [Usage & Docs](https://github.com/litecanvas/utils/tree/main/src/camera)
8
8
  - **Vector**: Modular 2D vector. [Usage & Docs](https://github.com/litecanvas/utils/tree/main/src/vector)
9
+ - **Actor**: class to represent game entities. [Usage & Docs](https://github.com/litecanvas/utils/tree/main/src/actor)
10
+ - **Grid**: class to handle retangular grid areas. [Usage & Docs](https://github.com/litecanvas/utils/tree/main/src/grid)
9
11
  - **Collision** utilities. [Usage & Docs](https://github.com/litecanvas/utils/tree/main/src/collision)
10
12
  - And [some math utilities](https://github.com/litecanvas/utils/tree/main/src/math)
11
13
 
package/dist/actor.js ADDED
@@ -0,0 +1,156 @@
1
+ (() => {
2
+ var __defProp = Object.defineProperty;
3
+ var __export = (target, all) => {
4
+ for (var name in all)
5
+ __defProp(target, name, { get: all[name], enumerable: true });
6
+ };
7
+
8
+ // src/actor/index.js
9
+ var actor_exports = {};
10
+ __export(actor_exports, {
11
+ ANCHOR_BOT_LEFT: () => ANCHOR_BOT_LEFT,
12
+ ANCHOR_BOT_RIGHT: () => ANCHOR_BOT_RIGHT,
13
+ ANCHOR_CENTER: () => ANCHOR_CENTER,
14
+ ANCHOR_TOP_LEFT: () => ANCHOR_TOP_LEFT,
15
+ ANCHOR_TOP_RIGHT: () => ANCHOR_TOP_RIGHT,
16
+ Actor: () => Actor
17
+ });
18
+
19
+ // src/vector/index.js
20
+ var Vector = class {
21
+ /** @type {number} */
22
+ x;
23
+ /** @type {number} */
24
+ y;
25
+ /**
26
+ * @param {number} x
27
+ * @param {number} y
28
+ */
29
+ constructor(x = 0, y = x) {
30
+ this.x = x;
31
+ this.y = y;
32
+ }
33
+ /**
34
+ * @returns {string}
35
+ */
36
+ toString() {
37
+ return `Vector (${this.x}, ${this.y})`;
38
+ }
39
+ };
40
+ var vec = (x = 0, y = x) => new Vector(x, y);
41
+ var veccopy = (v) => vec(v.x, v.y);
42
+
43
+ // src/actor/index.js
44
+ var ANCHOR_CENTER = vec(0.5, 0.5);
45
+ var ANCHOR_TOP_LEFT = vec(0, 0);
46
+ var ANCHOR_TOP_RIGHT = vec(1, 0);
47
+ var ANCHOR_BOT_LEFT = vec(0, 1);
48
+ var ANCHOR_BOT_RIGHT = vec(1, 1);
49
+ var Actor = class {
50
+ /** @type {Image|HTMLCanvasElement|OffscreenCanvas} */
51
+ sprite;
52
+ /** @type {Vector} The actor position */
53
+ _p;
54
+ /** @type {Vector} The actor anchor (origin) */
55
+ _o;
56
+ /** @type {Vector} The actor scale */
57
+ _s;
58
+ /** @type {number} The actor angle (in radians) */
59
+ angle = 0;
60
+ /** @type {number} The actor opacity */
61
+ opacity = 1;
62
+ /** @type {boolean} If `true` the actor will not be drawn. */
63
+ hidden = false;
64
+ /**
65
+ * @param {Image|HTMLCanvasElement|OffscreenCanvas} sprite
66
+ * @param {Vector} position
67
+ */
68
+ constructor(sprite, position) {
69
+ this.sprite = sprite;
70
+ this._p = position || vec(0);
71
+ this._o = veccopy(ANCHOR_TOP_LEFT);
72
+ this._s = vec(1, 1);
73
+ }
74
+ /**
75
+ * @param {number}
76
+ */
77
+ set x(value) {
78
+ this._p.x = value;
79
+ }
80
+ /**
81
+ * @returns {number}
82
+ */
83
+ get x() {
84
+ return this._p.x;
85
+ }
86
+ /**
87
+ * @param {number}
88
+ */
89
+ set y(value) {
90
+ this._p.y = value;
91
+ }
92
+ /**
93
+ * @returns {number}
94
+ */
95
+ get y() {
96
+ return this._p.y;
97
+ }
98
+ /**
99
+ * @param {Vector}
100
+ */
101
+ set anchor(vec2) {
102
+ this._o.x = vec2.x;
103
+ this._o.y = vec2.y;
104
+ }
105
+ /**
106
+ * @returns {Vector}
107
+ */
108
+ get anchor() {
109
+ return this._o;
110
+ }
111
+ /**
112
+ * @returns {number}
113
+ */
114
+ get width() {
115
+ return this.sprite.width * this._s.y;
116
+ }
117
+ /**
118
+ * @returns {number}
119
+ */
120
+ get height() {
121
+ return this.sprite.height * this._s.y;
122
+ }
123
+ /**
124
+ * @retuns {Vector}
125
+ */
126
+ get scale() {
127
+ return this._s;
128
+ }
129
+ /**
130
+ * Update the transformation matrix, sets the opacity and draw the actor sprite image.
131
+ *
132
+ * @param {LitecanvasInstance} [litecanvas]
133
+ */
134
+ draw(litecanvas = globalThis) {
135
+ if (this.hidden || this.opacity <= 0) return;
136
+ litecanvas.push();
137
+ this.transform(litecanvas);
138
+ const anchorX = this.sprite.width * this.anchor.x;
139
+ const anchorY = this.sprite.height * this.anchor.y;
140
+ litecanvas.image(-anchorX, -anchorY, this.sprite);
141
+ litecanvas.pop();
142
+ }
143
+ /**
144
+ * @param {LitecanvasInstance} litecanvas
145
+ */
146
+ transform(litecanvas) {
147
+ litecanvas.translate(this._p.x, this._p.y);
148
+ litecanvas.rotate(this.angle);
149
+ litecanvas.scale(this._s.x, this._s.y);
150
+ litecanvas.alpha(this.opacity);
151
+ }
152
+ };
153
+
154
+ // src/actor/_web.js
155
+ globalThis.utils = Object.assign(globalThis.utils || {}, { actorUtils: actor_exports });
156
+ })();
@@ -0,0 +1 @@
1
+ (()=>{var f=Object.defineProperty;var p=(e,t)=>{for(var r in t)f(e,r,{get:t[r],enumerable:!0})};var a={};p(a,{ANCHOR_BOT_LEFT:()=>d,ANCHOR_BOT_RIGHT:()=>x,ANCHOR_CENTER:()=>u,ANCHOR_TOP_LEFT:()=>c,ANCHOR_TOP_RIGHT:()=>h,Actor:()=>n});var s=class{x;y;constructor(t=0,r=t){this.x=t,this.y=r}toString(){return`Vector (${this.x}, ${this.y})`}},o=(e=0,t=e)=>new s(e,t);var i=e=>o(e.x,e.y);var u=o(.5,.5),c=o(0,0),h=o(1,0),d=o(0,1),x=o(1,1),n=class{sprite;_p;_o;_s;angle=0;opacity=1;hidden=!1;constructor(t,r){this.sprite=t,this._p=r||o(0),this._o=i(c),this._s=o(1,1)}set x(t){this._p.x=t}get x(){return this._p.x}set y(t){this._p.y=t}get y(){return this._p.y}set anchor(t){this._o.x=t.x,this._o.y=t.y}get anchor(){return this._o}get width(){return this.sprite.width*this._s.y}get height(){return this.sprite.height*this._s.y}get scale(){return this._s}draw(t=globalThis){if(this.hidden||this.opacity<=0)return;t.push(),this.transform(t);let r=this.sprite.width*this.anchor.x,l=this.sprite.height*this.anchor.y;t.image(-r,-l,this.sprite),t.pop()}transform(t){t.translate(this._p.x,this._p.y),t.rotate(this.angle),t.scale(this._s.x,this._s.y),t.alpha(this.opacity)}};globalThis.utils=Object.assign(globalThis.utils||{},{actorUtils:a});})();
package/dist/all.js CHANGED
@@ -8,8 +8,15 @@
8
8
  // src/index.js
9
9
  var src_exports = {};
10
10
  __export(src_exports, {
11
+ ANCHOR_BOT_LEFT: () => ANCHOR_BOT_LEFT,
12
+ ANCHOR_BOT_RIGHT: () => ANCHOR_BOT_RIGHT,
13
+ ANCHOR_CENTER: () => ANCHOR_CENTER,
14
+ ANCHOR_TOP_LEFT: () => ANCHOR_TOP_LEFT,
15
+ ANCHOR_TOP_RIGHT: () => ANCHOR_TOP_RIGHT,
16
+ Actor: () => Actor,
11
17
  Camera: () => Camera,
12
18
  DOWN: () => DOWN,
19
+ Grid: () => Grid,
13
20
  LEFT: () => LEFT,
14
21
  ONE: () => ONE,
15
22
  RIGHT: () => RIGHT,
@@ -198,6 +205,204 @@
198
205
  }
199
206
  };
200
207
 
208
+ // src/grid/index.js
209
+ var Grid = class _Grid {
210
+ /** @type {number} The grid width */
211
+ _w;
212
+ /** @type {number} The grid height */
213
+ _h;
214
+ /** @type {any[]} The grid cells */
215
+ _c;
216
+ /**
217
+ * @static
218
+ * @param {number} width
219
+ * @param {number} height
220
+ * @param {any[]} values
221
+ */
222
+ static fromArray(width, height, values) {
223
+ const grid = new _Grid(width, height);
224
+ for (let i = 0; i < values.length; i++) {
225
+ grid._c[i] = values[i];
226
+ }
227
+ return grid;
228
+ }
229
+ /**
230
+ * @param {number} width The grid width
231
+ * @param {number} height The grid height
232
+ */
233
+ constructor(width, height) {
234
+ this.width = width;
235
+ this.height = height;
236
+ this.clear();
237
+ }
238
+ /**
239
+ * Delete all cell values.
240
+ */
241
+ clear() {
242
+ this._c = Array(this._w * this._h);
243
+ }
244
+ /**
245
+ * @param {number} value
246
+ */
247
+ set width(value) {
248
+ this._w = Math.max(1, ~~value);
249
+ }
250
+ get width() {
251
+ return this._w;
252
+ }
253
+ /**
254
+ * @param {number} value
255
+ */
256
+ set height(value) {
257
+ this._h = Math.max(1, ~~value);
258
+ }
259
+ get height() {
260
+ return this._h;
261
+ }
262
+ /**
263
+ * The the value of a grid's cell.
264
+ *
265
+ * @param {number} x
266
+ * @param {number} y
267
+ * @param {any} value
268
+ */
269
+ set(x, y, value) {
270
+ this._c[this.pointToIndex(x, y)] = value;
271
+ }
272
+ /**
273
+ * Returns the value of a grid's cell.
274
+ *
275
+ * @param {number} x
276
+ * @param {number} y
277
+ * @returns {any}
278
+ */
279
+ get(x, y) {
280
+ return this._c[this.pointToIndex(x, y)];
281
+ }
282
+ /**
283
+ * Returns true if the which cell has any value not equal to `null` or `undefined`.
284
+ *
285
+ * @param {number} x
286
+ * @param {number} y
287
+ * @returns {boolean}
288
+ */
289
+ has(x, y) {
290
+ return this.get(x, y) != null;
291
+ }
292
+ /**
293
+ * Returns the total of cells.
294
+ *
295
+ * @returns {number}
296
+ */
297
+ get length() {
298
+ return this._w * this._h;
299
+ }
300
+ /**
301
+ * Convert a grid point (X, Y) to a index.
302
+ *
303
+ * @param {number} x
304
+ * @param {number} y
305
+ * @returns {number} The index
306
+ */
307
+ pointToIndex(x, y) {
308
+ return this.clampX(~~x) + this.clampY(~~y) * this._w;
309
+ }
310
+ /**
311
+ * Convert index to a grid point X.
312
+ *
313
+ * @param {number} index
314
+ * @returns {number}
315
+ */
316
+ indexToPointX(index) {
317
+ return index % this._w;
318
+ }
319
+ /**
320
+ * Convert index to a grid point Y.
321
+ *
322
+ * @param {number} index
323
+ * @returns {number}
324
+ */
325
+ indexToPointY(index) {
326
+ return Math.floor(index / this._w);
327
+ }
328
+ /**
329
+ * Loops over all grid cells.
330
+ *
331
+ * @callback GridForEachCallback
332
+ * @param {number} x
333
+ * @param {number} y
334
+ * @param {any} value
335
+ * @param {Grid} grid
336
+ * @returns {boolean?} returns `false` to stop/break the loop
337
+ *
338
+ * @param {GridForEachCallback} handler
339
+ * @param {boolean} [reverse=false]
340
+ */
341
+ forEach(handler, reverse = false) {
342
+ let i = reverse ? this.length - 1 : 0, limit = reverse ? -1 : this.length, step = reverse ? -1 : 1;
343
+ while (i !== limit) {
344
+ const x = this.indexToPointX(i), y = this.indexToPointY(i), cellValue = this._c[i];
345
+ if (false === handler(x, y, cellValue, this)) break;
346
+ i += step;
347
+ }
348
+ }
349
+ /**
350
+ * @param {*} value
351
+ */
352
+ fill(value) {
353
+ this.forEach((x, y) => {
354
+ this.set(x, y, value);
355
+ });
356
+ }
357
+ /**
358
+ * @returns {Grid} the cloned grid
359
+ */
360
+ clone() {
361
+ return _Grid.fromArray(this._w, this._h, this._c);
362
+ }
363
+ /**
364
+ * @param {number} y
365
+ * @returns {number}
366
+ */
367
+ clampX(x) {
368
+ return _clamp(x, 0, this._w - 1);
369
+ }
370
+ /**
371
+ * @param {number} y
372
+ * @returns {number}
373
+ */
374
+ clampY(y) {
375
+ return _clamp(y, 0, this._h - 1);
376
+ }
377
+ /**
378
+ * Returns the cell values in a single array.
379
+ *
380
+ * @returns {any[]}
381
+ */
382
+ toArray() {
383
+ return this._c.slice(0);
384
+ }
385
+ /**
386
+ * @param {string} separator
387
+ * @param {boolean} format
388
+ * @returns {string}
389
+ */
390
+ toString(separator = " ", format = true) {
391
+ if (!format) return this._c.join(separator);
392
+ const rows = [];
393
+ this.forEach((x, y, value) => {
394
+ rows[y] = rows[y] || "";
395
+ rows[y] += value + separator;
396
+ });
397
+ return rows.join("\n");
398
+ }
399
+ };
400
+ function _clamp(value, min, max) {
401
+ if (value < min) return min;
402
+ if (value > max) return max;
403
+ return value;
404
+ }
405
+
201
406
  // src/vector/index.js
202
407
  var Vector = class {
203
408
  /** @type {number} */
@@ -224,7 +429,7 @@
224
429
  if (isvector(x)) {
225
430
  return veceq(v, x.x, x.y);
226
431
  }
227
- return v.x === x && v.y === (y || x);
432
+ return v.x === x && v.y === y;
228
433
  };
229
434
  var veccopy = (v) => vec(v.x, v.y);
230
435
  var vecset = (v, x, y = x) => {
@@ -322,6 +527,117 @@
322
527
  var DOWN = /* @__PURE__ */ vec(0, 1);
323
528
  var LEFT = /* @__PURE__ */ vec(-1, 0);
324
529
 
530
+ // src/actor/index.js
531
+ var ANCHOR_CENTER = vec(0.5, 0.5);
532
+ var ANCHOR_TOP_LEFT = vec(0, 0);
533
+ var ANCHOR_TOP_RIGHT = vec(1, 0);
534
+ var ANCHOR_BOT_LEFT = vec(0, 1);
535
+ var ANCHOR_BOT_RIGHT = vec(1, 1);
536
+ var Actor = class {
537
+ /** @type {Image|HTMLCanvasElement|OffscreenCanvas} */
538
+ sprite;
539
+ /** @type {Vector} The actor position */
540
+ _p;
541
+ /** @type {Vector} The actor anchor (origin) */
542
+ _o;
543
+ /** @type {Vector} The actor scale */
544
+ _s;
545
+ /** @type {number} The actor angle (in radians) */
546
+ angle = 0;
547
+ /** @type {number} The actor opacity */
548
+ opacity = 1;
549
+ /** @type {boolean} If `true` the actor will not be drawn. */
550
+ hidden = false;
551
+ /**
552
+ * @param {Image|HTMLCanvasElement|OffscreenCanvas} sprite
553
+ * @param {Vector} position
554
+ */
555
+ constructor(sprite, position) {
556
+ this.sprite = sprite;
557
+ this._p = position || vec(0);
558
+ this._o = veccopy(ANCHOR_TOP_LEFT);
559
+ this._s = vec(1, 1);
560
+ }
561
+ /**
562
+ * @param {number}
563
+ */
564
+ set x(value) {
565
+ this._p.x = value;
566
+ }
567
+ /**
568
+ * @returns {number}
569
+ */
570
+ get x() {
571
+ return this._p.x;
572
+ }
573
+ /**
574
+ * @param {number}
575
+ */
576
+ set y(value) {
577
+ this._p.y = value;
578
+ }
579
+ /**
580
+ * @returns {number}
581
+ */
582
+ get y() {
583
+ return this._p.y;
584
+ }
585
+ /**
586
+ * @param {Vector}
587
+ */
588
+ set anchor(vec2) {
589
+ this._o.x = vec2.x;
590
+ this._o.y = vec2.y;
591
+ }
592
+ /**
593
+ * @returns {Vector}
594
+ */
595
+ get anchor() {
596
+ return this._o;
597
+ }
598
+ /**
599
+ * @returns {number}
600
+ */
601
+ get width() {
602
+ return this.sprite.width * this._s.y;
603
+ }
604
+ /**
605
+ * @returns {number}
606
+ */
607
+ get height() {
608
+ return this.sprite.height * this._s.y;
609
+ }
610
+ /**
611
+ * @retuns {Vector}
612
+ */
613
+ get scale() {
614
+ return this._s;
615
+ }
616
+ /**
617
+ * Update the transformation matrix, sets the opacity and draw the actor sprite image.
618
+ *
619
+ * @param {LitecanvasInstance} [litecanvas]
620
+ */
621
+ draw(litecanvas = globalThis) {
622
+ if (this.hidden || this.opacity <= 0) return;
623
+ litecanvas.push();
624
+ this.transform(litecanvas);
625
+ const anchorX = this.sprite.width * this.anchor.x;
626
+ const anchorY = this.sprite.height * this.anchor.y;
627
+ litecanvas.image(-anchorX, -anchorY, this.sprite);
628
+ litecanvas.pop();
629
+ }
630
+ /**
631
+ * @param {LitecanvasInstance} litecanvas
632
+ */
633
+ transform(litecanvas) {
634
+ litecanvas.translate(this._p.x, this._p.y);
635
+ litecanvas.rotate(this.angle);
636
+ litecanvas.scale(this._s.x, this._s.y);
637
+ litecanvas.alpha(this.opacity);
638
+ }
639
+ };
640
+
325
641
  // src/_web.js
326
642
  globalThis.utils = src_exports;
327
643
  })();
package/dist/all.min.js CHANGED
@@ -1 +1,2 @@
1
- (()=>{var N=Object.defineProperty;var P=(e,t)=>{for(var s in t)N(e,s,{get:t[s],enumerable:!0})};var T={};P(T,{Camera:()=>a,DOWN:()=>K,LEFT:()=>Q,ONE:()=>B,RIGHT:()=>J,UP:()=>C,Vector:()=>l,ZERO:()=>j,diff:()=>L,fract:()=>q,intersection:()=>y,isvector:()=>h,resolve:()=>z,vec:()=>i,vecadd:()=>I,vecconfig:()=>k,veccopy:()=>R,veccross:()=>S,vecdir:()=>A,vecdist:()=>$,vecdist2:()=>b,vecdiv:()=>d,vecdot:()=>F,veceq:()=>E,veclerp:()=>U,veclimit:()=>Y,vecmag:()=>D,vecmag2:()=>G,vecmult:()=>M,vecnorm:()=>X,vecrand:()=>Z,vecrot:()=>W,vecset:()=>H,vecsub:()=>O,wave:()=>v});var L=(e,t)=>Math.abs(t-e)||0;var q=e=>e%1||0;var v=(e,t,s,o=Math.sin)=>e+(o(s)+1)/2*(t-e);var y=(e,t,s,o,r,n,x,p)=>{let u=Math.max(e,r),w=Math.min(e+s,r+x)-u,f=Math.max(t,n),g=Math.min(t+o,n+p)-f;return[u,f,w,g]};var z=(e,t,s,o,r,n,x,p)=>{let[u,w,f,g]=y(e,t,s,o,r,n,x,p),c="",m=e,_=t;return f<g?e<r?(c="right",m=r-s):(c="left",m=r+x):t<n?(c="bottom",_=n-o):(c="top",_=n+p),{direction:c,x:m,y:_}};var a=class{_engine=null;x=0;y=0;width=0;height=0;rotation=0;scale=1;_shake={x:0,y:0,removeListener:null};constructor(t=null){t=t||globalThis,this._engine=t,this.size(t.WIDTH||0,t.HEIGHT||0),this.x=this.width/2,this.y=this.height/2}size(t,s){this.width=t,this.height=s}start(t=!1){let s=this.width/2,o=this.height/2;this._engine.push(),this._engine.translate(s,o),this._engine.scale(this.scale),this._engine.rotate(this.rotation),this._engine.translate(-this.x+this._shake.x,-this.y+this._shake.y),t&&this._engine.cliprect(this.x,this.y,this.width,this.height)}end(){this._engine.pop()}lookAt(t,s){this.x=t,this.y=s}move(t,s){this.x+=t,this.y+=s}zoom(t){this.scale*=t}zoomTo(t){this.scale=t}rotate(t){this.rotation+=t}rotateTo(t){this.rotation=t}shake(t=.3,s=1){this.shaking()||(this._shake.removeListener=this._engine.listen("update",o=>{this._shake.x=this._engine.randi(-s,s),this._shake.y=this._engine.randi(-s,s),t-=o,t<=0&&this.unshake()}))}unshake(){this.shaking()&&(this._shake.removeListener(),this._shake.removeListener=null,this._shake.x=this._shake.y=0)}shaking(){return this._shake.removeListener!==null}};var l=class{x;y;constructor(t=0,s=t){this.x=t,this.y=s}toString(){return`Vector (${this.x}, ${this.y})`}},i=(e=0,t=e)=>new l(e,t),E=(e,t,s=t)=>h(t)?E(e,t.x,t.y):e.x===t&&e.y===(s||t),R=e=>i(e.x,e.y),H=(e,t,s=t)=>{h(t)?H(e,t.x,t.y):(e.x=t,e.y=s)},I=(e,t,s=t)=>{h(t)?I(e,t.x,t.y):(e.x+=t,e.y+=s)},O=(e,t,s=t)=>{h(t)?O(e,t.x,t.y):(e.x-=t,e.y-=s)},M=(e,t,s=t)=>{h(t)?M(e,t.x,t.y):(e.x*=t,e.y*=s)},d=(e,t,s=t)=>{h(t)?d(e,t.x,t.y):(e.x/=t,e.y/=s)},W=(e,t)=>{let s=Math.cos(t),o=Math.sin(t);e.x=s*e.x-o*e.y,e.y=o*e.x+s*e.y},D=e=>Math.sqrt(e.x*e.x+e.y*e.y),G=e=>e.x*e.x+e.y*e.y,X=e=>{let t=D(e);t>0&&d(e,t)},Y=(e,t)=>{let s=G(e);s>t*t&&(d(e,Math.sqrt(s)),M(e,t))},$=(e,t)=>{let s=e.x-t.x,o=e.y-t.y;return Math.sqrt(s*s+o*o)},b=(e,t)=>{let s=e.x-t.x,o=e.y-t.y;return s*s+o*o},A=e=>Math.atan2(e.y,e.x),F=(e,t)=>e.x*t.x+e.y*t.y,S=(e,t)=>e.x*t.y-e.y*t.x,U=(e,t,s)=>{e.x+=(t.x-e.x)*s||0,e.y+=(t.y-e.y)*s||0},Z=(e=1,t=e)=>{let s=k.random()*2*Math.PI,o=k.random()*(t-e)+e;return i(Math.cos(s)*o,Math.sin(s)*o)},h=e=>e instanceof l,k={random:()=>globalThis.rand?rand():Math.random()},j=i(0,0),B=i(1,1),C=i(0,-1),J=i(1,0),K=i(0,1),Q=i(-1,0);globalThis.utils=T;})();
1
+ (()=>{var L=Object.defineProperty;var v=(e,t)=>{for(var s in t)L(e,s,{get:t[s],enumerable:!0})};var A={};v(A,{ANCHOR_BOT_LEFT:()=>it,ANCHOR_BOT_RIGHT:()=>nt,ANCHOR_CENTER:()=>ot,ANCHOR_TOP_LEFT:()=>W,ANCHOR_TOP_RIGHT:()=>rt,Actor:()=>I,Camera:()=>p,DOWN:()=>et,Grid:()=>u,LEFT:()=>st,ONE:()=>K,RIGHT:()=>tt,UP:()=>Q,Vector:()=>d,ZERO:()=>J,diff:()=>M,fract:()=>P,intersection:()=>g,isvector:()=>c,resolve:()=>O,vec:()=>i,vecadd:()=>S,vecconfig:()=>w,veccopy:()=>H,veccross:()=>V,vecdir:()=>$,vecdist:()=>B,vecdist2:()=>j,vecdiv:()=>_,vecdot:()=>q,veceq:()=>k,veclerp:()=>U,veclimit:()=>F,vecmag:()=>R,vecmag2:()=>Y,vecmult:()=>E,vecnorm:()=>N,vecrand:()=>Z,vecrot:()=>G,vecset:()=>z,vecsub:()=>X,wave:()=>b});var M=(e,t)=>Math.abs(t-e)||0;var P=e=>e%1||0;var b=(e,t,s,o=Math.sin)=>e+(o(s)+1)/2*(t-e);var g=(e,t,s,o,n,r,a,h)=>{let l=Math.max(e,n),D=Math.min(e+s,n+a)-l,x=Math.max(t,r),m=Math.min(t+o,r+h)-x;return[l,x,D,m]};var O=(e,t,s,o,n,r,a,h)=>{let[l,D,x,m]=g(e,t,s,o,n,r,a,h),f="",y=e,T=t;return x<m?e<n?(f="right",y=n-s):(f="left",y=n+a):t<r?(f="bottom",T=r-o):(f="top",T=r+h),{direction:f,x:y,y:T}};var p=class{_engine=null;x=0;y=0;width=0;height=0;rotation=0;scale=1;_shake={x:0,y:0,removeListener:null};constructor(t=null){t=t||globalThis,this._engine=t,this.size(t.WIDTH||0,t.HEIGHT||0),this.x=this.width/2,this.y=this.height/2}size(t,s){this.width=t,this.height=s}start(t=!1){let s=this.width/2,o=this.height/2;this._engine.push(),this._engine.translate(s,o),this._engine.scale(this.scale),this._engine.rotate(this.rotation),this._engine.translate(-this.x+this._shake.x,-this.y+this._shake.y),t&&this._engine.cliprect(this.x,this.y,this.width,this.height)}end(){this._engine.pop()}lookAt(t,s){this.x=t,this.y=s}move(t,s){this.x+=t,this.y+=s}zoom(t){this.scale*=t}zoomTo(t){this.scale=t}rotate(t){this.rotation+=t}rotateTo(t){this.rotation=t}shake(t=.3,s=1){this.shaking()||(this._shake.removeListener=this._engine.listen("update",o=>{this._shake.x=this._engine.randi(-s,s),this._shake.y=this._engine.randi(-s,s),t-=o,t<=0&&this.unshake()}))}unshake(){this.shaking()&&(this._shake.removeListener(),this._shake.removeListener=null,this._shake.x=this._shake.y=0)}shaking(){return this._shake.removeListener!==null}};var u=class e{_w;_h;_c;static fromArray(t,s,o){let n=new e(t,s);for(let r=0;r<o.length;r++)n._c[r]=o[r];return n}constructor(t,s){this.width=t,this.height=s,this.clear()}clear(){this._c=Array(this._w*this._h)}set width(t){this._w=Math.max(1,~~t)}get width(){return this._w}set height(t){this._h=Math.max(1,~~t)}get height(){return this._h}set(t,s,o){this._c[this.pointToIndex(t,s)]=o}get(t,s){return this._c[this.pointToIndex(t,s)]}has(t,s){return this.get(t,s)!=null}get length(){return this._w*this._h}pointToIndex(t,s){return this.clampX(~~t)+this.clampY(~~s)*this._w}indexToPointX(t){return t%this._w}indexToPointY(t){return Math.floor(t/this._w)}forEach(t,s=!1){let o=s?this.length-1:0,n=s?-1:this.length,r=s?-1:1;for(;o!==n;){let a=this.indexToPointX(o),h=this.indexToPointY(o),l=this._c[o];if(t(a,h,l,this)===!1)break;o+=r}}fill(t){this.forEach((s,o)=>{this.set(s,o,t)})}clone(){return e.fromArray(this._w,this._h,this._c)}clampX(t){return C(t,0,this._w-1)}clampY(t){return C(t,0,this._h-1)}toArray(){return this._c.slice(0)}toString(t=" ",s=!0){if(!s)return this._c.join(t);let o=[];return this.forEach((n,r,a)=>{o[r]=o[r]||"",o[r]+=a+t}),o.join(`
2
+ `)}};function C(e,t,s){return e<t?t:e>s?s:e}var d=class{x;y;constructor(t=0,s=t){this.x=t,this.y=s}toString(){return`Vector (${this.x}, ${this.y})`}},i=(e=0,t=e)=>new d(e,t),k=(e,t,s=t)=>c(t)?k(e,t.x,t.y):e.x===t&&e.y===s,H=e=>i(e.x,e.y),z=(e,t,s=t)=>{c(t)?z(e,t.x,t.y):(e.x=t,e.y=s)},S=(e,t,s=t)=>{c(t)?S(e,t.x,t.y):(e.x+=t,e.y+=s)},X=(e,t,s=t)=>{c(t)?X(e,t.x,t.y):(e.x-=t,e.y-=s)},E=(e,t,s=t)=>{c(t)?E(e,t.x,t.y):(e.x*=t,e.y*=s)},_=(e,t,s=t)=>{c(t)?_(e,t.x,t.y):(e.x/=t,e.y/=s)},G=(e,t)=>{let s=Math.cos(t),o=Math.sin(t);e.x=s*e.x-o*e.y,e.y=o*e.x+s*e.y},R=e=>Math.sqrt(e.x*e.x+e.y*e.y),Y=e=>e.x*e.x+e.y*e.y,N=e=>{let t=R(e);t>0&&_(e,t)},F=(e,t)=>{let s=Y(e);s>t*t&&(_(e,Math.sqrt(s)),E(e,t))},B=(e,t)=>{let s=e.x-t.x,o=e.y-t.y;return Math.sqrt(s*s+o*o)},j=(e,t)=>{let s=e.x-t.x,o=e.y-t.y;return s*s+o*o},$=e=>Math.atan2(e.y,e.x),q=(e,t)=>e.x*t.x+e.y*t.y,V=(e,t)=>e.x*t.y-e.y*t.x,U=(e,t,s)=>{e.x+=(t.x-e.x)*s||0,e.y+=(t.y-e.y)*s||0},Z=(e=1,t=e)=>{let s=w.random()*2*Math.PI,o=w.random()*(t-e)+e;return i(Math.cos(s)*o,Math.sin(s)*o)},c=e=>e instanceof d,w={random:()=>globalThis.rand?rand():Math.random()},J=i(0,0),K=i(1,1),Q=i(0,-1),tt=i(1,0),et=i(0,1),st=i(-1,0);var ot=i(.5,.5),W=i(0,0),rt=i(1,0),it=i(0,1),nt=i(1,1),I=class{sprite;_p;_o;_s;angle=0;opacity=1;hidden=!1;constructor(t,s){this.sprite=t,this._p=s||i(0),this._o=H(W),this._s=i(1,1)}set x(t){this._p.x=t}get x(){return this._p.x}set y(t){this._p.y=t}get y(){return this._p.y}set anchor(t){this._o.x=t.x,this._o.y=t.y}get anchor(){return this._o}get width(){return this.sprite.width*this._s.y}get height(){return this.sprite.height*this._s.y}get scale(){return this._s}draw(t=globalThis){if(this.hidden||this.opacity<=0)return;t.push(),this.transform(t);let s=this.sprite.width*this.anchor.x,o=this.sprite.height*this.anchor.y;t.image(-s,-o,this.sprite),t.pop()}transform(t){t.translate(this._p.x,this._p.y),t.rotate(this.angle),t.scale(this._s.x,this._s.y),t.alpha(this.opacity)}};globalThis.utils=A;})();