@litecanvas/utils 0.7.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,6 +2,46 @@
2
2
 
3
3
  Small collection of tools for developing games with [Litecanvas](https://github.com/litecanvas/game-engine).
4
4
 
5
+ ## Install
6
+
7
+ ### NPM package
8
+
9
+ ```
10
+ npm i @litecanvas/utils
11
+ ```
12
+
13
+ ```js
14
+ // import everything
15
+ import * as utils from "@litecanvas/utils"
16
+
17
+ const pos = utils.vec(0, 0)
18
+ ```
19
+
20
+ ```js
21
+ // or import just what you want
22
+ import { vec } from "@litecanvas/utils"
23
+
24
+ const pos = vec(0, 0)
25
+ ```
26
+
27
+ ### CDN
28
+
29
+ Download from https://unpkg.com/browse/@litecanvas/utils/dist/ and load in a `<script>` tag in your HTML.
30
+
31
+ ```js
32
+ // now the "utils" namespace is created
33
+ const pos = utils.vec(0, 0)
34
+ ```
35
+
36
+ ```js
37
+ // also, you can call this once to
38
+ // expose the components globally
39
+ utils.global()
40
+
41
+ // now the namescape is not required
42
+ const pos = vec(0, 0)
43
+ ```
44
+
5
45
  ## Components
6
46
 
7
47
  - **Camera**: Move-, zoom- and rotatable camera with shake. [Usage & Docs](https://github.com/litecanvas/utils/tree/main/src/camera)
@@ -10,9 +50,3 @@ Small collection of tools for developing games with [Litecanvas](https://github.
10
50
  - **Grid**: class to handle retangular grid areas. [Usage & Docs](https://github.com/litecanvas/utils/tree/main/src/grid)
11
51
  - **Collision** utilities. [Usage & Docs](https://github.com/litecanvas/utils/tree/main/src/collision)
12
52
  - And [some math utilities](https://github.com/litecanvas/utils/tree/main/src/math)
13
-
14
- ## Install
15
-
16
- ```
17
- npm i @litecanvas/utils
18
- ```
package/dist/all.js CHANGED
@@ -29,6 +29,7 @@
29
29
  LEFT: () => LEFT,
30
30
  ONE: () => ONE,
31
31
  RIGHT: () => RIGHT,
32
+ TypedGrid: () => TypedGrid,
32
33
  UP: () => UP,
33
34
  Vector: () => Vector,
34
35
  ZERO: () => ZERO,
@@ -222,49 +223,32 @@
222
223
  _h;
223
224
  /** @type {any[]} The grid cells */
224
225
  _c;
225
- /**
226
- * @static
227
- * @param {number} width
228
- * @param {number} height
229
- * @param {any[]} values
230
- */
231
- static fromArray(width, height, values) {
232
- const grid = new _Grid(width, height);
233
- for (let i = 0; i < values.length; i++) {
234
- grid._c[i] = values[i];
235
- }
236
- return grid;
237
- }
238
226
  /**
239
227
  * @param {number} width The grid width
240
228
  * @param {number} height The grid height
241
229
  */
242
- constructor(width, height) {
243
- this.width = width;
244
- this.height = height;
245
- this.clear();
230
+ constructor(width, height, values = []) {
231
+ this._w = Math.max(1, ~~width);
232
+ this._h = Math.max(1, ~~height);
233
+ this._c = values;
246
234
  }
247
235
  /**
248
236
  * Delete all cell values.
249
237
  */
250
238
  clear() {
251
- this._c = Array(this._w * this._h);
239
+ this.forEach((x, y) => this.set(x, y, void 0));
252
240
  }
253
241
  /**
254
- * @param {number} value
242
+ * @returns {number}
243
+ * @readonly
255
244
  */
256
- set width(value) {
257
- this._w = Math.max(1, ~~value);
258
- }
259
245
  get width() {
260
246
  return this._w;
261
247
  }
262
248
  /**
263
- * @param {number} value
249
+ * @returns {number}
250
+ * @readonly
264
251
  */
265
- set height(value) {
266
- this._h = Math.max(1, ~~value);
267
- }
268
252
  get height() {
269
253
  return this._h;
270
254
  }
@@ -389,7 +373,7 @@
389
373
  * @returns {any[]}
390
374
  */
391
375
  toArray() {
392
- return this._c.slice(0);
376
+ return this._c.slice();
393
377
  }
394
378
  /**
395
379
  * @param {string} separator
@@ -406,6 +390,34 @@
406
390
  return rows.join("\n");
407
391
  }
408
392
  };
393
+ var TypedGrid = class _TypedGrid extends Grid {
394
+ /**
395
+ * @param {number} width The grid width
396
+ * @param {number} height The grid height
397
+ */
398
+ constructor(width, height, TypedArray = Uint8Array) {
399
+ super(width, height, null);
400
+ this._c = new TypedArray(this._w * this._h);
401
+ }
402
+ /**
403
+ * @param {number} x
404
+ * @param {number} y
405
+ * @returns {boolean}
406
+ */
407
+ has(x, y) {
408
+ return this.get(x, y) !== 0;
409
+ }
410
+ /**
411
+ * @returns {TypedGrid}
412
+ */
413
+ clone() {
414
+ const copy = new _TypedGrid(this._w, this._h, this._c.constructor);
415
+ this.forEach((x, y, value) => {
416
+ copy.set(x, y, value);
417
+ });
418
+ return copy;
419
+ }
420
+ };
409
421
  function _clamp(value, min, max) {
410
422
  if (value < min) return min;
411
423
  if (value > max) return max;
package/dist/all.min.js CHANGED
@@ -1,2 +1,2 @@
1
- (()=>{var L=Object.defineProperty;var G=(e,t)=>{for(var s in t)L(e,s,{get:t[s],enumerable:!0})};globalThis.utils=globalThis.utils||{};globalThis.utils.global=()=>{for(let e in globalThis.utils)e!=="global"&&(globalThis[e]=globalThis.utils[e])};var I={};G(I,{ANCHOR_BOT_LEFT:()=>rt,ANCHOR_BOT_RIGHT:()=>nt,ANCHOR_CENTER:()=>ot,ANCHOR_TOP_LEFT:()=>W,ANCHOR_TOP_RIGHT:()=>it,Actor:()=>b,Camera:()=>p,DOWN:()=>et,Grid:()=>u,LEFT:()=>st,ONE:()=>K,RIGHT:()=>tt,UP:()=>Q,Vector:()=>d,ZERO:()=>J,diff:()=>D,fract:()=>M,intersection:()=>x,isvector:()=>l,resolve:()=>O,vec:()=>r,vecadd:()=>S,vecconfig:()=>w,veccopy:()=>H,veccross:()=>V,vecdir:()=>q,vecdist:()=>j,vecdist2:()=>$,vecdiv:()=>_,vecdot:()=>N,veceq:()=>k,veclerp:()=>U,veclimit:()=>B,vecmag:()=>R,vecmag2:()=>Y,vecmult:()=>E,vecnorm:()=>F,vecrand:()=>Z,vecrot:()=>v,vecset:()=>z,vecsub:()=>X,wave:()=>P});var D=(e,t)=>Math.abs(t-e)||0;var M=e=>e%1||0;var P=(e,t,s,o=Math.sin)=>e+(o(s)+1)/2*(t-e);var x=(e,t,s,o,n,i,a,c)=>{let h=Math.max(e,n),A=Math.min(e+s,n+a)-h,g=Math.max(t,i),m=Math.min(t+o,i+c)-g;return[h,g,A,m]};var O=(e,t,s,o,n,i,a,c)=>{let[h,A,g,m]=x(e,t,s,o,n,i,a,c),f="",y=e,T=t;return g<m?e<n?(f="right",y=n-s):(f="left",y=n+a):t<i?(f="bottom",T=i-o):(f="top",T=i+c),{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 i=0;i<o.length;i++)n._c[i]=o[i];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,i=s?-1:1;for(;o!==n;){let a=this.indexToPointX(o),c=this.indexToPointY(o),h=this._c[o];if(t(a,c,h,this)===!1)break;o+=i}}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,i,a)=>{o[i]=o[i]||"",o[i]+=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})`}},r=(e=0,t=e)=>new d(e,t),k=(e,t,s=t)=>l(t)?k(e,t.x,t.y):e.x===t&&e.y===s,H=e=>r(e.x,e.y),z=(e,t,s=t)=>{l(t)?z(e,t.x,t.y):(e.x=t,e.y=s)},S=(e,t,s=t)=>{l(t)?S(e,t.x,t.y):(e.x+=t,e.y+=s)},X=(e,t,s=t)=>{l(t)?X(e,t.x,t.y):(e.x-=t,e.y-=s)},E=(e,t,s=t)=>{l(t)?E(e,t.x,t.y):(e.x*=t,e.y*=s)},_=(e,t,s=t)=>{l(t)?_(e,t.x,t.y):(e.x/=t,e.y/=s)},v=(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,F=e=>{let t=R(e);t>0&&_(e,t)},B=(e,t)=>{let s=Y(e);s>t*t&&(_(e,Math.sqrt(s)),E(e,t))},j=(e,t)=>{let s=e.x-t.x,o=e.y-t.y;return Math.sqrt(s*s+o*o)},$=(e,t)=>{let s=e.x-t.x,o=e.y-t.y;return s*s+o*o},q=e=>Math.atan2(e.y,e.x),N=(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 r(Math.cos(s)*o,Math.sin(s)*o)},l=e=>e instanceof d,w={random:()=>globalThis.rand?rand():Math.random()},J=r(0,0),K=r(1,1),Q=r(0,-1),tt=r(1,0),et=r(0,1),st=r(-1,0);var ot=r(.5,.5),W=r(0,0),it=r(1,0),rt=r(0,1),nt=r(1,1),b=class{sprite;pos;_o;_s;angle=0;opacity=1;hidden=!1;constructor(t,s){this.sprite=t,this.pos=s||r(0),this._o=H(W),this._s=r(1,1)}set x(t){this.pos.x=t}get x(){return this.pos.x}set y(t){this.pos.y=t}get y(){return this.pos.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.pos.x,this.pos.y),t.rotate(this.angle),t.scale(this._s.x,this._s.y),t.alpha(this.opacity)}};globalThis.utils=Object.assign(globalThis.utils||{},I);})();
1
+ (()=>{var v=Object.defineProperty;var F=(e,t)=>{for(var s in t)v(e,s,{get:t[s],enumerable:!0})};globalThis.utils=globalThis.utils||{};globalThis.utils.global=()=>{for(let e in globalThis.utils)e!=="global"&&(globalThis[e]=globalThis.utils[e])};var A={};F(A,{ANCHOR_BOT_LEFT:()=>nt,ANCHOR_BOT_RIGHT:()=>at,ANCHOR_CENTER:()=>it,ANCHOR_TOP_LEFT:()=>L,ANCHOR_TOP_RIGHT:()=>rt,Actor:()=>I,Camera:()=>p,DOWN:()=>st,Grid:()=>g,LEFT:()=>ot,ONE:()=>Q,RIGHT:()=>et,TypedGrid:()=>w,UP:()=>tt,Vector:()=>u,ZERO:()=>K,diff:()=>M,fract:()=>P,intersection:()=>x,isvector:()=>c,resolve:()=>C,vec:()=>i,vecadd:()=>X,vecconfig:()=>H,veccopy:()=>E,veccross:()=>U,vecdir:()=>N,vecdist:()=>$,vecdist2:()=>q,vecdiv:()=>_,vecdot:()=>V,veceq:()=>z,veclerp:()=>Z,veclimit:()=>j,vecmag:()=>Y,vecmag2:()=>W,vecmult:()=>b,vecnorm:()=>B,vecrand:()=>J,vecrot:()=>G,vecset:()=>S,vecsub:()=>R,wave:()=>O});var M=(e,t)=>Math.abs(t-e)||0;var P=e=>e%1||0;var O=(e,t,s,o=Math.sin)=>e+(o(s)+1)/2*(t-e);var x=(e,t,s,o,n,r,a,l)=>{let h=Math.max(e,n),D=Math.min(e+s,n+a)-h,d=Math.max(t,r),m=Math.min(t+o,r+l)-d;return[h,d,D,m]};var C=(e,t,s,o,n,r,a,l)=>{let[h,D,d,m]=x(e,t,s,o,n,r,a,l),f="",y=e,T=t;return d<m?e<n?(f="right",y=n-s):(f="left",y=n+a):t<r?(f="bottom",T=r-o):(f="top",T=r+l),{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 g=class e{_w;_h;_c;constructor(t,s,o=[]){this._w=Math.max(1,~~t),this._h=Math.max(1,~~s),this._c=o}clear(){this.forEach((t,s)=>this.set(t,s,void 0))}get width(){return this._w}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),l=this.indexToPointY(o),h=this._c[o];if(t(a,l,h,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 k(t,0,this._w-1)}clampY(t){return k(t,0,this._h-1)}toArray(){return this._c.slice()}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
+ `)}},w=class e extends g{constructor(t,s,o=Uint8Array){super(t,s,null),this._c=new o(this._w*this._h)}has(t,s){return this.get(t,s)!==0}clone(){let t=new e(this._w,this._h,this._c.constructor);return this.forEach((s,o,n)=>{t.set(s,o,n)}),t}};function k(e,t,s){return e<t?t:e>s?s:e}var u=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 u(e,t),z=(e,t,s=t)=>c(t)?z(e,t.x,t.y):e.x===t&&e.y===s,E=e=>i(e.x,e.y),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)},R=(e,t,s=t)=>{c(t)?R(e,t.x,t.y):(e.x-=t,e.y-=s)},b=(e,t,s=t)=>{c(t)?b(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},Y=e=>Math.sqrt(e.x*e.x+e.y*e.y),W=e=>e.x*e.x+e.y*e.y,B=e=>{let t=Y(e);t>0&&_(e,t)},j=(e,t)=>{let s=W(e);s>t*t&&(_(e,Math.sqrt(s)),b(e,t))},$=(e,t)=>{let s=e.x-t.x,o=e.y-t.y;return Math.sqrt(s*s+o*o)},q=(e,t)=>{let s=e.x-t.x,o=e.y-t.y;return s*s+o*o},N=e=>Math.atan2(e.y,e.x),V=(e,t)=>e.x*t.x+e.y*t.y,U=(e,t)=>e.x*t.y-e.y*t.x,Z=(e,t,s)=>{e.x+=(t.x-e.x)*s||0,e.y+=(t.y-e.y)*s||0},J=(e=1,t=e)=>{let s=H.random()*2*Math.PI,o=H.random()*(t-e)+e;return i(Math.cos(s)*o,Math.sin(s)*o)},c=e=>e instanceof u,H={random:()=>globalThis.rand?rand():Math.random()},K=i(0,0),Q=i(1,1),tt=i(0,-1),et=i(1,0),st=i(0,1),ot=i(-1,0);var it=i(.5,.5),L=i(0,0),rt=i(1,0),nt=i(0,1),at=i(1,1),I=class{sprite;pos;_o;_s;angle=0;opacity=1;hidden=!1;constructor(t,s){this.sprite=t,this.pos=s||i(0),this._o=E(L),this._s=i(1,1)}set x(t){this.pos.x=t}get x(){return this.pos.x}set y(t){this.pos.y=t}get y(){return this.pos.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.pos.x,this.pos.y),t.rotate(this.angle),t.scale(this._s.x,this._s.y),t.alpha(this.opacity)}};globalThis.utils=Object.assign(globalThis.utils||{},A);})();
package/dist/grid.js CHANGED
@@ -1,4 +1,10 @@
1
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
+
2
8
  // src/_global.js
3
9
  globalThis.utils = globalThis.utils || {};
4
10
  globalThis.utils.global = () => {
@@ -9,6 +15,11 @@
9
15
  };
10
16
 
11
17
  // src/grid/index.js
18
+ var grid_exports = {};
19
+ __export(grid_exports, {
20
+ Grid: () => Grid,
21
+ TypedGrid: () => TypedGrid
22
+ });
12
23
  var Grid = class _Grid {
13
24
  /** @type {number} The grid width */
14
25
  _w;
@@ -16,49 +27,32 @@
16
27
  _h;
17
28
  /** @type {any[]} The grid cells */
18
29
  _c;
19
- /**
20
- * @static
21
- * @param {number} width
22
- * @param {number} height
23
- * @param {any[]} values
24
- */
25
- static fromArray(width, height, values) {
26
- const grid = new _Grid(width, height);
27
- for (let i = 0; i < values.length; i++) {
28
- grid._c[i] = values[i];
29
- }
30
- return grid;
31
- }
32
30
  /**
33
31
  * @param {number} width The grid width
34
32
  * @param {number} height The grid height
35
33
  */
36
- constructor(width, height) {
37
- this.width = width;
38
- this.height = height;
39
- this.clear();
34
+ constructor(width, height, values = []) {
35
+ this._w = Math.max(1, ~~width);
36
+ this._h = Math.max(1, ~~height);
37
+ this._c = values;
40
38
  }
41
39
  /**
42
40
  * Delete all cell values.
43
41
  */
44
42
  clear() {
45
- this._c = Array(this._w * this._h);
43
+ this.forEach((x, y) => this.set(x, y, void 0));
46
44
  }
47
45
  /**
48
- * @param {number} value
46
+ * @returns {number}
47
+ * @readonly
49
48
  */
50
- set width(value) {
51
- this._w = Math.max(1, ~~value);
52
- }
53
49
  get width() {
54
50
  return this._w;
55
51
  }
56
52
  /**
57
- * @param {number} value
53
+ * @returns {number}
54
+ * @readonly
58
55
  */
59
- set height(value) {
60
- this._h = Math.max(1, ~~value);
61
- }
62
56
  get height() {
63
57
  return this._h;
64
58
  }
@@ -183,7 +177,7 @@
183
177
  * @returns {any[]}
184
178
  */
185
179
  toArray() {
186
- return this._c.slice(0);
180
+ return this._c.slice();
187
181
  }
188
182
  /**
189
183
  * @param {string} separator
@@ -200,6 +194,34 @@
200
194
  return rows.join("\n");
201
195
  }
202
196
  };
197
+ var TypedGrid = class _TypedGrid extends Grid {
198
+ /**
199
+ * @param {number} width The grid width
200
+ * @param {number} height The grid height
201
+ */
202
+ constructor(width, height, TypedArray = Uint8Array) {
203
+ super(width, height, null);
204
+ this._c = new TypedArray(this._w * this._h);
205
+ }
206
+ /**
207
+ * @param {number} x
208
+ * @param {number} y
209
+ * @returns {boolean}
210
+ */
211
+ has(x, y) {
212
+ return this.get(x, y) !== 0;
213
+ }
214
+ /**
215
+ * @returns {TypedGrid}
216
+ */
217
+ clone() {
218
+ const copy = new _TypedGrid(this._w, this._h, this._c.constructor);
219
+ this.forEach((x, y, value) => {
220
+ copy.set(x, y, value);
221
+ });
222
+ return copy;
223
+ }
224
+ };
203
225
  function _clamp(value, min, max) {
204
226
  if (value < min) return min;
205
227
  if (value > max) return max;
@@ -207,5 +229,5 @@
207
229
  }
208
230
 
209
231
  // src/grid/_web.js
210
- globalThis.utils = Object.assign(globalThis.utils || {}, { Grid });
232
+ globalThis.utils = Object.assign(globalThis.utils || {}, grid_exports);
211
233
  })();
package/dist/grid.min.js CHANGED
@@ -1,2 +1,2 @@
1
- (()=>{globalThis.utils=globalThis.utils||{};globalThis.utils.global=()=>{for(let s in globalThis.utils)s!=="global"&&(globalThis[s]=globalThis.utils[s])};var n=class s{_w;_h;_c;static fromArray(t,i,h){let l=new s(t,i);for(let r=0;r<h.length;r++)l._c[r]=h[r];return l}constructor(t,i){this.width=t,this.height=i,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,i,h){this._c[this.pointToIndex(t,i)]=h}get(t,i){return this._c[this.pointToIndex(t,i)]}has(t,i){return this.get(t,i)!=null}get length(){return this._w*this._h}pointToIndex(t,i){return this.clampX(~~t)+this.clampY(~~i)*this._w}indexToPointX(t){return t%this._w}indexToPointY(t){return Math.floor(t/this._w)}forEach(t,i=!1){let h=i?this.length-1:0,l=i?-1:this.length,r=i?-1:1;for(;h!==l;){let e=this.indexToPointX(h),c=this.indexToPointY(h),a=this._c[h];if(t(e,c,a,this)===!1)break;h+=r}}fill(t){this.forEach((i,h)=>{this.set(i,h,t)})}clone(){return s.fromArray(this._w,this._h,this._c)}clampX(t){return o(t,0,this._w-1)}clampY(t){return o(t,0,this._h-1)}toArray(){return this._c.slice(0)}toString(t=" ",i=!0){if(!i)return this._c.join(t);let h=[];return this.forEach((l,r,e)=>{h[r]=h[r]||"",h[r]+=e+t}),h.join(`
2
- `)}};function o(s,t,i){return s<t?t:s>i?i:s}globalThis.utils=Object.assign(globalThis.utils||{},{Grid:n});})();
1
+ (()=>{var g=Object.defineProperty;var f=(h,t)=>{for(var i in t)g(h,i,{get:t[i],enumerable:!0})};globalThis.utils=globalThis.utils||{};globalThis.utils.global=()=>{for(let h in globalThis.utils)h!=="global"&&(globalThis[h]=globalThis.utils[h])};var c={};f(c,{Grid:()=>o,TypedGrid:()=>l});var o=class h{_w;_h;_c;constructor(t,i,s=[]){this._w=Math.max(1,~~t),this._h=Math.max(1,~~i),this._c=s}clear(){this.forEach((t,i)=>this.set(t,i,void 0))}get width(){return this._w}get height(){return this._h}set(t,i,s){this._c[this.pointToIndex(t,i)]=s}get(t,i){return this._c[this.pointToIndex(t,i)]}has(t,i){return this.get(t,i)!=null}get length(){return this._w*this._h}pointToIndex(t,i){return this.clampX(~~t)+this.clampY(~~i)*this._w}indexToPointX(t){return t%this._w}indexToPointY(t){return Math.floor(t/this._w)}forEach(t,i=!1){let s=i?this.length-1:0,r=i?-1:this.length,n=i?-1:1;for(;s!==r;){let e=this.indexToPointX(s),a=this.indexToPointY(s),_=this._c[s];if(t(e,a,_,this)===!1)break;s+=n}}fill(t){this.forEach((i,s)=>{this.set(i,s,t)})}clone(){return h.fromArray(this._w,this._h,this._c)}clampX(t){return u(t,0,this._w-1)}clampY(t){return u(t,0,this._h-1)}toArray(){return this._c.slice()}toString(t=" ",i=!0){if(!i)return this._c.join(t);let s=[];return this.forEach((r,n,e)=>{s[n]=s[n]||"",s[n]+=e+t}),s.join(`
2
+ `)}},l=class h extends o{constructor(t,i,s=Uint8Array){super(t,i,null),this._c=new s(this._w*this._h)}has(t,i){return this.get(t,i)!==0}clone(){let t=new h(this._w,this._h,this._c.constructor);return this.forEach((i,s,r)=>{t.set(i,s,r)}),t}};function u(h,t,i){return h<t?t:h>i?i:h}globalThis.utils=Object.assign(globalThis.utils||{},c);})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@litecanvas/utils",
3
- "version": "0.7.0",
3
+ "version": "0.8.1",
4
4
  "description": "Utilities to help build litecanvas games",
5
5
  "author": "Luiz Bills <luizbills@pm.me>",
6
6
  "license": "MIT",
@@ -17,9 +17,10 @@
17
17
  "keywords": [
18
18
  "litecanvas",
19
19
  "utilities",
20
+ "helpers",
20
21
  "camera",
21
22
  "vector",
22
- "gamedev"
23
+ "grid"
23
24
  ],
24
25
  "scripts": {
25
26
  "dev": "esbuild src/_web.js --bundle --watch --outfile=dist/all.js --servedir=.",
@@ -1,4 +1,4 @@
1
- # Grid
1
+ # Grid utils
2
2
 
3
3
  **CDN**: https://unpkg.com/@litecanvas/utils/dist/grid.js
4
4
 
@@ -45,3 +45,17 @@ The result:
45
45
  # . . . . . . . . . . . #
46
46
  # # # # # # # # # # # # #
47
47
  ```
48
+
49
+ ## Typed Grid
50
+
51
+ You can create a grid structure thats uses a [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Typed_arrays) rather than a "normal" array.
52
+
53
+ ```
54
+ import { TypedGrid } from "@litecanvas/utils"
55
+
56
+ let u8grid = new TypedGrid(5, 5) // by default, uses Uint8Array
57
+
58
+ let i16grid = new TypedGrid(5, 5, Int16Array) // or specify your typed array
59
+ ```
60
+
61
+ > Note: `TypedGrid` inherits all methods from `Grid`.
package/src/grid/_web.js CHANGED
@@ -1,4 +1,4 @@
1
1
  import "../_global.js"
2
- import Grid from "./index.js"
2
+ import * as gridUtils from "./index.js"
3
3
 
4
- globalThis.utils = Object.assign(globalThis.utils || {}, { Grid })
4
+ globalThis.utils = Object.assign(globalThis.utils || {}, gridUtils)
package/src/grid/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export default class Grid {
1
+ export class Grid {
2
2
  /** @type {number} The grid width */
3
3
  _w
4
4
 
@@ -8,55 +8,35 @@ export default class Grid {
8
8
  /** @type {any[]} The grid cells */
9
9
  _c
10
10
 
11
- /**
12
- * @static
13
- * @param {number} width
14
- * @param {number} height
15
- * @param {any[]} values
16
- */
17
- static fromArray(width, height, values) {
18
- const grid = new Grid(width, height)
19
- for (let i = 0; i < values.length; i++) {
20
- grid._c[i] = values[i]
21
- }
22
- return grid
23
- }
24
-
25
11
  /**
26
12
  * @param {number} width The grid width
27
13
  * @param {number} height The grid height
28
14
  */
29
- constructor(width, height) {
30
- this.width = width
31
- this.height = height
32
- this.clear()
15
+ constructor(width, height, values = []) {
16
+ this._w = Math.max(1, ~~width)
17
+ this._h = Math.max(1, ~~height)
18
+ this._c = values
33
19
  }
34
20
 
35
21
  /**
36
22
  * Delete all cell values.
37
23
  */
38
24
  clear() {
39
- this._c = Array(this._w * this._h)
25
+ this.forEach((x, y) => this.set(x, y, undefined))
40
26
  }
41
27
 
42
28
  /**
43
- * @param {number} value
29
+ * @returns {number}
30
+ * @readonly
44
31
  */
45
- set width(value) {
46
- this._w = Math.max(1, ~~value)
47
- }
48
-
49
32
  get width() {
50
33
  return this._w
51
34
  }
52
35
 
53
36
  /**
54
- * @param {number} value
37
+ * @returns {number}
38
+ * @readonly
55
39
  */
56
- set height(value) {
57
- this._h = Math.max(1, ~~value)
58
- }
59
-
60
40
  get height() {
61
41
  return this._h
62
42
  }
@@ -201,7 +181,7 @@ export default class Grid {
201
181
  * @returns {any[]}
202
182
  */
203
183
  toArray() {
204
- return this._c.slice(0)
184
+ return this._c.slice()
205
185
  }
206
186
 
207
187
  /**
@@ -222,6 +202,37 @@ export default class Grid {
222
202
  }
223
203
  }
224
204
 
205
+ export class TypedGrid extends Grid {
206
+ /**
207
+ * @param {number} width The grid width
208
+ * @param {number} height The grid height
209
+ */
210
+ constructor(width, height, TypedArray = Uint8Array) {
211
+ super(width, height, null)
212
+ this._c = new TypedArray(this._w * this._h)
213
+ }
214
+
215
+ /**
216
+ * @param {number} x
217
+ * @param {number} y
218
+ * @returns {boolean}
219
+ */
220
+ has(x, y) {
221
+ return this.get(x, y) !== 0
222
+ }
223
+
224
+ /**
225
+ * @returns {TypedGrid}
226
+ */
227
+ clone() {
228
+ const copy = new TypedGrid(this._w, this._h, this._c.constructor)
229
+ this.forEach((x, y, value) => {
230
+ copy.set(x, y, value)
231
+ })
232
+ return copy
233
+ }
234
+ }
235
+
225
236
  /**
226
237
  * Constrains a number between `min` and `max`.
227
238
  *
@@ -235,5 +246,3 @@ function _clamp(value, min, max) {
235
246
  if (value > max) return max
236
247
  return value
237
248
  }
238
-
239
- function _fill(x, y) {}
package/src/index.js CHANGED
@@ -4,6 +4,6 @@ export { default as wave } from "./math/wave.js"
4
4
  export { default as resolve } from "./collision/resolve.js"
5
5
  export { default as intersection } from "./collision/intersection.js"
6
6
  export { default as Camera } from "./camera/index.js"
7
- export { default as Grid } from "./grid/index.js"
7
+ export * from "./grid/index.js"
8
8
  export * from "./vector/index.js"
9
9
  export * from "./actor/index.js"