littlejsengine 1.1.2 → 1.1.3

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 (94) hide show
  1. package/README.md +55 -0
  2. package/build.bat +2 -1
  3. package/engine/engine.all.js +1320 -930
  4. package/engine/engine.all.min.js +1 -1
  5. package/engine/engine.all.release.js +965 -601
  6. package/engine/engine.js +71 -60
  7. package/engine/engineAudio.js +80 -22
  8. package/engine/engineBuild.bat +2 -2
  9. package/engine/engineDebug.js +65 -36
  10. package/engine/engineDraw.js +71 -56
  11. package/engine/engineInput.js +178 -28
  12. package/engine/engineMedals.js +66 -58
  13. package/engine/engineObject.js +86 -71
  14. package/engine/engineParticles.js +101 -63
  15. package/engine/engineRelease.js +4 -1
  16. package/engine/engineSettings.js +62 -53
  17. package/engine/engineTileLayer.js +99 -83
  18. package/engine/engineUtilities.js +95 -59
  19. package/engine/engineWebGL.js +53 -48
  20. package/examples/breakout/game.js +1 -1
  21. package/examples/breakout/gameObjects.js +2 -2
  22. package/examples/breakout/index.html +7 -5
  23. package/examples/platformer/game.js +7 -4
  24. package/examples/platformer/gameEffects.js +8 -11
  25. package/examples/platformer/gameLevel.js +15 -8
  26. package/examples/platformer/gameObjects.js +2 -2
  27. package/examples/platformer/gamePlayer.js +6 -6
  28. package/examples/platformer/index.html +10 -8
  29. package/examples/puzzle/game.js +3 -3
  30. package/examples/puzzle/index.html +6 -4
  31. package/examples/stress/index.html +7 -5
  32. package/game.js +10 -10
  33. package/index.html +17 -15
  34. package/package.json +4 -7
  35. package/tiles.png +0 -0
  36. package/LittleJS.zip +0 -0
  37. package/docs/Audio.html +0 -2264
  38. package/docs/Color.html +0 -2506
  39. package/docs/Debug.html +0 -2929
  40. package/docs/Draw.html +0 -3854
  41. package/docs/EngineObject.html +0 -2506
  42. package/docs/Input.html +0 -2478
  43. package/docs/Medal.html +0 -992
  44. package/docs/Medals.html +0 -624
  45. package/docs/Music.html +0 -569
  46. package/docs/Newgrounds.html +0 -1384
  47. package/docs/Particle.html +0 -567
  48. package/docs/ParticleEmitter.html +0 -1537
  49. package/docs/Random.html +0 -1770
  50. package/docs/Settings.html +0 -2885
  51. package/docs/Sound.html +0 -998
  52. package/docs/TileLayer.html +0 -3211
  53. package/docs/TileLayerData.html +0 -569
  54. package/docs/Timer.html +0 -1168
  55. package/docs/Utilities.html +0 -3266
  56. package/docs/Vector2.html +0 -3956
  57. package/docs/WebGL.html +0 -1842
  58. package/docs/engine.js.html +0 -428
  59. package/docs/engineAudio.js.html +0 -567
  60. package/docs/engineDebug.js.html +0 -721
  61. package/docs/engineDraw.js.html +0 -409
  62. package/docs/engineInput.js.html +0 -397
  63. package/docs/engineMedals.js.html +0 -445
  64. package/docs/engineObject.js.html +0 -492
  65. package/docs/engineParticles.js.html +0 -399
  66. package/docs/engineSettings.js.html +0 -358
  67. package/docs/engineTileLayer.js.html +0 -482
  68. package/docs/engineUtilities.js.html +0 -600
  69. package/docs/engineWebGL.js.html +0 -507
  70. package/docs/fonts/MavenPro-Regular.ttf +0 -0
  71. package/docs/fonts/Montserrat-Regular.ttf +0 -0
  72. package/docs/fonts/Muli-Black.ttf +0 -0
  73. package/docs/fonts/OFL-hind.txt +0 -93
  74. package/docs/fonts/OFL-montserrat.txt +0 -93
  75. package/docs/global.html +0 -1635
  76. package/docs/index.html +0 -243
  77. package/docs/scripts/fix-code-block.js +0 -53
  78. package/docs/scripts/fix-navbar.js +0 -25
  79. package/docs/scripts/linenumber.js +0 -25
  80. package/docs/scripts/misc.js +0 -217
  81. package/docs/scripts/resize.js +0 -85
  82. package/docs/scripts/search.js +0 -83
  83. package/docs/scripts/third-party/Apache-License-2.0.txt +0 -202
  84. package/docs/scripts/third-party/fuse.js +0 -9
  85. package/docs/scripts/third-party/lang-css.js +0 -2
  86. package/docs/scripts/third-party/prettify.js +0 -28
  87. package/docs/static/favicon.png +0 -0
  88. package/docs/styles/clean-jsdoc-theme-base.css +0 -393
  89. package/docs/styles/clean-jsdoc-theme-dark.css +0 -324
  90. package/docs/styles/clean-jsdoc-theme-light.css +0 -319
  91. package/docs/styles/reset.css +0 -346
  92. package/docs/styles/third-party/ionicons.min.css +0 -11
  93. package/docs/styles/third-party/prettify-jsdoc.css +0 -111
  94. package/docs/styles/third-party/prettify-tomorrow.css +0 -5
@@ -1,25 +1,29 @@
1
1
  /**
2
- * LittleJS Tile Layer System
3
- * <br> - Caches arrays of tiles to offscreen canvas for fast rendering
4
- * <br> - Unlimted numbers of layers, allocates canvases as needed
5
- * <br> - Interfaces with EngineObject for collision
6
- * <br> - Collision layer is separate from visible layers
7
- * <br> - Tile layers can be drawn to using their context with canvas2d
8
- * <br> - It is recommended to have a visible layer that matches the collision
9
- * @namespace TileLayer
2
+ * LittleJS Tile Layer System
3
+ * <br> - Caches arrays of tiles to off screen canvas for fast rendering
4
+ * <br> - Unlimted numbers of layers, allocates canvases as needed
5
+ * <br> - Interfaces with EngineObject for collision
6
+ * <br> - Collision layer is separate from visible layers
7
+ * <br> - It is recommended to have a visible layer that matches the collision
8
+ * <br> - Tile layers can be drawn to using their context with canvas2d
9
+ * <br> - Drawn directly to the main canvas without using WebGL
10
+ * @namespace TileCollision
10
11
  */
11
12
 
12
13
  'use strict';
13
14
 
14
- ///////////////////////////////////////////////////////////////////////////////
15
- // Tile Collision
15
+ /** The tile collision layer array, use setTileCollisionData and getTileCollisionData to access
16
+ * @memberof TileCollision */
17
+ let tileCollision = [];
16
18
 
17
- // Internal variables not exposed to documentation
18
- let tileCollision = [], tileCollisionSize = vec2();
19
+ /** Size of the tile collision layer
20
+ * @type {Vector2}
21
+ * @memberof TileCollision */
22
+ let tileCollisionSize = vec2();
19
23
 
20
24
  /** Clear and initialize tile collision
21
25
  * @param {Vector2} size
22
- * @memberof TileLayer */
26
+ * @memberof TileCollision */
23
27
  function initTileCollision(size)
24
28
  {
25
29
  tileCollisionSize = size;
@@ -31,14 +35,14 @@ function initTileCollision(size)
31
35
  /** Set tile collision data
32
36
  * @param {Vector2} pos
33
37
  * @param {Number} [data=0]
34
- * @memberof TileLayer */
38
+ * @memberof TileCollision */
35
39
  const setTileCollisionData = (pos, data=0)=>
36
40
  pos.arrayCheck(tileCollisionSize) && (tileCollision[(pos.y|0)*tileCollisionSize.x+pos.x|0] = data);
37
41
 
38
42
  /** Get tile collision data
39
43
  * @param {Vector2} pos
40
44
  * @return {Number}
41
- * @memberof TileLayer */
45
+ * @memberof TileCollision */
42
46
  const getTileCollisionData = (pos)=>
43
47
  pos.arrayCheck(tileCollisionSize) ? tileCollision[(pos.y|0)*tileCollisionSize.x+pos.x|0] : 0;
44
48
 
@@ -47,13 +51,13 @@ const getTileCollisionData = (pos)=>
47
51
  * @param {Vector2} [size=new Vector2(1,1)]
48
52
  * @param {EngineObject} [object]
49
53
  * @return {Boolean}
50
- * @memberof TileLayer */
54
+ * @memberof TileCollision */
51
55
  function tileCollisionTest(pos, size=vec2(), object)
52
56
  {
53
- const minX = max(Math.floor(pos.x - size.x/2), 0);
54
- const minY = max(Math.floor(pos.y - size.y/2), 0);
55
- const maxX = min(pos.x + size.x/2, tileCollisionSize.x-1);
56
- const maxY = min(pos.y + size.y/2, tileCollisionSize.y-1);
57
+ const minX = max(pos.x - size.x/2|0, 0);
58
+ const minY = max(pos.y - size.y/2|0, 0);
59
+ const maxX = min(pos.x + size.x/2, tileCollisionSize.x);
60
+ const maxY = min(pos.y + size.y/2, tileCollisionSize.y);
57
61
  for (let y = minY; y < maxY; ++y)
58
62
  for (let x = minX; x < maxX; ++x)
59
63
  {
@@ -68,7 +72,7 @@ function tileCollisionTest(pos, size=vec2(), object)
68
72
  * @param {Vector2} posEnd
69
73
  * @param {EngineObject} [object]
70
74
  * @return {Vector2}
71
- * @memberof TileLayer */
75
+ * @memberof TileCollision */
72
76
  function tileCollisionRaycast(posStart, posEnd, object)
73
77
  {
74
78
  // test if a ray collides with tiles from start to end
@@ -102,23 +106,32 @@ function tileCollisionRaycast(posStart, posEnd, object)
102
106
  ///////////////////////////////////////////////////////////////////////////////
103
107
  // Tile Layer Rendering System
104
108
 
105
- // Reuse canvas autmatically when destroyed
106
- const tileLayerCanvasCache = [];
107
-
108
- /** Tile layer data object stores info about how to render a tile */
109
+ /**
110
+ * Tile layer data object stores info about how to render a tile
111
+ * @example
112
+ * // create tile layer data with tile index 0 and random orientation and color
113
+ * const tileIndex = 0;
114
+ * const direction = randInt(4)
115
+ * const mirror = randInt(2);
116
+ * const color = randColor();
117
+ * const data = new TileLayerData(tileIndex, direction, mirror, color);
118
+ */
109
119
  class TileLayerData
110
120
  {
111
- /** Create a tile layer data object
112
- * @param {Number} [tile] - The tile to use, untextured if undefined
113
- * @param {Number} [direction=0] - Integer direction of tile, in 90 degree increments
114
- * @param {Boolean} [mirror=0] - If the tile should be mirrored along the x axis
115
- * @param {Color} [color=new Color(1,1,1)] - Color of the tile
116
- */
121
+ /** Create a tile layer data object, one for each tile in a TileLayer
122
+ * @param {Number} [tile] - The tile to use, untextured if undefined
123
+ * @param {Number} [direction=0] - Integer direction of tile, in 90 degree increments
124
+ * @param {Boolean} [mirror=0] - If the tile should be mirrored along the x axis
125
+ * @param {Color} [color=new Color(1,1,1)] - Color of the tile */
117
126
  constructor(tile, direction=0, mirror=0, color=new Color)
118
127
  {
128
+ /** @property {Number} - The tile to use, untextured if undefined */
119
129
  this.tile = tile;
130
+ /** @property {Number} - Integer direction of tile, in 90 degree increments */
120
131
  this.direction = direction;
132
+ /** @property {Boolean} - If the tile should be mirrored along the x axis */
121
133
  this.mirror = mirror;
134
+ /** @property {Color} - Color of the tile */
122
135
  this.color = color;
123
136
  }
124
137
 
@@ -126,44 +139,49 @@ class TileLayerData
126
139
  clear() { this.tile = this.direction = this.mirror = 0; color = new Color; }
127
140
  }
128
141
 
129
- /** Tile layer object - cached rendering system for tile layers */
142
+ /**
143
+ * Tile layer object - cached rendering system for tile layers
144
+ * <br> - Each Tile layer is rendered to an off screen canvas
145
+ * <br> - To allow dynamic modifications, layers are rendered using canvas 2d
146
+ * <br> - Some devices like mobile phones are limited to 4k texture resolution
147
+ * <br> - So with 16x16 tiles this limits layers to 256x256 on mobile devices
148
+ * @extends EngineObject
149
+ * @example
150
+ * // create tile collision and visible tile layer
151
+ * initTileCollision(vec2(200,100));
152
+ * const tileLayer = new TileLayer();
153
+ */
130
154
  class TileLayer extends EngineObject
131
155
  {
132
- /** Create a tile layer data object
156
+ /** Create a tile layer object
133
157
  * @param {Vector2} [position=new Vector2(0,0)] - World space position
134
- * @param {Vector2} [size=defaultObjectSize] - World space size
135
- * @param {Vector2} [scale=new Vector2(1,1)] - How much to scale this in world space
136
- * @param {Number} [renderOrder=0] - Objects sorted by renderOrder before being rendered
158
+ * @param {Vector2} [size=objectDefaultSize] - World space size
159
+ * @param {Vector2} [tileSize=tileSizeDefault] - Size of tiles in source pixels
160
+ * @param {Vector2} [scale=new Vector2(1,1)] - How much to scale this layer when rendered
161
+ * @param {Number} [renderOrder=0] - Objects sorted by renderOrder before being rendered
137
162
  */
138
- constructor(pos, size, scale=vec2(1), renderOrder=0)
163
+ constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1), renderOrder=0)
139
164
  {
140
- super(pos, size);
165
+ super(pos, size, -1, tileSize, 0, undefined, renderOrder);
141
166
 
142
- // create new canvas if necessary
143
- this.canvas = tileLayerCanvasCache.length ? tileLayerCanvasCache.pop() : document.createElement('canvas');
167
+ /** @property {HTMLCanvasElement} - The canvas used by this tile layer */
168
+ this.canvas = document.createElement('canvas');
169
+ /** @property {CanvasRenderingContext2D} - The 2D canvas context used by this tile layer */
144
170
  this.context = this.canvas.getContext('2d');
171
+ /** @property {Vector2} - How much to scale this layer when rendered */
145
172
  this.scale = scale;
146
- this.tileSize = defaultTileSize.copy();
147
- this.renderOrder = renderOrder;
148
- this.flushGLBeforeRender = 1;
173
+ /** @property {Boolean} [isOverlay=0] - If true this layer will render to overlay canvas and appear above all objects */
174
+ this.isOverlay;
149
175
 
150
176
  // init tile data
151
177
  this.data = [];
152
178
  for (let j = this.size.area(); j--;)
153
179
  this.data.push(new TileLayerData());
154
180
  }
155
-
156
- /** Destroy this tile layer */
157
- destroy()
158
- {
159
- // add canvas back to the cache
160
- tileLayerCanvasCache.push(this.canvas);
161
- super.destroy();
162
- }
163
181
 
164
182
  /** Set data at a given position in the array
165
- * @param {Vector2} position - Local position in array
166
- * @param {TileLayerData} data - Data to set
183
+ * @param {Vector2} position - Local position in array
184
+ * @param {TileLayerData} data - Data to set
167
185
  * @param {Boolean} [redraw=0] - Force the tile to redraw if true */
168
186
  setData(layerPos, data, redraw)
169
187
  {
@@ -188,50 +206,48 @@ class TileLayer extends EngineObject
188
206
  {
189
207
  ASSERT(mainContext != this.context); // must call redrawEnd() after drawing tiles
190
208
 
191
- // flush and copy gl canvas because tile canvas does not use gl
192
- this.flushGLBeforeRender && glEnable && glCopyToContext(mainContext);
209
+ // flush and copy gl canvas because tile canvas does not use webgl
210
+ glEnable && !glOverlay && !this.isOverlay && glCopyToContext(mainContext);
193
211
 
194
- // draw the entire cached level onto the main canvas
212
+ // draw the entire cached level onto the canvas
195
213
  const pos = worldToScreen(this.pos.add(vec2(0,this.size.y*this.scale.y)));
196
- mainContext.drawImage
214
+ (this.isOverlay ? overlayContext : mainContext).drawImage
197
215
  (
198
216
  this.canvas, pos.x, pos.y,
199
217
  cameraScale*this.size.x*this.scale.x, cameraScale*this.size.y*this.scale.y
200
218
  );
201
219
  }
202
220
 
203
- /** Draw all the tile data to an offscreen canvas using webgl if possible */
221
+ /** Draw all the tile data to an offscreen canvas
222
+ * - This may be slow in some browsers
223
+ */
204
224
  redraw()
205
225
  {
206
- this.redrawStart();
226
+ this.redrawStart(1);
207
227
  this.drawAllTileData();
208
228
  this.redrawEnd();
209
229
  }
210
230
 
211
231
  /** Call to start the redraw process
212
- * @param {Boolean} [clear=1] - Should it clear the canvas before drawing */
213
- redrawStart(clear = 1)
232
+ * @param {Boolean} [clear=0] - Should it clear the canvas before drawing */
233
+ redrawStart(clear = 0)
214
234
  {
215
- // clear and set size
216
- const width = this.size.x * this.tileSize.x;
217
- const height = this.size.y * this.tileSize.y;
218
235
  if (clear)
219
236
  {
220
- this.canvas.width = width;
221
- this.canvas.height = height;
237
+ // clear and set size
238
+ this.canvas.width = this.size.x * this.tileSize.x;
239
+ this.canvas.height = this.size.y * this.tileSize.y;
222
240
  }
223
241
 
224
242
  // save current render settings
225
- this.savedRenderSettings = [mainCanvasSize, mainCanvas, mainContext, cameraScale, cameraPos];
243
+ this.savedRenderSettings = [mainCanvas, mainContext, cameraPos, cameraScale];
226
244
 
227
- // set camera transform for renering
228
- cameraScale = this.tileSize.x;
229
- cameraPos = this.size.scale(.5);
245
+ // use normal rendering system to render the tiles
230
246
  mainCanvas = this.canvas;
231
247
  mainContext = this.context;
232
- mainContext.imageSmoothingEnabled = !pixelated; // disable smoothing for pixel art
233
- mainCanvasSize = vec2(width, height);
234
- glPreRender(width, height);
248
+ cameraPos = this.size.scale(.5);
249
+ cameraScale = this.tileSize.x;
250
+ enginePreRender();
235
251
  }
236
252
 
237
253
  /** Call to end the redraw process */
@@ -242,7 +258,7 @@ class TileLayer extends EngineObject
242
258
  //debugSaveCanvas(this.canvas);
243
259
 
244
260
  // set stuff back to normal
245
- [mainCanvasSize, mainCanvas, mainContext, cameraScale, cameraPos] = this.savedRenderSettings;
261
+ [mainCanvas, mainContext, cameraPos, cameraScale] = this.savedRenderSettings;
246
262
  }
247
263
 
248
264
  /** Draw the tile at a given position
@@ -270,13 +286,13 @@ class TileLayer extends EngineObject
270
286
  this.drawTileData(vec2(x,y));
271
287
  }
272
288
 
273
- /** Draw directly to the 2d canvas in world space (bipass webgl)
289
+ /** Draw directly to the 2D canvas in world space (bipass webgl)
274
290
  * @param {Vector2} pos
275
291
  * @param {Vector2} size
276
- * @param {Number} angle
277
- * @param {Boolean} mirror
292
+ * @param {Number} [angle=0]
293
+ * @param {Boolean} [mirror=0]
278
294
  * @param {Function} drawFunction */
279
- drawCanvas2D(pos, size, angle, mirror, drawFunction)
295
+ drawCanvas2D(pos, size, angle=0, mirror, drawFunction)
280
296
  {
281
297
  const context = this.context;
282
298
  context.save();
@@ -284,7 +300,7 @@ class TileLayer extends EngineObject
284
300
  size = size.multiply(this.tileSize);
285
301
  context.translate(pos.x, this.canvas.height - pos.y);
286
302
  context.rotate(angle);
287
- context.scale(mirror?-size.x:size.x, size.y);
303
+ context.scale(mirror ? -size.x : size.x, size.y);
288
304
  drawFunction(context);
289
305
  context.restore();
290
306
  }
@@ -293,11 +309,11 @@ class TileLayer extends EngineObject
293
309
  * @param {Vector2} pos
294
310
  * @param {Vector2} [size=new Vector2(1,1)]
295
311
  * @param {Number} [tileIndex=-1]
296
- * @param {Vector2} [tileSize=defaultTileSize]
312
+ * @param {Vector2} [tileSize=tileSizeDefault]
297
313
  * @param {Color} [color=new Color(1,1,1)]
298
314
  * @param {Number} [angle=0]
299
315
  * @param {Boolean} [mirror=0] */
300
- drawTile(pos, size=vec2(1), tileIndex=-1, tileSize=defaultTileSize, color=new Color, angle=0, mirror)
316
+ drawTile(pos, size=vec2(1), tileIndex=-1, tileSize=tileSizeDefault, color=new Color, angle, mirror)
301
317
  {
302
318
  this.drawCanvas2D(pos, size, angle, mirror, (context)=>
303
319
  {
@@ -310,7 +326,7 @@ class TileLayer extends EngineObject
310
326
  else
311
327
  {
312
328
  const cols = tileImage.width/tileSize.x;
313
- context.globalAlpha = color.a; // full color not supported in this mode
329
+ context.globalAlpha = color.a; // only alpha, no color, is supported in this mode
314
330
  context.drawImage(tileImage,
315
331
  (tileIndex%cols)*tileSize.x, (tileIndex/cols|0)*tileSize.x,
316
332
  tileSize.x, tileSize.y, -.5, -.5, 1, 1);
@@ -323,5 +339,5 @@ class TileLayer extends EngineObject
323
339
  * @param {Vector2} [size=new Vector2(1,1)]
324
340
  * @param {Color} [color=new Color(1,1,1)]
325
341
  * @param {Number} [angle=0] */
326
- drawRect(pos, size, color, angle) { this.drawTile(pos, size, -1, 0, color, angle, 0); }
342
+ drawRect(pos, size, color, angle) { this.drawTile(pos, size, -1, 0, color, angle); }
327
343
  }
@@ -1,10 +1,10 @@
1
1
  /**
2
- * LittleJS Utility Classes and Functions
3
- * <br> - General purpose math library
4
- * <br> - Vector2 - fast, simple, easy 2D vector class
5
- * <br> - Color - holds a rgba color with some math functions
6
- * <br> - Timer - tracks time automatically
7
- * @namespace Utilities
2
+ * LittleJS Utility Classes and Functions
3
+ * <br> - General purpose math library
4
+ * <br> - Vector2 - fast, simple, easy 2D vector class
5
+ * <br> - Color - holds a rgba color with some math functions
6
+ * <br> - Timer - tracks time automatically
7
+ * @namespace Utilities
8
8
  */
9
9
 
10
10
  'use strict';
@@ -14,23 +14,12 @@
14
14
  * @memberof Utilities */
15
15
  const PI = Math.PI;
16
16
 
17
- /** True if running a Chromium based browser
18
- * @const
19
- * @memberof Utilities */
20
- const isChrome = window['chrome'];
21
-
22
17
  /** Returns absoulte value of value passed in
23
18
  * @param {Number} value
24
19
  * @return {Number}
25
20
  * @memberof Utilities */
26
21
  const abs = (a)=> a < 0 ? -a : a;
27
22
 
28
- /** Returns the sign of value passed in
29
- * @param {Number} value
30
- * @return {Number}
31
- * @memberof Utilities */
32
- const sign = (a)=> a < 0 ? -1 : 1;
33
-
34
23
  /** Returns lowest of two values passed in
35
24
  * @param {Number} valueA
36
25
  * @param {Number} valueB
@@ -45,54 +34,54 @@ const min = (a, b)=> a < b ? a : b;
45
34
  * @memberof Utilities */
46
35
  const max = (a, b)=> a > b ? a : b;
47
36
 
37
+ /** Returns the sign of value passed in (also returns 1 if 0)
38
+ * @param {Number} value
39
+ * @return {Number}
40
+ * @memberof Utilities */
41
+ const sign = (a)=> a < 0 ? -1 : 1;
42
+
48
43
  /** Returns first parm modulo the second param, but adjusted so negative numbers work as expected
49
44
  * @param {Number} dividend
50
- * @param {Number} divisor
45
+ * @param {Number} [divisor=1]
51
46
  * @return {Number}
52
47
  * @memberof Utilities */
53
- const mod = (a, b)=> ((a % b) + b) % b;
48
+ const mod = (a, b=1)=> ((a % b) + b) % b;
54
49
 
55
50
  /** Clamps the value beween max and min
56
51
  * @param {Number} value
57
- * @param {Number} [max=1]
58
52
  * @param {Number} [min=0]
53
+ * @param {Number} [max=1]
59
54
  * @return {Number}
60
55
  * @memberof Utilities */
61
- const clamp = (v, max=1, min=0)=> (ASSERT(max > min), v < min ? min : v > max ? max : v);
56
+ const clamp = (v, min=0, max=1)=> v < min ? min : v > max ? max : v;
62
57
 
63
58
  /** Returns what percentage the value is between max and min
64
59
  * @param {Number} value
65
- * @param {Number} [max=1]
66
60
  * @param {Number} [min=0]
61
+ * @param {Number} [max=1]
67
62
  * @return {Number}
68
63
  * @memberof Utilities */
69
- const percent = (v, max=1, min=0)=> max-min ? clamp((v-min) / (max-min)) : 0;
64
+ const percent = (v, min=0, max=1)=> max-min ? clamp((v-min) / (max-min)) : 0;
70
65
 
71
66
  /** Linearly interpolates the percent value between max and min
72
67
  * @param {Number} percent
73
- * @param {Number} [max=1]
74
68
  * @param {Number} [min=0]
69
+ * @param {Number} [max=1]
75
70
  * @return {Number}
76
71
  * @memberof Utilities */
77
- const lerp = (p, max=1, min=0)=> min + clamp(p) * (max-min);
72
+ const lerp = (p, min=0, max=1)=> min + clamp(p) * (max-min);
78
73
 
79
- /** Formats seconds to 00:00 style for display purposes
80
- * @param {Number} t - time in seconds
81
- * @return {String}
82
- * @memberof Utilities */
83
- const formatTime = (t)=> (t/60|0)+':'+(t%60<10?'0':'')+(t%60|0);
84
-
85
- /** Returns the nearest power of two not less then the value
74
+ /** Applies smoothstep function to the percentage value
86
75
  * @param {Number} value
87
76
  * @return {Number}
88
77
  * @memberof Utilities */
89
- const nearestPowerOfTwo = (v)=> 2**Math.ceil(Math.log2(v));
78
+ const smoothStep = (p)=> p * p * (3 - 2 * p);
90
79
 
91
- /** Applies smoothstep function to the percentage value
80
+ /** Returns the nearest power of two not less then the value
92
81
  * @param {Number} value
93
82
  * @return {Number}
94
83
  * @memberof Utilities */
95
- const smoothStep = (p)=> p * p * (3 - 2 * p);
84
+ const nearestPowerOfTwo = (v)=> 2**Math.ceil(Math.log2(v));
96
85
 
97
86
  /** Returns true if two axis aligned bounding boxes are overlapping
98
87
  * @param {Vector2} pointA - Center of box A
@@ -111,6 +100,12 @@ const isOverlapping = (pA, sA, pB, sB)=> abs(pA.x - pB.x)*2 < sA.x + sB.x & abs(
111
100
  * @memberof Utilities */
112
101
  const wave = (frequency=1, amplitude=1, t=time)=> amplitude/2 * (1 - Math.cos(t*frequency*2*PI));
113
102
 
103
+ /** Formats seconds to mm:ss style for display purposes
104
+ * @param {Number} t - time in seconds
105
+ * @return {String}
106
+ * @memberof Utilities */
107
+ const formatTime = (t)=> (t/60|0)+':'+(t%60<10?'0':'')+(t%60|0);
108
+
114
109
  ///////////////////////////////////////////////////////////////////////////////
115
110
 
116
111
  /** Random global functions
@@ -133,7 +128,7 @@ const randInt = (a=1, b=0)=> rand(a,b)|0;
133
128
  /** Randomly returns either -1 or 1
134
129
  * @return {Number}
135
130
  * @memberof Random */
136
- const randSign = ()=> (rand(2)|0)*2-1;
131
+ const randSign = ()=> (rand(2)|0) * 2 - 1;
137
132
 
138
133
  /** Returns a random Vector2 within a circular shape
139
134
  * @param {Number} [radius=1]
@@ -169,25 +164,46 @@ let randSeed = 1;
169
164
  const randSeeded = (a=1, b=0)=>
170
165
  {
171
166
  randSeed ^= randSeed << 13; randSeed ^= randSeed >>> 17; randSeed ^= randSeed << 5; // xorshift
172
- return b + (a-b)*abs(randSeed % 1e9)/1e9;
167
+ return b + (a-b) * abs(randSeed % 1e9) / 1e9;
173
168
  }
174
169
 
175
170
  ///////////////////////////////////////////////////////////////////////////////
176
171
 
177
- /** Create a 2d vector, can take another Vector2 to copy, 2 scalars, or 1 scalar
178
- * @param {Number} [x=0]
179
- * @param {Number} [y=0]
180
- * @return {Vector2}
181
- * @memberof Utilities */
172
+ /**
173
+ * Create a 2d vector, can take another Vector2 to copy, 2 scalars, or 1 scalar
174
+ * @param {Number} [x=0]
175
+ * @param {Number} [y=0]
176
+ * @return {Vector2}
177
+ * @example
178
+ * let a = vec2(0, 1); // vector with coordinates (0, 1)
179
+ * let b = vec2(a); // copy a into b
180
+ * a = vec2(5); // set a to (5, 5)
181
+ * b = vec2(); // set b to (0, 0)
182
+ * @memberof Utilities
183
+ */
182
184
  const vec2 = (x=0, y)=> x.x == undefined ? new Vector2(x, y == undefined? x : y) : new Vector2(x.x, x.y);
183
185
 
184
- /** 2D Vector object with vector math library */
186
+ /**
187
+ * 2D Vector object with vector math library
188
+ * <br> - Functions do not change this so they can be chained together
189
+ * @example
190
+ * let a = new Vector2(2, 3); // vector with coordinates (2, 3)
191
+ * let b = new Vector2; // vector with coordinates (0, 0)
192
+ * let c = vec2(4, 2); // use the vec2 function to make a Vector2
193
+ * let d = a.add(b).scale(5); // operators can be chained
194
+ */
185
195
  class Vector2
186
196
  {
187
197
  /** Create a 2D vector with the x and y passed in, can also be created with vec2()
188
- * @param {Number} [x=0] - x axis position
189
- * @param {Number} [y=0] - y axis position */
190
- constructor(x=0, y=0) { this.x = x; this.y = y; }
198
+ * @param {Number} [x=0] - X axis location
199
+ * @param {Number} [y=0] - Y axis location */
200
+ constructor(x=0, y=0)
201
+ {
202
+ /** @property {Number} - X axis location */
203
+ this.x = x;
204
+ /** @property {Number} - Y axis location */
205
+ this.y = y;
206
+ }
191
207
 
192
208
  /** Returns a new vector that is a copy of this
193
209
  * @return {Vector2} */
@@ -278,10 +294,6 @@ class Vector2
278
294
  * @return {Vector2} */
279
295
  invert() { return new Vector2(this.y, -this.x); }
280
296
 
281
- /** Returns a copy of this vector with the axies flipped
282
- * @return {Vector2} */
283
- flip() { return new Vector2(this.y, this.x); }
284
-
285
297
  /** Returns a copy of this vector with each axis floored
286
298
  * @return {Vector2} */
287
299
  floor() { return new Vector2(Math.floor(this.x), Math.floor(this.y)); }
@@ -304,15 +316,31 @@ class Vector2
304
316
 
305
317
  ///////////////////////////////////////////////////////////////////////////////
306
318
 
307
- /** Color object (red, green, blue, alpha) with some helpful functions */
319
+ /**
320
+ * Color object (red, green, blue, alpha) with some helpful functions
321
+ * @example
322
+ * let a = new Color; // white
323
+ * let b = new Color(1, 0, 0); // red
324
+ * let c = new Color(0, 0, 0, 0); // transparent black
325
+ */
308
326
  class Color
309
327
  {
310
328
  /** Create a color with the components passed in, white by default
311
- * @param {Number} [r=1] - red
312
- * @param {Number} [g=1] - green
313
- * @param {Number} [b=1] - blue
314
- * @param {Number} [a=1] - alpha */
315
- constructor(r=1, g=1, b=1, a=1) { this.r=r; this.g=g; this.b=b; this.a=a; }
329
+ * @param {Number} [red=1]
330
+ * @param {Number} [green=1]
331
+ * @param {Number} [blue=1]
332
+ * @param {Number} [alpha=1] */
333
+ constructor(r=1, g=1, b=1, a=1)
334
+ {
335
+ /** @property {Number} - Red */
336
+ this.r = r;
337
+ /** @property {Number} - Green */
338
+ this.g = g;
339
+ /** @property {Number} - Blue */
340
+ this.b = b;
341
+ /** @property {Number} - Alpha */
342
+ this.a = a;
343
+ }
316
344
 
317
345
  /** Returns a new color that is a copy of this
318
346
  * @return {Color} */
@@ -409,7 +437,15 @@ class Color
409
437
 
410
438
  ///////////////////////////////////////////////////////////////////////////////
411
439
 
412
- /** Timer object tracks how long has passed since it was set */
440
+ /**
441
+ * Timer object tracks how long has passed since it was set
442
+ * @example
443
+ * let a = new Timer; // creates a timer that is not set
444
+ * a.set(3); // sets the timer to 3 seconds
445
+ *
446
+ * let b = new Timer(1); // creates a timer with 1 second left
447
+ * b.unset(); // unsets the timer
448
+ */
413
449
  class Timer
414
450
  {
415
451
  /** Create a timer object set time passed in
@@ -435,11 +471,11 @@ class Timer
435
471
  * @return {Boolean} */
436
472
  elapsed() { return time > this.time; }
437
473
 
438
- /** Get how long since elapsed, returns 0 if not set
474
+ /** Get how long since elapsed, returns 0 if not set (returns negative if currently active)
439
475
  * @return {Number} */
440
476
  get() { return this.isSet()? time - this.time : 0; }
441
477
 
442
478
  /** Get percentage elapsed based on time it was set to, returns 0 if not set
443
479
  * @return {Number} */
444
- getPercent() { return this.isSet()? percent(this.time - time, 0, this.setTime) : 0; }
480
+ getPercent() { return this.isSet()? percent(this.time - time, this.setTime, 0) : 0; }
445
481
  }