littlejsengine 1.11.9 → 1.11.13

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 (44) hide show
  1. package/README.md +3 -3
  2. package/dist/littlejs.d.ts +485 -492
  3. package/dist/littlejs.esm.js +548 -529
  4. package/dist/littlejs.esm.min.js +1 -1
  5. package/dist/littlejs.js +546 -525
  6. package/dist/littlejs.min.js +1 -1
  7. package/dist/littlejs.release.js +502 -484
  8. package/examples/htmlMenu/game.js +11 -1
  9. package/examples/htmlMenu/index.html +1 -10
  10. package/examples/module/game.js +2 -2
  11. package/examples/shorts/base.html +1 -1
  12. package/examples/starter/build/index.html +2 -0
  13. package/examples/starter/build/index.js +1 -0
  14. package/examples/starter/build/tiles.png +0 -0
  15. package/examples/starter/build.js +13 -3
  16. package/examples/starter/game.js +8 -1
  17. package/examples/starter/game.zip +0 -0
  18. package/examples/typescript/build/dist/littlejs.esm.js +4834 -0
  19. package/examples/typescript/build/examples/typescript/build.js +24 -0
  20. package/examples/typescript/build/examples/typescript/game.js +102 -0
  21. package/examples/typescript/build.bat +5 -0
  22. package/examples/typescript/build.js +33 -0
  23. package/examples/typescript/game.js +102 -0
  24. package/examples/typescript/game.ts +134 -0
  25. package/examples/typescript/index.html +10 -0
  26. package/examples/typescript/tiles.png +0 -0
  27. package/examples/typescript/tsconfig.json +8 -0
  28. package/package.json +1 -1
  29. package/plugins/newgrounds.js +44 -35
  30. package/plugins/postProcess.js +18 -4
  31. package/plugins/uiSystem.js +196 -30
  32. package/src/engine.js +21 -20
  33. package/src/engineAudio.js +59 -59
  34. package/src/engineDebug.js +44 -41
  35. package/src/engineDraw.js +58 -58
  36. package/src/engineExport.js +2 -4
  37. package/src/engineInput.js +40 -35
  38. package/src/engineMedals.js +21 -11
  39. package/src/engineObject.js +42 -35
  40. package/src/engineParticles.js +10 -10
  41. package/src/engineSettings.js +77 -82
  42. package/src/engineTileLayer.js +21 -21
  43. package/src/engineUtilities.js +150 -150
  44. package/src/engineWebGL.js +3 -3
@@ -51,112 +51,112 @@ function debugSaveDataURL(){}
51
51
 
52
52
 
53
53
  /** A shortcut to get Math.PI
54
- * @type {Number}
54
+ * @type {number}
55
55
  * @default Math.PI
56
56
  * @memberof Utilities */
57
57
  const PI = Math.PI;
58
58
 
59
59
  /** Returns absolute value of value passed in
60
- * @param {Number} value
61
- * @return {Number}
60
+ * @param {number} value
61
+ * @return {number}
62
62
  * @memberof Utilities */
63
63
  function abs(value) { return Math.abs(value); }
64
64
 
65
65
  /** Returns lowest of two values passed in
66
- * @param {Number} valueA
67
- * @param {Number} valueB
68
- * @return {Number}
66
+ * @param {number} valueA
67
+ * @param {number} valueB
68
+ * @return {number}
69
69
  * @memberof Utilities */
70
70
  function min(valueA, valueB) { return Math.min(valueA, valueB); }
71
71
 
72
72
  /** Returns highest of two values passed in
73
- * @param {Number} valueA
74
- * @param {Number} valueB
75
- * @return {Number}
73
+ * @param {number} valueA
74
+ * @param {number} valueB
75
+ * @return {number}
76
76
  * @memberof Utilities */
77
77
  function max(valueA, valueB) { return Math.max(valueA, valueB); }
78
78
 
79
79
  /** Returns the sign of value passed in
80
- * @param {Number} value
81
- * @return {Number}
80
+ * @param {number} value
81
+ * @return {number}
82
82
  * @memberof Utilities */
83
83
  function sign(value) { return Math.sign(value); }
84
84
 
85
85
  /** Returns first parm modulo the second param, but adjusted so negative numbers work as expected
86
- * @param {Number} dividend
87
- * @param {Number} [divisor]
88
- * @return {Number}
86
+ * @param {number} dividend
87
+ * @param {number} [divisor]
88
+ * @return {number}
89
89
  * @memberof Utilities */
90
90
  function mod(dividend, divisor=1) { return ((dividend % divisor) + divisor) % divisor; }
91
91
 
92
92
  /** Clamps the value between max and min
93
- * @param {Number} value
94
- * @param {Number} [min]
95
- * @param {Number} [max]
96
- * @return {Number}
93
+ * @param {number} value
94
+ * @param {number} [min]
95
+ * @param {number} [max]
96
+ * @return {number}
97
97
  * @memberof Utilities */
98
98
  function clamp(value, min=0, max=1) { return value < min ? min : value > max ? max : value; }
99
99
 
100
100
  /** Returns what percentage the value is between valueA and valueB
101
- * @param {Number} value
102
- * @param {Number} valueA
103
- * @param {Number} valueB
104
- * @return {Number}
101
+ * @param {number} value
102
+ * @param {number} valueA
103
+ * @param {number} valueB
104
+ * @return {number}
105
105
  * @memberof Utilities */
106
106
  function percent(value, valueA, valueB)
107
107
  { return (valueB-=valueA) ? clamp((value-valueA)/valueB) : 0; }
108
108
 
109
109
  /** Linearly interpolates between values passed in using percent
110
- * @param {Number} percent
111
- * @param {Number} valueA
112
- * @param {Number} valueB
113
- * @return {Number}
110
+ * @param {number} percent
111
+ * @param {number} valueA
112
+ * @param {number} valueB
113
+ * @return {number}
114
114
  * @memberof Utilities */
115
115
  function lerp(percent, valueA, valueB) { return valueA + clamp(percent) * (valueB-valueA); }
116
116
 
117
117
  /** Returns signed wrapped distance between the two values passed in
118
- * @param {Number} valueA
119
- * @param {Number} valueB
120
- * @param {Number} [wrapSize]
121
- * @returns {Number}
118
+ * @param {number} valueA
119
+ * @param {number} valueB
120
+ * @param {number} [wrapSize]
121
+ * @returns {number}
122
122
  * @memberof Utilities */
123
123
  function distanceWrap(valueA, valueB, wrapSize=1)
124
124
  { const d = (valueA - valueB) % wrapSize; return d*2 % wrapSize - d; }
125
125
 
126
126
  /** Linearly interpolates between values passed in with wrapping
127
- * @param {Number} percent
128
- * @param {Number} valueA
129
- * @param {Number} valueB
130
- * @param {Number} [wrapSize]
131
- * @returns {Number}
127
+ * @param {number} percent
128
+ * @param {number} valueA
129
+ * @param {number} valueB
130
+ * @param {number} [wrapSize]
131
+ * @returns {number}
132
132
  * @memberof Utilities */
133
133
  function lerpWrap(percent, valueA, valueB, wrapSize=1)
134
134
  { return valueB + clamp(percent) * distanceWrap(valueA, valueB, wrapSize); }
135
135
 
136
136
  /** Returns signed wrapped distance between the two angles passed in
137
- * @param {Number} angleA
138
- * @param {Number} angleB
139
- * @returns {Number}
137
+ * @param {number} angleA
138
+ * @param {number} angleB
139
+ * @returns {number}
140
140
  * @memberof Utilities */
141
141
  function distanceAngle(angleA, angleB) { return distanceWrap(angleA, angleB, 2*PI); }
142
142
 
143
143
  /** Linearly interpolates between the angles passed in with wrapping
144
- * @param {Number} percent
145
- * @param {Number} angleA
146
- * @param {Number} angleB
147
- * @returns {Number}
144
+ * @param {number} percent
145
+ * @param {number} angleA
146
+ * @param {number} angleB
147
+ * @returns {number}
148
148
  * @memberof Utilities */
149
149
  function lerpAngle(percent, angleA, angleB) { return lerpWrap(percent, angleA, angleB, 2*PI); }
150
150
 
151
151
  /** Applies smoothstep function to the percentage value
152
- * @param {Number} percent
153
- * @return {Number}
152
+ * @param {number} percent
153
+ * @return {number}
154
154
  * @memberof Utilities */
155
155
  function smoothStep(percent) { return percent * percent * (3 - 2 * percent); }
156
156
 
157
157
  /** Returns the nearest power of two not less then the value
158
- * @param {Number} value
159
- * @return {Number}
158
+ * @param {number} value
159
+ * @return {number}
160
160
  * @memberof Utilities */
161
161
  function nearestPowerOfTwo(value) { return 2**Math.ceil(Math.log2(value)); }
162
162
 
@@ -165,7 +165,7 @@ function nearestPowerOfTwo(value) { return 2**Math.ceil(Math.log2(value)); }
165
165
  * @param {Vector2} sizeA - Size of box A
166
166
  * @param {Vector2} posB - Center of box B
167
167
  * @param {Vector2} [sizeB=(0,0)] - Size of box B, a point if undefined
168
- * @return {Boolean} - True if overlapping
168
+ * @return {boolean} - True if overlapping
169
169
  * @memberof Utilities */
170
170
  function isOverlapping(posA, sizeA, posB, sizeB=vec2())
171
171
  {
@@ -178,7 +178,7 @@ function isOverlapping(posA, sizeA, posB, sizeB=vec2())
178
178
  * @param {Vector2} end - End of raycast
179
179
  * @param {Vector2} pos - Center of box
180
180
  * @param {Vector2} size - Size of box
181
- * @return {Boolean} - True if intersecting
181
+ * @return {boolean} - True if intersecting
182
182
  * @memberof Utilities */
183
183
  function isIntersecting(start, end, pos, size)
184
184
  {
@@ -215,17 +215,17 @@ function isIntersecting(start, end, pos, size)
215
215
  }
216
216
 
217
217
  /** Returns an oscillating wave between 0 and amplitude with frequency of 1 Hz by default
218
- * @param {Number} [frequency] - Frequency of the wave in Hz
219
- * @param {Number} [amplitude] - Amplitude (max height) of the wave
220
- * @param {Number} [t=time] - Value to use for time of the wave
221
- * @return {Number} - Value waving between 0 and amplitude
218
+ * @param {number} [frequency] - Frequency of the wave in Hz
219
+ * @param {number} [amplitude] - Amplitude (max height) of the wave
220
+ * @param {number} [t=time] - Value to use for time of the wave
221
+ * @return {number} - Value waving between 0 and amplitude
222
222
  * @memberof Utilities */
223
223
  function wave(frequency=1, amplitude=1, t=time)
224
224
  { return amplitude/2 * (1 - Math.cos(t*frequency*2*PI)); }
225
225
 
226
226
  /** Formats seconds to mm:ss style for display purposes
227
- * @param {Number} t - time in seconds
228
- * @return {String}
227
+ * @param {number} t - time in seconds
228
+ * @return {string}
229
229
  * @memberof Utilities */
230
230
  function formatTime(t) { return (t/60|0) + ':' + (t%60<10?'0':'') + (t%60|0); }
231
231
 
@@ -235,34 +235,34 @@ function formatTime(t) { return (t/60|0) + ':' + (t%60<10?'0':'') + (t%60|0); }
235
235
  * @namespace Random */
236
236
 
237
237
  /** Returns a random value between the two values passed in
238
- * @param {Number} [valueA]
239
- * @param {Number} [valueB]
240
- * @return {Number}
238
+ * @param {number} [valueA]
239
+ * @param {number} [valueB]
240
+ * @return {number}
241
241
  * @memberof Random */
242
242
  function rand(valueA=1, valueB=0) { return valueB + Math.random() * (valueA-valueB); }
243
243
 
244
244
  /** Returns a floored random value between the two values passed in
245
245
  * The upper bound is exclusive. (If 2 is passed in, result will be 0 or 1)
246
- * @param {Number} valueA
247
- * @param {Number} [valueB]
248
- * @return {Number}
246
+ * @param {number} valueA
247
+ * @param {number} [valueB]
248
+ * @return {number}
249
249
  * @memberof Random */
250
250
  function randInt(valueA, valueB=0) { return Math.floor(rand(valueA,valueB)); }
251
251
 
252
252
  /** Randomly returns either -1 or 1
253
- * @return {Number}
253
+ * @return {number}
254
254
  * @memberof Random */
255
255
  function randSign() { return randInt(2) * 2 - 1; }
256
256
 
257
257
  /** Returns a random Vector2 with the passed in length
258
- * @param {Number} [length]
258
+ * @param {number} [length]
259
259
  * @return {Vector2}
260
260
  * @memberof Random */
261
261
  function randVector(length=1) { return new Vector2().setAngle(rand(2*PI), length); }
262
262
 
263
263
  /** Returns a random Vector2 within a circular shape
264
- * @param {Number} [radius]
265
- * @param {Number} [minRadius]
264
+ * @param {number} [radius]
265
+ * @param {number} [minRadius]
266
266
  * @return {Vector2}
267
267
  * @memberof Random */
268
268
  function randInCircle(radius=1, minRadius=0)
@@ -271,7 +271,7 @@ function randInCircle(radius=1, minRadius=0)
271
271
  /** Returns a random color between the two passed in colors, combine components if linear
272
272
  * @param {Color} [colorA=(1,1,1,1)]
273
273
  * @param {Color} [colorB=(0,0,0,1)]
274
- * @param {Boolean} [linear]
274
+ * @param {boolean} [linear]
275
275
  * @return {Color}
276
276
  * @memberof Random */
277
277
  function randColor(colorA=new Color, colorB=new Color(0,0,0,1), linear=false)
@@ -295,17 +295,17 @@ function randColor(colorA=new Color, colorB=new Color(0,0,0,1), linear=false)
295
295
  class RandomGenerator
296
296
  {
297
297
  /** Create a random number generator with the seed passed in
298
- * @param {Number} seed - Starting seed */
298
+ * @param {number} seed - Starting seed */
299
299
  constructor(seed)
300
300
  {
301
- /** @property {Number} - random seed */
301
+ /** @property {number} - random seed */
302
302
  this.seed = seed;
303
303
  }
304
304
 
305
305
  /** Returns a seeded random value between the two values passed in
306
- * @param {Number} [valueA]
307
- * @param {Number} [valueB]
308
- * @return {Number} */
306
+ * @param {number} [valueA]
307
+ * @param {number} [valueB]
308
+ * @return {number} */
309
309
  float(valueA=1, valueB=0)
310
310
  {
311
311
  // xorshift algorithm
@@ -316,13 +316,13 @@ class RandomGenerator
316
316
  }
317
317
 
318
318
  /** Returns a floored seeded random value the two values passed in
319
- * @param {Number} valueA
320
- * @param {Number} [valueB]
321
- * @return {Number} */
319
+ * @param {number} valueA
320
+ * @param {number} [valueB]
321
+ * @return {number} */
322
322
  int(valueA, valueB=0) { return Math.floor(this.float(valueA, valueB)); }
323
323
 
324
324
  /** Randomly returns either -1 or 1 deterministically
325
- * @return {Number} */
325
+ * @return {number} */
326
326
  sign() { return this.float() > .5 ? 1 : -1; }
327
327
  }
328
328
 
@@ -330,8 +330,8 @@ class RandomGenerator
330
330
 
331
331
  /**
332
332
  * Create a 2d vector, can take another Vector2 to copy, 2 scalars, or 1 scalar
333
- * @param {(Number|Vector2)} [x]
334
- * @param {Number} [y]
333
+ * @param {Vector2|number} [x]
334
+ * @param {number} [y]
335
335
  * @return {Vector2}
336
336
  * @example
337
337
  * let a = vec2(0, 1); // vector with coordinates (0, 1)
@@ -350,7 +350,7 @@ function vec2(x=0, y)
350
350
  /**
351
351
  * Check if object is a valid Vector2
352
352
  * @param {any} v
353
- * @return {Boolean}
353
+ * @return {boolean}
354
354
  * @memberof Utilities
355
355
  */
356
356
  function isVector2(v) { return v instanceof Vector2; }
@@ -367,20 +367,20 @@ function isVector2(v) { return v instanceof Vector2; }
367
367
  class Vector2
368
368
  {
369
369
  /** Create a 2D vector with the x and y passed in, can also be created with vec2()
370
- * @param {Number} [x] - X axis location
371
- * @param {Number} [y] - Y axis location */
370
+ * @param {number} [x] - X axis location
371
+ * @param {number} [y] - Y axis location */
372
372
  constructor(x=0, y=0)
373
373
  {
374
- /** @property {Number} - X axis location */
374
+ /** @property {number} - X axis location */
375
375
  this.x = x;
376
- /** @property {Number} - Y axis location */
376
+ /** @property {number} - Y axis location */
377
377
  this.y = y;
378
378
  ASSERT(this.isValid());
379
379
  }
380
380
 
381
381
  /** Sets values of this vector and returns self
382
- * @param {Number} [x] - X axis location
383
- * @param {Number} [y] - Y axis location
382
+ * @param {number} [x] - X axis location
383
+ * @param {number} [y] - Y axis location
384
384
  * @return {Vector2} */
385
385
  set(x=0, y=0)
386
386
  {
@@ -431,7 +431,7 @@ class Vector2
431
431
  }
432
432
 
433
433
  /** Returns a copy of this vector scaled by the vector passed in
434
- * @param {Number} s - scale
434
+ * @param {number} s - scale
435
435
  * @return {Vector2} */
436
436
  scale(s)
437
437
  {
@@ -440,16 +440,16 @@ class Vector2
440
440
  }
441
441
 
442
442
  /** Returns the length of this vector
443
- * @return {Number} */
443
+ * @return {number} */
444
444
  length() { return this.lengthSquared()**.5; }
445
445
 
446
446
  /** Returns the length of this vector squared
447
- * @return {Number} */
447
+ * @return {number} */
448
448
  lengthSquared() { return this.x**2 + this.y**2; }
449
449
 
450
450
  /** Returns the distance from this vector to vector passed in
451
451
  * @param {Vector2} v - other vector
452
- * @return {Number} */
452
+ * @return {number} */
453
453
  distance(v)
454
454
  {
455
455
  ASSERT(isVector2(v));
@@ -458,7 +458,7 @@ class Vector2
458
458
 
459
459
  /** Returns the distance squared from this vector to vector passed in
460
460
  * @param {Vector2} v - other vector
461
- * @return {Number} */
461
+ * @return {number} */
462
462
  distanceSquared(v)
463
463
  {
464
464
  ASSERT(isVector2(v));
@@ -466,7 +466,7 @@ class Vector2
466
466
  }
467
467
 
468
468
  /** Returns a new vector in same direction as this one with the length passed in
469
- * @param {Number} [length]
469
+ * @param {number} [length]
470
470
  * @return {Vector2} */
471
471
  normalize(length=1)
472
472
  {
@@ -475,7 +475,7 @@ class Vector2
475
475
  }
476
476
 
477
477
  /** Returns a new vector clamped to length passed in
478
- * @param {Number} [length]
478
+ * @param {number} [length]
479
479
  * @return {Vector2} */
480
480
  clampLength(length=1)
481
481
  {
@@ -485,7 +485,7 @@ class Vector2
485
485
 
486
486
  /** Returns the dot product of this and the vector passed in
487
487
  * @param {Vector2} v - other vector
488
- * @return {Number} */
488
+ * @return {number} */
489
489
  dot(v)
490
490
  {
491
491
  ASSERT(isVector2(v));
@@ -494,7 +494,7 @@ class Vector2
494
494
 
495
495
  /** Returns the cross product of this and the vector passed in
496
496
  * @param {Vector2} v - other vector
497
- * @return {Number} */
497
+ * @return {number} */
498
498
  cross(v)
499
499
  {
500
500
  ASSERT(isVector2(v));
@@ -502,12 +502,12 @@ class Vector2
502
502
  }
503
503
 
504
504
  /** Returns the clockwise angle of this vector, up is angle 0
505
- * @return {Number} */
505
+ * @return {number} */
506
506
  angle() { return Math.atan2(this.x, this.y); }
507
507
 
508
508
  /** Sets this vector with clockwise angle and length passed in
509
- * @param {Number} [angle]
510
- * @param {Number} [length]
509
+ * @param {number} [angle]
510
+ * @param {number} [length]
511
511
  * @return {Vector2} */
512
512
  setAngle(angle=0, length=1)
513
513
  {
@@ -517,7 +517,7 @@ class Vector2
517
517
  }
518
518
 
519
519
  /** Returns copy of this vector rotated by the clockwise angle passed in
520
- * @param {Number} angle
520
+ * @param {number} angle
521
521
  * @return {Vector2} */
522
522
  rotate(angle)
523
523
  {
@@ -526,8 +526,8 @@ class Vector2
526
526
  }
527
527
 
528
528
  /** Set the integer direction of this vector, corresponding to multiples of 90 degree rotation (0-3)
529
- * @param {Number} [direction]
530
- * @param {Number} [length] */
529
+ * @param {number} [direction]
530
+ * @param {number} [length] */
531
531
  setDirection(direction, length=1)
532
532
  {
533
533
  direction = mod(direction, 4);
@@ -537,7 +537,7 @@ class Vector2
537
537
  }
538
538
 
539
539
  /** Returns the integer direction of this vector, corresponding to multiples of 90 degree rotation (0-3)
540
- * @return {Number} */
540
+ * @return {number} */
541
541
  direction()
542
542
  { return abs(this.x) > abs(this.y) ? this.x < 0 ? 3 : 1 : this.y < 0 ? 2 : 0; }
543
543
 
@@ -550,12 +550,12 @@ class Vector2
550
550
  floor() { return new Vector2(Math.floor(this.x), Math.floor(this.y)); }
551
551
 
552
552
  /** Returns the area this vector covers as a rectangle
553
- * @return {Number} */
553
+ * @return {number} */
554
554
  area() { return abs(this.x * this.y); }
555
555
 
556
556
  /** Returns a new vector that is p percent between this and the vector passed in
557
557
  * @param {Vector2} v - other vector
558
- * @param {Number} percent
558
+ * @param {number} percent
559
559
  * @return {Vector2} */
560
560
  lerp(v, percent)
561
561
  {
@@ -565,7 +565,7 @@ class Vector2
565
565
 
566
566
  /** Returns true if this vector is within the bounds of an array size passed in
567
567
  * @param {Vector2} arraySize
568
- * @return {Boolean} */
568
+ * @return {boolean} */
569
569
  arrayCheck(arraySize)
570
570
  {
571
571
  ASSERT(isVector2(arraySize));
@@ -573,8 +573,8 @@ class Vector2
573
573
  }
574
574
 
575
575
  /** Returns this vector expressed as a string
576
- * @param {Number} digits - precision to display
577
- * @return {String} */
576
+ * @param {number} digits - precision to display
577
+ * @return {string} */
578
578
  toString(digits=3)
579
579
  {
580
580
  if (debug)
@@ -582,7 +582,7 @@ class Vector2
582
582
  }
583
583
 
584
584
  /** Checks if this is a valid vector
585
- * @return {Boolean} */
585
+ * @return {boolean} */
586
586
  isValid()
587
587
  {
588
588
  return typeof this.x == 'number' && !isNaN(this.x)
@@ -594,10 +594,10 @@ class Vector2
594
594
 
595
595
  /**
596
596
  * Create a color object with RGBA values, white by default
597
- * @param {Number} [r=1] - red
598
- * @param {Number} [g=1] - green
599
- * @param {Number} [b=1] - blue
600
- * @param {Number} [a=1] - alpha
597
+ * @param {number} [r=1] - red
598
+ * @param {number} [g=1] - green
599
+ * @param {number} [b=1] - blue
600
+ * @param {number} [a=1] - alpha
601
601
  * @return {Color}
602
602
  * @memberof Utilities
603
603
  */
@@ -605,10 +605,10 @@ function rgb(r, g, b, a) { return new Color(r, g, b, a); }
605
605
 
606
606
  /**
607
607
  * Create a color object with HSLA values, white by default
608
- * @param {Number} [h=0] - hue
609
- * @param {Number} [s=0] - saturation
610
- * @param {Number} [l=1] - lightness
611
- * @param {Number} [a=1] - alpha
608
+ * @param {number} [h=0] - hue
609
+ * @param {number} [s=0] - saturation
610
+ * @param {number} [l=1] - lightness
611
+ * @param {number} [a=1] - alpha
612
612
  * @return {Color}
613
613
  * @memberof Utilities
614
614
  */
@@ -617,7 +617,7 @@ function hsl(h, s, l, a) { return new Color().setHSLA(h, s, l, a); }
617
617
  /**
618
618
  * Check if object is a valid Color
619
619
  * @param {any} c
620
- * @return {Boolean}
620
+ * @return {boolean}
621
621
  * @memberof Utilities
622
622
  */
623
623
  function isColor(c) { return c instanceof Color; }
@@ -634,28 +634,28 @@ function isColor(c) { return c instanceof Color; }
634
634
  class Color
635
635
  {
636
636
  /** Create a color with the rgba components passed in, white by default
637
- * @param {Number} [r] - red
638
- * @param {Number} [g] - green
639
- * @param {Number} [b] - blue
640
- * @param {Number} [a] - alpha*/
637
+ * @param {number} [r] - red
638
+ * @param {number} [g] - green
639
+ * @param {number} [b] - blue
640
+ * @param {number} [a] - alpha*/
641
641
  constructor(r=1, g=1, b=1, a=1)
642
642
  {
643
- /** @property {Number} - Red */
643
+ /** @property {number} - Red */
644
644
  this.r = r;
645
- /** @property {Number} - Green */
645
+ /** @property {number} - Green */
646
646
  this.g = g;
647
- /** @property {Number} - Blue */
647
+ /** @property {number} - Blue */
648
648
  this.b = b;
649
- /** @property {Number} - Alpha */
649
+ /** @property {number} - Alpha */
650
650
  this.a = a;
651
651
  ASSERT(this.isValid());
652
652
  }
653
653
 
654
654
  /** Sets values of this color and returns self
655
- * @param {Number} [r] - red
656
- * @param {Number} [g] - green
657
- * @param {Number} [b] - blue
658
- * @param {Number} [a] - alpha
655
+ * @param {number} [r] - red
656
+ * @param {number} [g] - green
657
+ * @param {number} [b] - blue
658
+ * @param {number} [a] - alpha
659
659
  * @return {Color} */
660
660
  set(r=1, g=1, b=1, a=1)
661
661
  {
@@ -708,8 +708,8 @@ class Color
708
708
  }
709
709
 
710
710
  /** Returns a copy of this color scaled by the value passed in, alpha can be scaled separately
711
- * @param {Number} scale
712
- * @param {Number} [alphaScale=scale]
711
+ * @param {number} scale
712
+ * @param {number} [alphaScale=scale]
713
713
  * @return {Color} */
714
714
  scale(scale, alphaScale=scale)
715
715
  { return new Color(this.r*scale, this.g*scale, this.b*scale, this.a*alphaScale); }
@@ -720,7 +720,7 @@ class Color
720
720
 
721
721
  /** Returns a new color that is p percent between this and the color passed in
722
722
  * @param {Color} c - other color
723
- * @param {Number} percent
723
+ * @param {number} percent
724
724
  * @return {Color} */
725
725
  lerp(c, percent)
726
726
  {
@@ -729,10 +729,10 @@ class Color
729
729
  }
730
730
 
731
731
  /** Sets this color given a hue, saturation, lightness, and alpha
732
- * @param {Number} [h] - hue
733
- * @param {Number} [s] - saturation
734
- * @param {Number} [l] - lightness
735
- * @param {Number} [a] - alpha
732
+ * @param {number} [h] - hue
733
+ * @param {number} [s] - saturation
734
+ * @param {number} [l] - lightness
735
+ * @param {number} [a] - alpha
736
736
  * @return {Color} */
737
737
  setHSLA(h=0, s=0, l=1, a=1)
738
738
  {
@@ -753,7 +753,7 @@ class Color
753
753
  }
754
754
 
755
755
  /** Returns this color expressed in hsla format
756
- * @return {Array} */
756
+ * @return {Array<number>} */
757
757
  HSLA()
758
758
  {
759
759
  const r = clamp(this.r);
@@ -780,8 +780,8 @@ class Color
780
780
  }
781
781
 
782
782
  /** Returns a new color that has each component randomly adjusted
783
- * @param {Number} [amount]
784
- * @param {Number} [alphaAmount]
783
+ * @param {number} [amount]
784
+ * @param {number} [alphaAmount]
785
785
  * @return {Color} */
786
786
  mutate(amount=.05, alphaAmount=0)
787
787
  {
@@ -795,8 +795,8 @@ class Color
795
795
  }
796
796
 
797
797
  /** Returns this color expressed as a hex color code
798
- * @param {Boolean} [useAlpha] - if alpha should be included in result
799
- * @return {String} */
798
+ * @param {boolean} [useAlpha] - if alpha should be included in result
799
+ * @return {string} */
800
800
  toString(useAlpha = true)
801
801
  {
802
802
  const toHex = (c)=> ((c=clamp(c)*255|0)<16 ? '0' : '') + c.toString(16);
@@ -804,7 +804,7 @@ class Color
804
804
  }
805
805
 
806
806
  /** Set this color from a hex code
807
- * @param {String} hex - html hex code
807
+ * @param {string} hex - html hex code
808
808
  * @return {Color} */
809
809
  setHex(hex)
810
810
  {
@@ -833,7 +833,7 @@ class Color
833
833
  }
834
834
 
835
835
  /** Returns this color expressed as 32 bit RGBA value
836
- * @return {Number} */
836
+ * @return {number} */
837
837
  rgbaInt()
838
838
  {
839
839
  const r = clamp(this.r)*255|0;
@@ -844,7 +844,7 @@ class Color
844
844
  }
845
845
 
846
846
  /** Checks if this is a valid color
847
- * @return {Boolean} */
847
+ * @return {boolean} */
848
848
  isValid()
849
849
  {
850
850
  return typeof this.r == 'number' && !isNaN(this.r)
@@ -926,42 +926,42 @@ const MAGENTA = rgb(1,0,1);
926
926
  class Timer
927
927
  {
928
928
  /** Create a timer object set time passed in
929
- * @param {Number} [timeLeft] - How much time left before the timer elapses in seconds */
929
+ * @param {number} [timeLeft] - How much time left before the timer elapses in seconds */
930
930
  constructor(timeLeft) { this.time = timeLeft == undefined ? undefined : time + timeLeft; this.setTime = timeLeft; }
931
931
 
932
932
  /** Set the timer with seconds passed in
933
- * @param {Number} [timeLeft] - How much time left before the timer is elapsed in seconds */
933
+ * @param {number} [timeLeft] - How much time left before the timer is elapsed in seconds */
934
934
  set(timeLeft=0) { this.time = time + timeLeft; this.setTime = timeLeft; }
935
935
 
936
936
  /** Unset the timer */
937
937
  unset() { this.time = undefined; }
938
938
 
939
939
  /** Returns true if set
940
- * @return {Boolean} */
940
+ * @return {boolean} */
941
941
  isSet() { return this.time != undefined; }
942
942
 
943
943
  /** Returns true if set and has not elapsed
944
- * @return {Boolean} */
944
+ * @return {boolean} */
945
945
  active() { return time < this.time; }
946
946
 
947
947
  /** Returns true if set and elapsed
948
- * @return {Boolean} */
948
+ * @return {boolean} */
949
949
  elapsed() { return time >= this.time; }
950
950
 
951
951
  /** Get how long since elapsed, returns 0 if not set (returns negative if currently active)
952
- * @return {Number} */
952
+ * @return {number} */
953
953
  get() { return this.isSet()? time - this.time : 0; }
954
954
 
955
955
  /** Get percentage elapsed based on time it was set to, returns 0 if not set
956
- * @return {Number} */
956
+ * @return {number} */
957
957
  getPercent() { return this.isSet()? 1-percent(this.time - time, 0, this.setTime) : 0; }
958
958
 
959
959
  /** Returns this timer expressed as a string
960
- * @return {String} */
960
+ * @return {string} */
961
961
  toString() { if (debug) { return this.isSet() ? Math.abs(this.get()) + ' seconds ' + (this.get()<0 ? 'before' : 'after' ) : 'unset'; }}
962
962
 
963
963
  /** Get how long since elapsed, returns 0 if not set (returns negative if currently active)
964
- * @return {Number} */
964
+ * @return {number} */
965
965
  valueOf() { return this.get(); }
966
966
  }
967
967
  /**
@@ -982,7 +982,7 @@ class Timer
982
982
  let cameraPos = vec2();
983
983
 
984
984
  /** Scale of camera in world space
985
- * @type {Number}
985
+ * @type {number}
986
986
  * @default
987
987
  * @memberof Settings */
988
988
  let cameraScale = 32;
@@ -1004,31 +1004,34 @@ let canvasMaxSize = vec2(1920, 1080);
1004
1004
  let canvasFixedSize = vec2();
1005
1005
 
1006
1006
  /** Use nearest neighbor scaling algorithm for canvas for more pixelated look
1007
- * @type {Boolean}
1007
+ * - Must be set before startup to take effect
1008
+ * - If enabled sets css image-rendering:pixelated
1009
+ * @type {boolean}
1008
1010
  * @default
1009
1011
  * @memberof Settings */
1010
1012
  let canvasPixelated = true;
1011
1013
 
1012
1014
  /** Disables texture filtering for crisper pixel art
1013
- * @type {Boolean}
1015
+ * @type {boolean}
1014
1016
  * @default
1015
1017
  * @memberof Settings */
1016
1018
  let tilesPixelated = true;
1017
1019
 
1018
1020
  /** Default font used for text rendering
1019
- * @type {String}
1021
+ * @type {string}
1020
1022
  * @default
1021
1023
  * @memberof Settings */
1022
1024
  let fontDefault = 'arial';
1023
1025
 
1024
1026
  /** Enable to show the LittleJS splash screen be shown on startup
1025
- * @type {Boolean}
1027
+ * @type {boolean}
1026
1028
  * @default
1027
1029
  * @memberof Settings */
1028
1030
  let showSplashScreen = false;
1029
1031
 
1030
1032
  /** Disables all rendering, audio, and input for servers
1031
- * @type {Boolean}
1033
+ * - Must be set before startup to take effect
1034
+ * @type {boolean}
1032
1035
  * @default
1033
1036
  * @memberof Settings */
1034
1037
  let headlessMode = false;
@@ -1037,13 +1040,15 @@ let headlessMode = false;
1037
1040
  // WebGL settings
1038
1041
 
1039
1042
  /** Enable webgl rendering, webgl can be disabled and removed from build (with some features disabled)
1040
- * @type {Boolean}
1043
+ * - Must be set before startup to take effect
1044
+ * @type {boolean}
1041
1045
  * @default
1042
1046
  * @memberof Settings */
1043
1047
  let glEnable = true;
1044
1048
 
1045
1049
  /** Fixes slow rendering in some browsers by not compositing the WebGL canvas
1046
- * @type {Boolean}
1050
+ * - Must be set before startup to take effect
1051
+ * @type {boolean}
1047
1052
  * @default
1048
1053
  * @memberof Settings */
1049
1054
  let glOverlay = true;
@@ -1058,7 +1063,7 @@ let glOverlay = true;
1058
1063
  let tileSizeDefault = vec2(16);
1059
1064
 
1060
1065
  /** How many pixels smaller to draw tiles to prevent bleeding from neighbors
1061
- * @type {Number}
1066
+ * @type {number}
1062
1067
  * @default
1063
1068
  * @memberof Settings */
1064
1069
  let tileFixBleedScale = 0;
@@ -1067,55 +1072,55 @@ let tileFixBleedScale = 0;
1067
1072
  // Object settings
1068
1073
 
1069
1074
  /** Enable physics solver for collisions between objects
1070
- * @type {Boolean}
1075
+ * @type {boolean}
1071
1076
  * @default
1072
1077
  * @memberof Settings */
1073
1078
  let enablePhysicsSolver = true;
1074
1079
 
1075
1080
  /** Default object mass for collision calculations (how heavy objects are)
1076
- * @type {Number}
1081
+ * @type {number}
1077
1082
  * @default
1078
1083
  * @memberof Settings */
1079
1084
  let objectDefaultMass = 1;
1080
1085
 
1081
1086
  /** How much to slow velocity by each frame (0-1)
1082
- * @type {Number}
1087
+ * @type {number}
1083
1088
  * @default
1084
1089
  * @memberof Settings */
1085
1090
  let objectDefaultDamping = 1;
1086
1091
 
1087
1092
  /** How much to slow angular velocity each frame (0-1)
1088
- * @type {Number}
1093
+ * @type {number}
1089
1094
  * @default
1090
1095
  * @memberof Settings */
1091
1096
  let objectDefaultAngleDamping = 1;
1092
1097
 
1093
1098
  /** How much to bounce when a collision occurs (0-1)
1094
- * @type {Number}
1099
+ * @type {number}
1095
1100
  * @default
1096
1101
  * @memberof Settings */
1097
1102
  let objectDefaultElasticity = 0;
1098
1103
 
1099
1104
  /** How much to slow when touching (0-1)
1100
- * @type {Number}
1105
+ * @type {number}
1101
1106
  * @default
1102
1107
  * @memberof Settings */
1103
1108
  let objectDefaultFriction = .8;
1104
1109
 
1105
1110
  /** Clamp max speed to avoid fast objects missing collisions
1106
- * @type {Number}
1111
+ * @type {number}
1107
1112
  * @default
1108
1113
  * @memberof Settings */
1109
1114
  let objectMaxSpeed = 1;
1110
1115
 
1111
1116
  /** How much gravity to apply to objects along the Y axis, negative is down
1112
- * @type {Number}
1117
+ * @type {number}
1113
1118
  * @default
1114
1119
  * @memberof Settings */
1115
1120
  let gravity = 0;
1116
1121
 
1117
1122
  /** Scales emit rate of particles, useful for low graphics mode (0 disables particle emitters)
1118
- * @type {Number}
1123
+ * @type {number}
1119
1124
  * @default
1120
1125
  * @memberof Settings */
1121
1126
  let particleEmitRateScale = 1;
@@ -1124,58 +1129,59 @@ let particleEmitRateScale = 1;
1124
1129
  // Input settings
1125
1130
 
1126
1131
  /** Should gamepads be allowed
1127
- * @type {Boolean}
1132
+ * @type {boolean}
1128
1133
  * @default
1129
1134
  * @memberof Settings */
1130
1135
  let gamepadsEnable = true;
1131
1136
 
1132
1137
  /** If true, the dpad input is also routed to the left analog stick (for better accessability)
1133
- * @type {Boolean}
1138
+ * @type {boolean}
1134
1139
  * @default
1135
1140
  * @memberof Settings */
1136
1141
  let gamepadDirectionEmulateStick = true;
1137
1142
 
1138
1143
  /** If true the WASD keys are also routed to the direction keys (for better accessability)
1139
- * @type {Boolean}
1144
+ * @type {boolean}
1140
1145
  * @default
1141
1146
  * @memberof Settings */
1142
1147
  let inputWASDEmulateDirection = true;
1143
1148
 
1144
1149
  /** True if touch input is enabled for mobile devices
1145
1150
  * - Touch events will be routed to mouse events
1146
- * @type {Boolean}
1151
+ * - Must be set before startup to take effect
1152
+ * @type {boolean}
1147
1153
  * @default
1148
1154
  * @memberof Settings */
1149
1155
  let touchInputEnable = true;
1150
1156
 
1151
1157
  /** True if touch gamepad should appear on mobile devices
1152
1158
  * - Supports left analog stick, 4 face buttons and start button (button 9)
1153
- * - Must be set by end of gameInit to be activated
1154
- * @type {Boolean}
1159
+ * - Must be set before startup to take effect
1160
+ * @type {boolean}
1155
1161
  * @default
1156
1162
  * @memberof Settings */
1157
1163
  let touchGamepadEnable = false;
1158
1164
 
1159
1165
  /** True if touch gamepad should be analog stick or false to use if 8 way dpad
1160
- * @type {Boolean}
1166
+ * @type {boolean}
1161
1167
  * @default
1162
1168
  * @memberof Settings */
1163
1169
  let touchGamepadAnalog = true;
1164
1170
 
1165
1171
  /** Size of virtual gamepad for touch devices in pixels
1166
- * @type {Number}
1172
+ * @type {number}
1167
1173
  * @default
1168
1174
  * @memberof Settings */
1169
1175
  let touchGamepadSize = 99;
1170
1176
 
1171
1177
  /** Transparency of touch gamepad overlay
1172
- * @type {Number}
1178
+ * @type {number}
1173
1179
  * @default
1174
1180
  * @memberof Settings */
1175
1181
  let touchGamepadAlpha = .3;
1176
1182
 
1177
1183
  /** Allow vibration hardware if it exists
1178
- * @type {Boolean}
1184
+ * @type {boolean}
1179
1185
  * @default
1180
1186
  * @memberof Settings */
1181
1187
  let vibrateEnable = true;
@@ -1184,25 +1190,25 @@ let vibrateEnable = true;
1184
1190
  // Audio settings
1185
1191
 
1186
1192
  /** All audio code can be disabled and removed from build
1187
- * @type {Boolean}
1193
+ * @type {boolean}
1188
1194
  * @default
1189
1195
  * @memberof Settings */
1190
1196
  let soundEnable = true;
1191
1197
 
1192
1198
  /** Volume scale to apply to all sound, music and speech
1193
- * @type {Number}
1199
+ * @type {number}
1194
1200
  * @default
1195
1201
  * @memberof Settings */
1196
1202
  let soundVolume = .3;
1197
1203
 
1198
1204
  /** Default range where sound no longer plays
1199
- * @type {Number}
1205
+ * @type {number}
1200
1206
  * @default
1201
1207
  * @memberof Settings */
1202
1208
  let soundDefaultRange = 40;
1203
1209
 
1204
1210
  /** Default range percent to start tapering off sound (0-1)
1205
- * @type {Number}
1211
+ * @type {number}
1206
1212
  * @default
1207
1213
  * @memberof Settings */
1208
1214
  let soundDefaultTaper = .7;
@@ -1211,13 +1217,13 @@ let soundDefaultTaper = .7;
1211
1217
  // Medals settings
1212
1218
 
1213
1219
  /** How long to show medals for in seconds
1214
- * @type {Number}
1220
+ * @type {number}
1215
1221
  * @default
1216
1222
  * @memberof Settings */
1217
1223
  let medalDisplayTime = 5;
1218
1224
 
1219
1225
  /** How quickly to slide on/off medals in seconds
1220
- * @type {Number}
1226
+ * @type {number}
1221
1227
  * @default
1222
1228
  * @memberof Settings */
1223
1229
  let medalDisplaySlideTime = .5;
@@ -1228,14 +1234,8 @@ let medalDisplaySlideTime = .5;
1228
1234
  * @memberof Settings */
1229
1235
  let medalDisplaySize = vec2(640, 80);
1230
1236
 
1231
- /** Size of icon in medal display
1232
- * @type {Number}
1233
- * @default
1234
- * @memberof Settings */
1235
- let medalDisplayIconSize = 50;
1236
-
1237
1237
  /** Set to stop medals from being unlockable (like if cheats are enabled)
1238
- * @type {Boolean}
1238
+ * @type {boolean}
1239
1239
  * @default
1240
1240
  * @memberof Settings */
1241
1241
  let medalsPreventUnlock = false;
@@ -1249,7 +1249,7 @@ let medalsPreventUnlock = false;
1249
1249
  function setCameraPos(pos) { cameraPos = pos; }
1250
1250
 
1251
1251
  /** Set scale of camera in world space
1252
- * @param {Number} scale
1252
+ * @param {number} scale
1253
1253
  * @memberof Settings */
1254
1254
  function setCameraScale(scale) { cameraScale = scale; }
1255
1255
 
@@ -1264,37 +1264,37 @@ function setCanvasMaxSize(size) { canvasMaxSize = size; }
1264
1264
  function setCanvasFixedSize(size) { canvasFixedSize = size; }
1265
1265
 
1266
1266
  /** Use nearest neighbor scaling algorithm for canvas for more pixelated look
1267
- * @param {Boolean} pixelated
1267
+ * @param {boolean} pixelated
1268
1268
  * @memberof Settings */
1269
1269
  function setCanvasPixelated(pixelated) { canvasPixelated = pixelated; }
1270
1270
 
1271
1271
  /** Disables texture filtering for crisper pixel art
1272
- * @param {Boolean} pixelated
1272
+ * @param {boolean} pixelated
1273
1273
  * @memberof Settings */
1274
1274
  function setTilesPixelated(pixelated) { tilesPixelated = pixelated; }
1275
1275
 
1276
1276
  /** Set default font used for text rendering
1277
- * @param {String} font
1277
+ * @param {string} font
1278
1278
  * @memberof Settings */
1279
1279
  function setFontDefault(font) { fontDefault = font; }
1280
1280
 
1281
1281
  /** Set if the LittleJS splash screen be shown on startup
1282
- * @param {Boolean} show
1282
+ * @param {boolean} show
1283
1283
  * @memberof Settings */
1284
1284
  function setShowSplashScreen(show) { showSplashScreen = show; }
1285
1285
 
1286
1286
  /** Set to disable rendering, audio, and input for servers
1287
- * @param {Boolean} headless
1287
+ * @param {boolean} headless
1288
1288
  * @memberof Settings */
1289
1289
  function setHeadlessMode(headless) { headlessMode = headless; }
1290
1290
 
1291
1291
  /** Set if webgl rendering is enabled
1292
- * @param {Boolean} enable
1292
+ * @param {boolean} enable
1293
1293
  * @memberof Settings */
1294
1294
  function setGlEnable(enable) { glEnable = enable; }
1295
1295
 
1296
1296
  /** Set to not composite the WebGL canvas
1297
- * @param {Boolean} overlay
1297
+ * @param {boolean} overlay
1298
1298
  * @memberof Settings */
1299
1299
  function setGlOverlay(overlay) { glOverlay = overlay; }
1300
1300
 
@@ -1304,107 +1304,107 @@ function setGlOverlay(overlay) { glOverlay = overlay; }
1304
1304
  function setTileSizeDefault(size) { tileSizeDefault = size; }
1305
1305
 
1306
1306
  /** Set to prevent tile bleeding from neighbors in pixels
1307
- * @param {Number} scale
1307
+ * @param {number} scale
1308
1308
  * @memberof Settings */
1309
1309
  function setTileFixBleedScale(scale) { tileFixBleedScale = scale; }
1310
1310
 
1311
1311
  /** Set if collisions between objects are enabled
1312
- * @param {Boolean} enable
1312
+ * @param {boolean} enable
1313
1313
  * @memberof Settings */
1314
1314
  function setEnablePhysicsSolver(enable) { enablePhysicsSolver = enable; }
1315
1315
 
1316
1316
  /** Set default object mass for collision calculations
1317
- * @param {Number} mass
1317
+ * @param {number} mass
1318
1318
  * @memberof Settings */
1319
1319
  function setObjectDefaultMass(mass) { objectDefaultMass = mass; }
1320
1320
 
1321
1321
  /** Set how much to slow velocity by each frame
1322
- * @param {Number} damp
1322
+ * @param {number} damp
1323
1323
  * @memberof Settings */
1324
1324
  function setObjectDefaultDamping(damp) { objectDefaultDamping = damp; }
1325
1325
 
1326
1326
  /** Set how much to slow angular velocity each frame
1327
- * @param {Number} damp
1327
+ * @param {number} damp
1328
1328
  * @memberof Settings */
1329
1329
  function setObjectDefaultAngleDamping(damp) { objectDefaultAngleDamping = damp; }
1330
1330
 
1331
1331
  /** Set how much to bounce when a collision occur
1332
- * @param {Number} elasticity
1332
+ * @param {number} elasticity
1333
1333
  * @memberof Settings */
1334
1334
  function setObjectDefaultElasticity(elasticity) { objectDefaultElasticity = elasticity; }
1335
1335
 
1336
1336
  /** Set how much to slow when touching
1337
- * @param {Number} friction
1337
+ * @param {number} friction
1338
1338
  * @memberof Settings */
1339
1339
  function setObjectDefaultFriction(friction) { objectDefaultFriction = friction; }
1340
1340
 
1341
1341
  /** Set max speed to avoid fast objects missing collisions
1342
- * @param {Number} speed
1342
+ * @param {number} speed
1343
1343
  * @memberof Settings */
1344
1344
  function setObjectMaxSpeed(speed) { objectMaxSpeed = speed; }
1345
1345
 
1346
1346
  /** Set how much gravity to apply to objects along the Y axis
1347
- * @param {Number} newGravity
1347
+ * @param {number} newGravity
1348
1348
  * @memberof Settings */
1349
1349
  function setGravity(newGravity) { gravity = newGravity; }
1350
1350
 
1351
1351
  /** Set to scales emit rate of particles
1352
- * @param {Number} scale
1352
+ * @param {number} scale
1353
1353
  * @memberof Settings */
1354
1354
  function setParticleEmitRateScale(scale) { particleEmitRateScale = scale; }
1355
1355
 
1356
1356
  /** Set if gamepads are enabled
1357
- * @param {Boolean} enable
1357
+ * @param {boolean} enable
1358
1358
  * @memberof Settings */
1359
1359
  function setGamepadsEnable(enable) { gamepadsEnable = enable; }
1360
1360
 
1361
1361
  /** Set if the dpad input is also routed to the left analog stick
1362
- * @param {Boolean} enable
1362
+ * @param {boolean} enable
1363
1363
  * @memberof Settings */
1364
1364
  function setGamepadDirectionEmulateStick(enable) { gamepadDirectionEmulateStick = enable; }
1365
1365
 
1366
1366
  /** Set if true the WASD keys are also routed to the direction keys
1367
- * @param {Boolean} enable
1367
+ * @param {boolean} enable
1368
1368
  * @memberof Settings */
1369
1369
  function setInputWASDEmulateDirection(enable) { inputWASDEmulateDirection = enable; }
1370
1370
 
1371
1371
  /** Set if touch input is allowed
1372
- * @param {Boolean} enable
1372
+ * @param {boolean} enable
1373
1373
  * @memberof Settings */
1374
1374
  function setTouchInputEnable(enable) { touchInputEnable = enable; }
1375
1375
 
1376
1376
  /** Set if touch gamepad should appear on mobile devices
1377
- * @param {Boolean} enable
1377
+ * @param {boolean} enable
1378
1378
  * @memberof Settings */
1379
1379
  function setTouchGamepadEnable(enable) { touchGamepadEnable = enable; }
1380
1380
 
1381
1381
  /** Set if touch gamepad should be analog stick or 8 way dpad
1382
- * @param {Boolean} analog
1382
+ * @param {boolean} analog
1383
1383
  * @memberof Settings */
1384
1384
  function setTouchGamepadAnalog(analog) { touchGamepadAnalog = analog; }
1385
1385
 
1386
1386
  /** Set size of virtual gamepad for touch devices in pixels
1387
- * @param {Number} size
1387
+ * @param {number} size
1388
1388
  * @memberof Settings */
1389
1389
  function setTouchGamepadSize(size) { touchGamepadSize = size; }
1390
1390
 
1391
1391
  /** Set transparency of touch gamepad overlay
1392
- * @param {Number} alpha
1392
+ * @param {number} alpha
1393
1393
  * @memberof Settings */
1394
1394
  function setTouchGamepadAlpha(alpha) { touchGamepadAlpha = alpha; }
1395
1395
 
1396
1396
  /** Set to allow vibration hardware if it exists
1397
- * @param {Boolean} enable
1397
+ * @param {boolean} enable
1398
1398
  * @memberof Settings */
1399
1399
  function setVibrateEnable(enable) { vibrateEnable = enable; }
1400
1400
 
1401
1401
  /** Set to disable all audio code
1402
- * @param {Boolean} enable
1402
+ * @param {boolean} enable
1403
1403
  * @memberof Settings */
1404
1404
  function setSoundEnable(enable) { soundEnable = enable; }
1405
1405
 
1406
1406
  /** Set volume scale to apply to all sound, music and speech
1407
- * @param {Number} volume
1407
+ * @param {number} volume
1408
1408
  * @memberof Settings */
1409
1409
  function setSoundVolume(volume)
1410
1410
  {
@@ -1414,22 +1414,22 @@ function setSoundVolume(volume)
1414
1414
  }
1415
1415
 
1416
1416
  /** Set default range where sound no longer plays
1417
- * @param {Number} range
1417
+ * @param {number} range
1418
1418
  * @memberof Settings */
1419
1419
  function setSoundDefaultRange(range) { soundDefaultRange = range; }
1420
1420
 
1421
1421
  /** Set default range percent to start tapering off sound
1422
- * @param {Number} taper
1422
+ * @param {number} taper
1423
1423
  * @memberof Settings */
1424
1424
  function setSoundDefaultTaper(taper) { soundDefaultTaper = taper; }
1425
1425
 
1426
1426
  /** Set how long to show medals for in seconds
1427
- * @param {Number} time
1427
+ * @param {number} time
1428
1428
  * @memberof Settings */
1429
1429
  function setMedalDisplayTime(time) { medalDisplayTime = time; }
1430
1430
 
1431
1431
  /** Set how quickly to slide on/off medals in seconds
1432
- * @param {Number} time
1432
+ * @param {number} time
1433
1433
  * @memberof Settings */
1434
1434
  function setMedalDisplaySlideTime(time) { medalDisplaySlideTime = time; }
1435
1435
 
@@ -1438,23 +1438,18 @@ function setMedalDisplaySlideTime(time) { medalDisplaySlideTime = time; }
1438
1438
  * @memberof Settings */
1439
1439
  function setMedalDisplaySize(size) { medalDisplaySize = size; }
1440
1440
 
1441
- /** Set size of icon in medal display
1442
- * @param {Number} size
1443
- * @memberof Settings */
1444
- function setMedalDisplayIconSize(size) { medalDisplayIconSize = size; }
1445
-
1446
1441
  /** Set to stop medals from being unlockable
1447
- * @param {Boolean} preventUnlock
1442
+ * @param {boolean} preventUnlock
1448
1443
  * @memberof Settings */
1449
1444
  function setMedalsPreventUnlock(preventUnlock) { medalsPreventUnlock = preventUnlock; }
1450
1445
 
1451
1446
  /** Set if watermark with FPS should be shown
1452
- * @param {Boolean} show
1447
+ * @param {boolean} show
1453
1448
  * @memberof Debug */
1454
1449
  function setShowWatermark(show) { showWatermark = show; }
1455
1450
 
1456
1451
  /** Set key code used to toggle debug mode, Esc by default
1457
- * @param {String} key
1452
+ * @param {string} key
1458
1453
  * @memberof Debug */
1459
1454
  function setDebugKey(key) { debugKey = key; }
1460
1455
  /**
@@ -1494,9 +1489,9 @@ class EngineObject
1494
1489
  * @param {Vector2} [pos=(0,0)] - World space position of the object
1495
1490
  * @param {Vector2} [size=(1,1)] - World space size of the object
1496
1491
  * @param {TileInfo} [tileInfo] - Tile info to render object (undefined is untextured)
1497
- * @param {Number} [angle] - Angle the object is rotated by
1492
+ * @param {number} [angle] - Angle the object is rotated by
1498
1493
  * @param {Color} [color=(1,1,1,1)] - Color to apply to tile when rendered
1499
- * @param {Number} [renderOrder] - Objects sorted by renderOrder before being rendered
1494
+ * @param {number} [renderOrder] - Objects sorted by renderOrder before being rendered
1500
1495
  */
1501
1496
  constructor(pos=vec2(), size=vec2(1), tileInfo, angle=0, color=new Color, renderOrder=0)
1502
1497
  {
@@ -1512,57 +1507,59 @@ class EngineObject
1512
1507
  this.drawSize = undefined;
1513
1508
  /** @property {TileInfo} - Tile info to render object (undefined is untextured) */
1514
1509
  this.tileInfo = tileInfo;
1515
- /** @property {Number} - Angle to rotate the object */
1510
+ /** @property {number} - Angle to rotate the object */
1516
1511
  this.angle = angle;
1517
1512
  /** @property {Color} - Color to apply when rendered */
1518
1513
  this.color = color;
1519
1514
  /** @property {Color} - Additive color to apply when rendered */
1520
1515
  this.additiveColor = undefined;
1521
- /** @property {Boolean} - Should it flip along y axis when rendered */
1516
+ /** @property {boolean} - Should it flip along y axis when rendered */
1522
1517
  this.mirror = false;
1523
1518
 
1524
1519
  // physical properties
1525
- /** @property {Number} [mass=objectDefaultMass] - How heavy the object is, static if 0 */
1520
+ /** @property {number} [mass=objectDefaultMass] - How heavy the object is, static if 0 */
1526
1521
  this.mass = objectDefaultMass;
1527
- /** @property {Number} [damping=objectDefaultDamping] - How much to slow down velocity each frame (0-1) */
1522
+ /** @property {number} [damping=objectDefaultDamping] - How much to slow down velocity each frame (0-1) */
1528
1523
  this.damping = objectDefaultDamping;
1529
- /** @property {Number} [angleDamping=objectDefaultAngleDamping] - How much to slow down rotation each frame (0-1) */
1524
+ /** @property {number} [angleDamping=objectDefaultAngleDamping] - How much to slow down rotation each frame (0-1) */
1530
1525
  this.angleDamping = objectDefaultAngleDamping;
1531
- /** @property {Number} [elasticity=objectDefaultElasticity] - How bouncy the object is when colliding (0-1) */
1526
+ /** @property {number} [elasticity=objectDefaultElasticity] - How bouncy the object is when colliding (0-1) */
1532
1527
  this.elasticity = objectDefaultElasticity;
1533
- /** @property {Number} [friction=objectDefaultFriction] - How much friction to apply when sliding (0-1) */
1528
+ /** @property {number} [friction=objectDefaultFriction] - How much friction to apply when sliding (0-1) */
1534
1529
  this.friction = objectDefaultFriction;
1535
- /** @property {Number} - How much to scale gravity by for this object */
1530
+ /** @property {number} - How much to scale gravity by for this object */
1536
1531
  this.gravityScale = 1;
1537
- /** @property {Number} - Objects are sorted by render order */
1532
+ /** @property {number} - Objects are sorted by render order */
1538
1533
  this.renderOrder = renderOrder;
1539
1534
  /** @property {Vector2} - Velocity of the object */
1540
1535
  this.velocity = vec2();
1541
- /** @property {Number} - Angular velocity of the object */
1536
+ /** @property {number} - Angular velocity of the object */
1542
1537
  this.angleVelocity = 0;
1543
- /** @property {Number} - Track when object was created */
1538
+ /** @property {number} - Track when object was created */
1544
1539
  this.spawnTime = time;
1545
- /** @property {Array} - List of children of this object */
1540
+ /** @property {Array<EngineObject>} - List of children of this object */
1546
1541
  this.children = [];
1547
- /** @property {Boolean} - Limit object speed using linear or circular math */
1542
+ /** @property {boolean} - Limit object speed using linear or circular math */
1548
1543
  this.clampSpeedLinear = true;
1544
+ /** @property {EngineObject} - Object we are standing on, if any */
1545
+ this.groundObject = undefined;
1549
1546
 
1550
1547
  // parent child system
1551
1548
  /** @property {EngineObject} - Parent of object if in local space */
1552
1549
  this.parent = undefined;
1553
1550
  /** @property {Vector2} - Local position if child */
1554
1551
  this.localPos = vec2();
1555
- /** @property {Number} - Local angle if child */
1552
+ /** @property {number} - Local angle if child */
1556
1553
  this.localAngle = 0;
1557
1554
 
1558
1555
  // collision flags
1559
- /** @property {Boolean} - Object collides with the tile collision */
1556
+ /** @property {boolean} - Object collides with the tile collision */
1560
1557
  this.collideTiles = false;
1561
- /** @property {Boolean} - Object collides with solid objects */
1558
+ /** @property {boolean} - Object collides with solid objects */
1562
1559
  this.collideSolidObjects = false;
1563
- /** @property {Boolean} - Object collides with and blocks other objects */
1560
+ /** @property {boolean} - Object collides with and blocks other objects */
1564
1561
  this.isSolid = false;
1565
- /** @property {Boolean} - Object collides with raycasts */
1562
+ /** @property {boolean} - Object collides with raycasts */
1566
1563
  this.collideRaycast = false;
1567
1564
 
1568
1565
  // add to list of objects
@@ -1630,9 +1627,10 @@ class EngineObject
1630
1627
  if (this.groundObject)
1631
1628
  {
1632
1629
  // apply friction in local space of ground object
1633
- const groundSpeed = this.groundObject.velocity ? this.groundObject.velocity.x : 0;
1630
+ const groundSpeed = this.groundObject != this && this.groundObject.velocity ?
1631
+ this.groundObject.velocity.x : 0;
1634
1632
  this.velocity.x = groundSpeed + (this.velocity.x - groundSpeed) * this.friction;
1635
- this.groundObject = 0;
1633
+ this.groundObject = undefined;
1636
1634
  //debugOverlay && debugPhysics && debugPoint(this.pos.subtract(vec2(0,this.size.y/2)), '#0f0');
1637
1635
  }
1638
1636
 
@@ -1749,18 +1747,22 @@ class EngineObject
1749
1747
  // bounce velocity
1750
1748
  this.velocity.y *= -this.elasticity;
1751
1749
 
1752
- // set if landed on ground
1753
- if (this.groundObject = wasMovingDown)
1750
+ if (wasMovingDown)
1754
1751
  {
1755
1752
  // adjust position to slightly above nearest tile boundary
1756
1753
  // this prevents gap between object and ground
1757
1754
  const epsilon = .0001;
1758
1755
  this.pos.y = (oldPos.y-this.size.y/2|0)+this.size.y/2+epsilon;
1756
+
1757
+ // set ground object to self for tile collision
1758
+ // TODO: rework system so tile collision is its own object
1759
+ this.groundObject = this;
1759
1760
  }
1760
1761
  else
1761
1762
  {
1762
1763
  // move to previous position
1763
1764
  this.pos.y = oldPos.y;
1765
+ this.groundObject = undefined;
1764
1766
  }
1765
1767
  }
1766
1768
  if (isBlockedX)
@@ -1812,19 +1814,19 @@ class EngineObject
1812
1814
  worldToLocalVector(vec) { return vec.rotate(-this.angle); }
1813
1815
 
1814
1816
  /** Called to check if a tile collision should be resolved
1815
- * @param {Number} tileData - the value of the tile at the position
1817
+ * @param {number} tileData - the value of the tile at the position
1816
1818
  * @param {Vector2} pos - tile where the collision occurred
1817
- * @return {Boolean} - true if the collision should be resolved */
1819
+ * @return {boolean} - true if the collision should be resolved */
1818
1820
  collideWithTile(tileData, pos) { return tileData > 0; }
1819
1821
 
1820
1822
  /** Called to check if a object collision should be resolved
1821
1823
  * @param {EngineObject} object - the object to test against
1822
- * @return {Boolean} - true if the collision should be resolved
1824
+ * @return {boolean} - true if the collision should be resolved
1823
1825
  */
1824
1826
  collideWithObject(object) { return true; }
1825
1827
 
1826
1828
  /** How long since the object was created
1827
- * @return {Number} */
1829
+ * @return {number} */
1828
1830
  getAliveTime() { return time - this.spawnTime; }
1829
1831
 
1830
1832
  /** Apply acceleration to this object (adjust velocity, not affected by mass)
@@ -1836,13 +1838,13 @@ class EngineObject
1836
1838
  applyForce(force) { this.applyAcceleration(force.scale(1/this.mass)); }
1837
1839
 
1838
1840
  /** Get the direction of the mirror
1839
- * @return {Number} -1 if this.mirror is true, or 1 if not mirrored */
1841
+ * @return {number} -1 if this.mirror is true, or 1 if not mirrored */
1840
1842
  getMirrorSign() { return this.mirror ? -1 : 1; }
1841
1843
 
1842
1844
  /** Attaches a child to this with a given local transform
1843
1845
  * @param {EngineObject} child
1844
1846
  * @param {Vector2} [localPos=(0,0)]
1845
- * @param {Number} [localAngle] */
1847
+ * @param {number} [localAngle] */
1846
1848
  addChild(child, localPos=vec2(), localAngle=0)
1847
1849
  {
1848
1850
  ASSERT(!child.parent && !this.children.includes(child));
@@ -1862,10 +1864,10 @@ class EngineObject
1862
1864
  }
1863
1865
 
1864
1866
  /** Set how this object collides
1865
- * @param {Boolean} [collideSolidObjects] - Does it collide with solid objects?
1866
- * @param {Boolean} [isSolid] - Does it collide with and block other objects? (expensive in large numbers)
1867
- * @param {Boolean} [collideTiles] - Does it collide with the tile collision?
1868
- * @param {Boolean} [collideRaycast] - Does it collide with raycasts? */
1867
+ * @param {boolean} [collideSolidObjects] - Does it collide with solid objects?
1868
+ * @param {boolean} [isSolid] - Does it collide with and block other objects? (expensive in large numbers)
1869
+ * @param {boolean} [collideTiles] - Does it collide with the tile collision?
1870
+ * @param {boolean} [collideRaycast] - Does it collide with raycasts? */
1869
1871
  setCollision(collideSolidObjects=true, isSolid=true, collideTiles=true, collideRaycast=true)
1870
1872
  {
1871
1873
  ASSERT(collideSolidObjects || !isSolid, 'solid objects must be set to collide');
@@ -1877,7 +1879,7 @@ class EngineObject
1877
1879
  }
1878
1880
 
1879
1881
  /** Returns string containing info about this object for debugging
1880
- * @return {String} */
1882
+ * @return {string} */
1881
1883
  toString()
1882
1884
  {
1883
1885
  if (debug)
@@ -1975,10 +1977,10 @@ let drawCount;
1975
1977
  * Create a tile info object using a grid based system
1976
1978
  * - This can take vecs or floats for easier use and conversion
1977
1979
  * - If an index is passed in, the tile size and index will determine the position
1978
- * @param {(Number|Vector2)} [pos=0] - Index of tile in sheet
1979
- * @param {(Number|Vector2)} [size=tileSizeDefault] - Size of tile in pixels
1980
- * @param {Number} [textureIndex] - Texture index to use
1981
- * @param {Number} [padding] - How many pixels padding around tiles
1980
+ * @param {Vector2|number} [pos=0] - Index of tile in sheet
1981
+ * @param {Vector2|number} [size=tileSizeDefault] - Size of tile in pixels
1982
+ * @param {number} [textureIndex] - Texture index to use
1983
+ * @param {number} [padding] - How many pixels padding around tiles
1982
1984
  * @return {TileInfo}
1983
1985
  * @example
1984
1986
  * tile(2) // a tile at index 2 using the default tile size of 16
@@ -2022,8 +2024,8 @@ class TileInfo
2022
2024
  /** Create a tile info object
2023
2025
  * @param {Vector2} [pos=(0,0)] - Top left corner of tile in pixels
2024
2026
  * @param {Vector2} [size=tileSizeDefault] - Size of tile in pixels
2025
- * @param {Number} [textureIndex] - Texture index to use
2026
- * @param {Number} [padding] - How many pixels padding around tiles
2027
+ * @param {number} [textureIndex] - Texture index to use
2028
+ * @param {number} [padding] - How many pixels padding around tiles
2027
2029
  */
2028
2030
  constructor(pos=vec2(), size=tileSizeDefault, textureIndex=0, padding=0)
2029
2031
  {
@@ -2031,9 +2033,9 @@ class TileInfo
2031
2033
  this.pos = pos.copy();
2032
2034
  /** @property {Vector2} - Size of tile in pixels */
2033
2035
  this.size = size.copy();
2034
- /** @property {Number} - Texture index to use */
2036
+ /** @property {number} - Texture index to use */
2035
2037
  this.textureIndex = textureIndex;
2036
- /** @property {Number} - How many pixels padding around tiles */
2038
+ /** @property {number} - How many pixels padding around tiles */
2037
2039
  this.padding = padding;
2038
2040
  }
2039
2041
 
@@ -2045,7 +2047,7 @@ class TileInfo
2045
2047
  { return new TileInfo(this.pos.add(offset), this.size, this.textureIndex); }
2046
2048
 
2047
2049
  /** Returns a copy of this tile offset by a number of animation frames
2048
- * @param {Number} frame - Offset to apply in animation frames
2050
+ * @param {number} frame - Offset to apply in animation frames
2049
2051
  * @return {TileInfo}
2050
2052
  */
2051
2053
  frame(frame)
@@ -2117,11 +2119,11 @@ function getCameraSize() { return mainCanvasSize.scale(1/cameraScale); }
2117
2119
  * @param {Vector2} [size=(1,1)] - Size of the tile in world space
2118
2120
  * @param {TileInfo}[tileInfo] - Tile info to use, untextured if undefined
2119
2121
  * @param {Color} [color=(1,1,1,1)] - Color to modulate with
2120
- * @param {Number} [angle] - Angle to rotate by
2121
- * @param {Boolean} [mirror] - If true image is flipped along the Y axis
2122
+ * @param {number} [angle] - Angle to rotate by
2123
+ * @param {boolean} [mirror] - If true image is flipped along the Y axis
2122
2124
  * @param {Color} [additiveColor=(0,0,0,0)] - Additive color to be applied
2123
- * @param {Boolean} [useWebGL=glEnable] - Use accelerated WebGL rendering
2124
- * @param {Boolean} [screenSpace=false] - If true the pos and size are in screen space
2125
+ * @param {boolean} [useWebGL=glEnable] - Use accelerated WebGL rendering
2126
+ * @param {boolean} [screenSpace=false] - If true the pos and size are in screen space
2125
2127
  * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context] - Canvas 2D context to draw to
2126
2128
  * @memberof Draw */
2127
2129
  function drawTile(pos, size=vec2(1), tileInfo, color=new Color,
@@ -2196,9 +2198,9 @@ function drawTile(pos, size=vec2(1), tileInfo, color=new Color,
2196
2198
  * @param {Vector2} pos
2197
2199
  * @param {Vector2} [size=(1,1)]
2198
2200
  * @param {Color} [color=(1,1,1,1)]
2199
- * @param {Number} [angle]
2200
- * @param {Boolean} [useWebGL=glEnable]
2201
- * @param {Boolean} [screenSpace=false]
2201
+ * @param {number} [angle]
2202
+ * @param {boolean} [useWebGL=glEnable]
2203
+ * @param {boolean} [screenSpace=false]
2202
2204
  * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
2203
2205
  * @memberof Draw */
2204
2206
  function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
@@ -2209,10 +2211,10 @@ function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
2209
2211
  /** Draw colored line between two points
2210
2212
  * @param {Vector2} posA
2211
2213
  * @param {Vector2} posB
2212
- * @param {Number} [thickness]
2214
+ * @param {number} [thickness]
2213
2215
  * @param {Color} [color=(1,1,1,1)]
2214
- * @param {Boolean} [useWebGL=glEnable]
2215
- * @param {Boolean} [screenSpace=false]
2216
+ * @param {boolean} [useWebGL=glEnable]
2217
+ * @param {boolean} [screenSpace=false]
2216
2218
  * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
2217
2219
  * @memberof Draw */
2218
2220
  function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace, context)
@@ -2223,11 +2225,11 @@ function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace, contex
2223
2225
  }
2224
2226
 
2225
2227
  /** Draw colored polygon using passed in points
2226
- * @param {Array} points - Array of Vector2 points
2228
+ * @param {Array<Vector2>} points - Array of Vector2 points
2227
2229
  * @param {Color} [color=(1,1,1,1)]
2228
- * @param {Number} [lineWidth=0]
2230
+ * @param {number} [lineWidth=0]
2229
2231
  * @param {Color} [lineColor=(0,0,0,1)]
2230
- * @param {Boolean} [screenSpace=false]
2232
+ * @param {boolean} [screenSpace=false]
2231
2233
  * @param {CanvasRenderingContext2D} [context=mainContext]
2232
2234
  * @memberof Draw */
2233
2235
  function drawPoly(points, color=new Color, lineWidth=0, lineColor=new Color(0,0,0), screenSpace, context=mainContext)
@@ -2249,13 +2251,13 @@ function drawPoly(points, color=new Color, lineWidth=0, lineColor=new Color(0,0,
2249
2251
 
2250
2252
  /** Draw colored ellipse using passed in point
2251
2253
  * @param {Vector2} pos
2252
- * @param {Number} [width=1]
2253
- * @param {Number} [height=1]
2254
- * @param {Number} [angle=0]
2254
+ * @param {number} [width=1]
2255
+ * @param {number} [height=1]
2256
+ * @param {number} [angle=0]
2255
2257
  * @param {Color} [color=(1,1,1,1)]
2256
- * @param {Number} [lineWidth=0]
2258
+ * @param {number} [lineWidth=0]
2257
2259
  * @param {Color} [lineColor=(0,0,0,1)]
2258
- * @param {Boolean} [screenSpace=false]
2260
+ * @param {boolean} [screenSpace=false]
2259
2261
  * @param {CanvasRenderingContext2D} [context=mainContext]
2260
2262
  * @memberof Draw */
2261
2263
  function drawEllipse(pos, width=1, height=1, angle=0, color=new Color, lineWidth=0, lineColor=new Color(0,0,0), screenSpace, context=mainContext)
@@ -2282,11 +2284,11 @@ function drawEllipse(pos, width=1, height=1, angle=0, color=new Color, lineWidth
2282
2284
 
2283
2285
  /** Draw colored circle using passed in point
2284
2286
  * @param {Vector2} pos
2285
- * @param {Number} [radius=1]
2287
+ * @param {number} [radius=1]
2286
2288
  * @param {Color} [color=(1,1,1,1)]
2287
- * @param {Number} [lineWidth=0]
2289
+ * @param {number} [lineWidth=0]
2288
2290
  * @param {Color} [lineColor=(0,0,0,1)]
2289
- * @param {Boolean} [screenSpace=false]
2291
+ * @param {boolean} [screenSpace=false]
2290
2292
  * @param {CanvasRenderingContext2D} [context=mainContext]
2291
2293
  * @memberof Draw */
2292
2294
  function drawCircle(pos, radius=1, color=new Color, lineWidth=0, lineColor=new Color(0,0,0), screenSpace, context=mainContext)
@@ -2295,10 +2297,10 @@ function drawCircle(pos, radius=1, color=new Color, lineWidth=0, lineColor=new C
2295
2297
  /** Draw directly to a 2d canvas context in world space
2296
2298
  * @param {Vector2} pos
2297
2299
  * @param {Vector2} size
2298
- * @param {Number} angle
2299
- * @param {Boolean} mirror
2300
+ * @param {number} angle
2301
+ * @param {boolean} mirror
2300
2302
  * @param {Function} drawFunction
2301
- * @param {Boolean} [screenSpace=false]
2303
+ * @param {boolean} [screenSpace=false]
2302
2304
  * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=mainContext]
2303
2305
  * @memberof Draw */
2304
2306
  function drawCanvas2D(pos, size, angle, mirror, drawFunction, screenSpace, context=mainContext)
@@ -2319,15 +2321,15 @@ function drawCanvas2D(pos, size, angle, mirror, drawFunction, screenSpace, conte
2319
2321
 
2320
2322
  /** Draw text on main canvas in world space
2321
2323
  * Automatically splits new lines into rows
2322
- * @param {String} text
2324
+ * @param {string} text
2323
2325
  * @param {Vector2} pos
2324
- * @param {Number} [size]
2326
+ * @param {number} [size]
2325
2327
  * @param {Color} [color=(1,1,1,1)]
2326
- * @param {Number} [lineWidth]
2328
+ * @param {number} [lineWidth]
2327
2329
  * @param {Color} [lineColor=(0,0,0,1)]
2328
2330
  * @param {CanvasTextAlign} [textAlign='center']
2329
- * @param {String} [font=fontDefault]
2330
- * @param {Number} [maxWidth]
2331
+ * @param {string} [font=fontDefault]
2332
+ * @param {number} [maxWidth]
2331
2333
  * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=mainContext]
2332
2334
  * @memberof Draw */
2333
2335
  function drawText(text, pos, size=1, color, lineWidth=0, lineColor, textAlign, font, maxWidth, context=mainContext)
@@ -2337,15 +2339,15 @@ function drawText(text, pos, size=1, color, lineWidth=0, lineColor, textAlign, f
2337
2339
 
2338
2340
  /** Draw text on overlay canvas in world space
2339
2341
  * Automatically splits new lines into rows
2340
- * @param {String} text
2342
+ * @param {string} text
2341
2343
  * @param {Vector2} pos
2342
- * @param {Number} [size]
2344
+ * @param {number} [size]
2343
2345
  * @param {Color} [color=(1,1,1,1)]
2344
- * @param {Number} [lineWidth]
2346
+ * @param {number} [lineWidth]
2345
2347
  * @param {Color} [lineColor=(0,0,0,1)]
2346
2348
  * @param {CanvasTextAlign} [textAlign='center']
2347
- * @param {String} [font=fontDefault]
2348
- * @param {Number} [maxWidth]
2349
+ * @param {string} [font=fontDefault]
2350
+ * @param {number} [maxWidth]
2349
2351
  * @memberof Draw */
2350
2352
  function drawTextOverlay(text, pos, size=1, color, lineWidth=0, lineColor, textAlign, font, maxWidth)
2351
2353
  {
@@ -2354,15 +2356,15 @@ function drawTextOverlay(text, pos, size=1, color, lineWidth=0, lineColor, textA
2354
2356
 
2355
2357
  /** Draw text on overlay canvas in screen space
2356
2358
  * Automatically splits new lines into rows
2357
- * @param {String} text
2359
+ * @param {string} text
2358
2360
  * @param {Vector2} pos
2359
- * @param {Number} [size]
2361
+ * @param {number} [size]
2360
2362
  * @param {Color} [color=(1,1,1,1)]
2361
- * @param {Number} [lineWidth]
2363
+ * @param {number} [lineWidth]
2362
2364
  * @param {Color} [lineColor=(0,0,0,1)]
2363
2365
  * @param {CanvasTextAlign} [textAlign]
2364
- * @param {String} [font=fontDefault]
2365
- * @param {Number} [maxWidth]
2366
+ * @param {string} [font=fontDefault]
2367
+ * @param {number} [maxWidth]
2366
2368
  * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=overlayContext]
2367
2369
  * @memberof Draw */
2368
2370
  function drawTextScreen(text, pos, size=1, color=new Color, lineWidth=0, lineColor=new Color(0,0,0), textAlign='center', font=fontDefault, maxWidth=undefined, context=overlayContext)
@@ -2388,8 +2390,8 @@ function drawTextScreen(text, pos, size=1, color=new Color, lineWidth=0, lineCol
2388
2390
  }
2389
2391
 
2390
2392
  /** Enable normal or additive blend mode
2391
- * @param {Boolean} [additive]
2392
- * @param {Boolean} [useWebGL=glEnable]
2393
+ * @param {boolean} [additive]
2394
+ * @param {boolean} [useWebGL=glEnable]
2393
2395
  * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=mainContext]
2394
2396
  * @memberof Draw */
2395
2397
  function setBlendMode(additive, useWebGL=glEnable, context)
@@ -2456,10 +2458,10 @@ class FontImage
2456
2458
  }
2457
2459
 
2458
2460
  /** Draw text in world space using the image font
2459
- * @param {String} text
2461
+ * @param {string} text
2460
2462
  * @param {Vector2} pos
2461
- * @param {Number} [scale=.25]
2462
- * @param {Boolean} [center]
2463
+ * @param {number} [scale=.25]
2464
+ * @param {boolean} [center]
2463
2465
  */
2464
2466
  drawText(text, pos, scale=1, center)
2465
2467
  {
@@ -2467,10 +2469,10 @@ class FontImage
2467
2469
  }
2468
2470
 
2469
2471
  /** Draw text in screen space using the image font
2470
- * @param {String} text
2472
+ * @param {string} text
2471
2473
  * @param {Vector2} pos
2472
- * @param {Number} [scale]
2473
- * @param {Boolean} [center]
2474
+ * @param {number} [scale]
2475
+ * @param {boolean} [center]
2474
2476
  */
2475
2477
  drawTextScreen(text, pos, scale=4, center)
2476
2478
  {
@@ -2508,7 +2510,7 @@ class FontImage
2508
2510
  // Display functions
2509
2511
 
2510
2512
  /** Returns true if fullscreen mode is active
2511
- * @return {Boolean}
2513
+ * @return {boolean}
2512
2514
  * @memberof Draw */
2513
2515
  function isFullscreen() { return !!document.fullscreenElement; }
2514
2516
 
@@ -2527,7 +2529,7 @@ function toggleFullscreen()
2527
2529
  }
2528
2530
 
2529
2531
  /** Set the cursor style
2530
- * @param {String} cursorStyle - CSS cursor style (auto, none, crosshair, etc)
2532
+ * @param {string} cursorStyle - CSS cursor style (auto, none, crosshair, etc)
2531
2533
  * @memberof Draw */
2532
2534
  function setCursor(cursorStyle = 'auto')
2533
2535
  {
@@ -2547,9 +2549,9 @@ function setCursor(cursorStyle = 'auto')
2547
2549
 
2548
2550
 
2549
2551
  /** Returns true if device key is down
2550
- * @param {String|Number} key
2551
- * @param {Number} [device]
2552
- * @return {Boolean}
2552
+ * @param {string|number} key
2553
+ * @param {number} [device]
2554
+ * @return {boolean}
2553
2555
  * @memberof Input */
2554
2556
  function keyIsDown(key, device=0)
2555
2557
  {
@@ -2558,9 +2560,9 @@ function keyIsDown(key, device=0)
2558
2560
  }
2559
2561
 
2560
2562
  /** Returns true if device key was pressed this frame
2561
- * @param {String|Number} key
2562
- * @param {Number} [device]
2563
- * @return {Boolean}
2563
+ * @param {string|number} key
2564
+ * @param {number} [device]
2565
+ * @return {boolean}
2564
2566
  * @memberof Input */
2565
2567
  function keyWasPressed(key, device=0)
2566
2568
  {
@@ -2569,9 +2571,9 @@ function keyWasPressed(key, device=0)
2569
2571
  }
2570
2572
 
2571
2573
  /** Returns true if device key was released this frame
2572
- * @param {String|Number} key
2573
- * @param {Number} [device]
2574
- * @return {Boolean}
2574
+ * @param {string|number} key
2575
+ * @param {number} [device]
2576
+ * @return {boolean}
2575
2577
  * @memberof Input */
2576
2578
  function keyWasReleased(key, device=0)
2577
2579
  {
@@ -2594,22 +2596,22 @@ function clearInput() { inputData = [[]]; touchGamepadButtons = []; }
2594
2596
 
2595
2597
  /** Returns true if mouse button is down
2596
2598
  * @function
2597
- * @param {Number} button
2598
- * @return {Boolean}
2599
+ * @param {number} button
2600
+ * @return {boolean}
2599
2601
  * @memberof Input */
2600
2602
  const mouseIsDown = keyIsDown;
2601
2603
 
2602
2604
  /** Returns true if mouse button was pressed
2603
2605
  * @function
2604
- * @param {Number} button
2605
- * @return {Boolean}
2606
+ * @param {number} button
2607
+ * @return {boolean}
2606
2608
  * @memberof Input */
2607
2609
  const mouseWasPressed = keyWasPressed;
2608
2610
 
2609
2611
  /** Returns true if mouse button was released
2610
2612
  * @function
2611
- * @param {Number} button
2612
- * @return {Boolean}
2613
+ * @param {number} button
2614
+ * @return {boolean}
2613
2615
  * @memberof Input */
2614
2616
  const mouseWasReleased = keyWasReleased;
2615
2617
 
@@ -2624,47 +2626,53 @@ let mousePos = vec2();
2624
2626
  let mousePosScreen = vec2();
2625
2627
 
2626
2628
  /** Mouse wheel delta this frame
2627
- * @type {Number}
2629
+ * @type {number}
2628
2630
  * @memberof Input */
2629
2631
  let mouseWheel = 0;
2630
2632
 
2631
2633
  /** Returns true if user is using gamepad (has more recently pressed a gamepad button)
2632
- * @type {Boolean}
2634
+ * @type {boolean}
2633
2635
  * @memberof Input */
2634
2636
  let isUsingGamepad = false;
2635
2637
 
2636
- /** Prevents input continuing to the default browser handling (false by default)
2637
- * @type {Boolean}
2638
+ /** Prevents input continuing to the default browser handling (true by default)
2639
+ * @type {boolean}
2638
2640
  * @memberof Input */
2639
- let preventDefaultInput = false;
2641
+ let inputPreventDefault = true;
2642
+
2643
+ /** Prevents input continuing to the default browser handling
2644
+ * This is useful to disable for html menus so the browser can handle input normally
2645
+ * @param {boolean} preventDefault
2646
+ * @memberof Input */
2647
+ function setInputPreventDefault(preventDefault) { inputPreventDefault = preventDefault; }
2640
2648
 
2641
2649
  /** Returns true if gamepad button is down
2642
- * @param {Number} button
2643
- * @param {Number} [gamepad]
2644
- * @return {Boolean}
2650
+ * @param {number} button
2651
+ * @param {number} [gamepad]
2652
+ * @return {boolean}
2645
2653
  * @memberof Input */
2646
2654
  function gamepadIsDown(button, gamepad=0)
2647
2655
  { return keyIsDown(button, gamepad+1); }
2648
2656
 
2649
2657
  /** Returns true if gamepad button was pressed
2650
- * @param {Number} button
2651
- * @param {Number} [gamepad]
2652
- * @return {Boolean}
2658
+ * @param {number} button
2659
+ * @param {number} [gamepad]
2660
+ * @return {boolean}
2653
2661
  * @memberof Input */
2654
2662
  function gamepadWasPressed(button, gamepad=0)
2655
2663
  { return keyWasPressed(button, gamepad+1); }
2656
2664
 
2657
2665
  /** Returns true if gamepad button was released
2658
- * @param {Number} button
2659
- * @param {Number} [gamepad]
2660
- * @return {Boolean}
2666
+ * @param {number} button
2667
+ * @param {number} [gamepad]
2668
+ * @return {boolean}
2661
2669
  * @memberof Input */
2662
2670
  function gamepadWasReleased(button, gamepad=0)
2663
2671
  { return keyWasReleased(button, gamepad+1); }
2664
2672
 
2665
2673
  /** Returns gamepad stick value
2666
- * @param {Number} stick
2667
- * @param {Number} [gamepad]
2674
+ * @param {number} stick
2675
+ * @param {number} [gamepad]
2668
2676
  * @return {Vector2}
2669
2677
  * @memberof Input */
2670
2678
  function gamepadStick(stick, gamepad=0)
@@ -2716,7 +2724,6 @@ function inputInit()
2716
2724
  if (inputWASDEmulateDirection)
2717
2725
  inputData[0][remapKey(e.code)] = 3;
2718
2726
  }
2719
- preventDefaultInput && e.preventDefault();
2720
2727
  }
2721
2728
 
2722
2729
  onkeyup = (e)=>
@@ -2746,7 +2753,7 @@ function inputInit()
2746
2753
  isUsingGamepad = false;
2747
2754
  inputData[0][e.button] = 3;
2748
2755
  mousePosScreen = mouseEventToScreen(e);
2749
- e.button && e.preventDefault();
2756
+ inputPreventDefault && e.button && e.preventDefault();
2750
2757
  }
2751
2758
  onmouseup = (e)=> inputData[0][e.button] = inputData[0][e.button] & 2 | 4;
2752
2759
  onmousemove = (e)=> mousePosScreen = mouseEventToScreen(e);
@@ -2867,7 +2874,7 @@ function gamepadsUpdate()
2867
2874
  ///////////////////////////////////////////////////////////////////////////////
2868
2875
 
2869
2876
  /** Pulse the vibration hardware if it exists
2870
- * @param {Number|Array} [pattern] - single value in ms or vibration interval array
2877
+ * @param {number|Array} [pattern] - single value in ms or vibration interval array
2871
2878
  * @memberof Input */
2872
2879
  function vibrate(pattern=100)
2873
2880
  { vibrateEnable && !headlessMode && navigator && navigator.vibrate && navigator.vibrate(pattern); }
@@ -2930,7 +2937,7 @@ function touchInputInit()
2930
2937
  wasTouching = touching;
2931
2938
 
2932
2939
  // prevent default handling like copy and magnifier lens
2933
- if (document.hasFocus()) // allow document to get focus
2940
+ if (inputPreventDefault && document.hasFocus()) // allow document to get focus
2934
2941
  e.preventDefault();
2935
2942
 
2936
2943
  // must return true so the document will get focus
@@ -3102,20 +3109,20 @@ class Sound
3102
3109
  {
3103
3110
  /** Create a sound object and cache the zzfx samples for later use
3104
3111
  * @param {Array} zzfxSound - Array of zzfx parameters, ex. [.5,.5]
3105
- * @param {Number} [range=soundDefaultRange] - World space max range of sound, will not play if camera is farther away
3106
- * @param {Number} [taper=soundDefaultTaper] - At what percentage of range should it start tapering
3112
+ * @param {number} [range=soundDefaultRange] - World space max range of sound, will not play if camera is farther away
3113
+ * @param {number} [taper=soundDefaultTaper] - At what percentage of range should it start tapering
3107
3114
  */
3108
3115
  constructor(zzfxSound, range=soundDefaultRange, taper=soundDefaultTaper)
3109
3116
  {
3110
3117
  if (!soundEnable || headlessMode) return;
3111
3118
 
3112
- /** @property {Number} - World space max range of sound, will not play if camera is farther away */
3119
+ /** @property {number} - World space max range of sound, will not play if camera is farther away */
3113
3120
  this.range = range;
3114
3121
 
3115
- /** @property {Number} - At what percentage of range should it start tapering off */
3122
+ /** @property {number} - At what percentage of range should it start tapering off */
3116
3123
  this.taper = taper;
3117
3124
 
3118
- /** @property {Number} - How much to randomize frequency each time sound plays */
3125
+ /** @property {number} - How much to randomize frequency each time sound plays */
3119
3126
  this.randomness = 0;
3120
3127
 
3121
3128
  if (zzfxSound)
@@ -3131,10 +3138,10 @@ class Sound
3131
3138
 
3132
3139
  /** Play the sound
3133
3140
  * @param {Vector2} [pos] - World space position to play the sound, sound is not attenuated if null
3134
- * @param {Number} [volume] - How much to scale volume by (in addition to range fade)
3135
- * @param {Number} [pitch] - How much to scale pitch by (also adjusted by this.randomness)
3136
- * @param {Number} [randomnessScale] - How much to scale randomness
3137
- * @param {Boolean} [loop] - Should the sound loop
3141
+ * @param {number} [volume] - How much to scale volume by (in addition to range fade)
3142
+ * @param {number} [pitch] - How much to scale pitch by (also adjusted by this.randomness)
3143
+ * @param {number} [randomnessScale] - How much to scale randomness
3144
+ * @param {boolean} [loop] - Should the sound loop
3138
3145
  * @return {AudioBufferSourceNode} - The audio source node
3139
3146
  */
3140
3147
  play(pos, volume=1, pitch=1, randomnessScale=1, loop=false)
@@ -3169,7 +3176,7 @@ class Sound
3169
3176
  }
3170
3177
 
3171
3178
  /** Set the sound volume of the most recently played instance of this sound
3172
- * @param {Number} [volume] - How much to scale volume by
3179
+ * @param {number} [volume] - How much to scale volume by
3173
3180
  */
3174
3181
  setVolume(volume=1)
3175
3182
  {
@@ -3191,22 +3198,22 @@ class Sound
3191
3198
  getSource() { return this.source; }
3192
3199
 
3193
3200
  /** Play the sound as a note with a semitone offset
3194
- * @param {Number} semitoneOffset - How many semitones to offset pitch
3201
+ * @param {number} semitoneOffset - How many semitones to offset pitch
3195
3202
  * @param {Vector2} [pos] - World space position to play the sound, sound is not attenuated if null
3196
- * @param {Number} [volume=1] - How much to scale volume by (in addition to range fade)
3203
+ * @param {number} [volume=1] - How much to scale volume by (in addition to range fade)
3197
3204
  * @return {AudioBufferSourceNode} - The audio source node
3198
3205
  */
3199
3206
  playNote(semitoneOffset, pos, volume)
3200
3207
  { return this.play(pos, volume, 2**(semitoneOffset/12), 0); }
3201
3208
 
3202
3209
  /** Get how long this sound is in seconds
3203
- * @return {Number} - How long the sound is in seconds (undefined if loading)
3210
+ * @return {number} - How long the sound is in seconds (undefined if loading)
3204
3211
  */
3205
3212
  getDuration()
3206
3213
  { return this.sampleChannels && this.sampleChannels[0].length / this.sampleRate; }
3207
3214
 
3208
3215
  /** Check if sound is loading, for sounds fetched from a url
3209
- * @return {Boolean} - True if sound is loading and not ready to play
3216
+ * @return {boolean} - True if sound is loading and not ready to play
3210
3217
  */
3211
3218
  isLoading() { return !this.sampleChannels; }
3212
3219
  }
@@ -3224,10 +3231,10 @@ class Sound
3224
3231
  class SoundWave extends Sound
3225
3232
  {
3226
3233
  /** Create a sound object and cache the wave file for later use
3227
- * @param {String} filename - Filename of audio file to load
3228
- * @param {Number} [randomness] - How much to randomize frequency each time sound plays
3229
- * @param {Number} [range=soundDefaultRange] - World space max range of sound, will not play if camera is farther away
3230
- * @param {Number} [taper=soundDefaultTaper] - At what percentage of range should it start tapering off
3234
+ * @param {string} filename - Filename of audio file to load
3235
+ * @param {number} [randomness] - How much to randomize frequency each time sound plays
3236
+ * @param {number} [range=soundDefaultRange] - World space max range of sound, will not play if camera is farther away
3237
+ * @param {number} [taper=soundDefaultTaper] - At what percentage of range should it start tapering off
3231
3238
  * @param {Function} [onloadCallback] - callback function to call when sound is loaded
3232
3239
  */
3233
3240
  constructor(filename, randomness=0, range, taper, onloadCallback)
@@ -3250,9 +3257,9 @@ class SoundWave extends Sound
3250
3257
  }
3251
3258
 
3252
3259
  /** Play an mp3, ogg, or wav audio from a local file or url
3253
- * @param {String} filename - Location of sound file to play
3254
- * @param {Number} [volume] - How much to scale volume by
3255
- * @param {Boolean} [loop] - True if the music should loop
3260
+ * @param {string} filename - Location of sound file to play
3261
+ * @param {number} [volume] - How much to scale volume by
3262
+ * @param {boolean} [loop] - True if the music should loop
3256
3263
  * @return {SoundWave} - The sound object for this file
3257
3264
  * @memberof Audio */
3258
3265
  function playAudioFile(filename, volume=1, loop=false)
@@ -3295,7 +3302,7 @@ function playAudioFile(filename, volume=1, loop=false)
3295
3302
  class Music extends Sound
3296
3303
  {
3297
3304
  /** Create a music object and cache the zzfx music samples for later use
3298
- * @param {[Array, Array, Array, Number]} zzfxMusic - Array of zzfx music parameters
3305
+ * @param {[Array, Array, Array, number]} zzfxMusic - Array of zzfx music parameters
3299
3306
  */
3300
3307
  constructor(zzfxMusic)
3301
3308
  {
@@ -3308,8 +3315,8 @@ class Music extends Sound
3308
3315
  }
3309
3316
 
3310
3317
  /** Play the music
3311
- * @param {Number} [volume=1] - How much to scale volume by
3312
- * @param {Boolean} [loop] - True if the music should loop
3318
+ * @param {number} [volume=1] - How much to scale volume by
3319
+ * @param {boolean} [loop] - True if the music should loop
3313
3320
  * @return {AudioBufferSourceNode} - The audio source node
3314
3321
  */
3315
3322
  playMusic(volume, loop=false)
@@ -3317,11 +3324,11 @@ class Music extends Sound
3317
3324
  }
3318
3325
 
3319
3326
  /** Speak text with passed in settings
3320
- * @param {String} text - The text to speak
3321
- * @param {String} [language] - The language/accent to use (examples: en, it, ru, ja, zh)
3322
- * @param {Number} [volume] - How much to scale volume by
3323
- * @param {Number} [rate] - How quickly to speak
3324
- * @param {Number} [pitch] - How much to change the pitch by
3327
+ * @param {string} text - The text to speak
3328
+ * @param {string} [language] - The language/accent to use (examples: en, it, ru, ja, zh)
3329
+ * @param {number} [volume] - How much to scale volume by
3330
+ * @param {number} [rate] - How quickly to speak
3331
+ * @param {number} [pitch] - How much to change the pitch by
3325
3332
  * @return {SpeechSynthesisUtterance} - The utterance that was spoken
3326
3333
  * @memberof Audio */
3327
3334
  function speak(text, language='', volume=1, rate=1, pitch=1)
@@ -3348,9 +3355,9 @@ function speak(text, language='', volume=1, rate=1, pitch=1)
3348
3355
  function speakStop() {speechSynthesis && speechSynthesis.cancel();}
3349
3356
 
3350
3357
  /** Get frequency of a note on a musical scale
3351
- * @param {Number} semitoneOffset - How many semitones away from the root note
3352
- * @param {Number} [rootFrequency=220] - Frequency at semitone offset 0
3353
- * @return {Number} - The frequency of the note
3358
+ * @param {number} semitoneOffset - How many semitones away from the root note
3359
+ * @param {number} [rootFrequency=220] - Frequency at semitone offset 0
3360
+ * @return {number} - The frequency of the note
3354
3361
  * @memberof Audio */
3355
3362
  function getNoteFrequency(semitoneOffset, rootFrequency=220)
3356
3363
  { return rootFrequency * 2**(semitoneOffset/12); }
@@ -3359,11 +3366,11 @@ function getNoteFrequency(semitoneOffset, rootFrequency=220)
3359
3366
 
3360
3367
  /** Play cached audio samples with given settings
3361
3368
  * @param {Array} sampleChannels - Array of arrays of samples to play (for stereo playback)
3362
- * @param {Number} [volume] - How much to scale volume by
3363
- * @param {Number} [rate] - The playback rate to use
3364
- * @param {Number} [pan] - How much to apply stereo panning
3365
- * @param {Boolean} [loop] - True if the sound should loop when it reaches the end
3366
- * @param {Number} [sampleRate=44100] - Sample rate for the sound
3369
+ * @param {number} [volume] - How much to scale volume by
3370
+ * @param {number} [rate] - The playback rate to use
3371
+ * @param {number} [pan] - How much to apply stereo panning
3372
+ * @param {boolean} [loop] - True if the sound should loop when it reaches the end
3373
+ * @param {number} [sampleRate=44100] - Sample rate for the sound
3367
3374
  * @param {GainNode} [gainNode] - Optional gain node for volume control while playing
3368
3375
  * @return {AudioBufferSourceNode} - The audio node of the sound played
3369
3376
  * @memberof Audio */
@@ -3422,27 +3429,27 @@ function zzfx(...zzfxSound) { return playSamples([zzfxG(...zzfxSound)]); }
3422
3429
  const zzfxR = 44100;
3423
3430
 
3424
3431
  /** Generate samples for a ZzFX sound
3425
- * @param {Number} [volume] - Volume scale (percent)
3426
- * @param {Number} [randomness] - How much to randomize frequency (percent Hz)
3427
- * @param {Number} [frequency] - Frequency of sound (Hz)
3428
- * @param {Number} [attack] - Attack time, how fast sound starts (seconds)
3429
- * @param {Number} [sustain] - Sustain time, how long sound holds (seconds)
3430
- * @param {Number} [release] - Release time, how fast sound fades out (seconds)
3431
- * @param {Number} [shape] - Shape of the sound wave
3432
- * @param {Number} [shapeCurve] - Squareness of wave (0=square, 1=normal, 2=pointy)
3433
- * @param {Number} [slide] - How much to slide frequency (kHz/s)
3434
- * @param {Number} [deltaSlide] - How much to change slide (kHz/s/s)
3435
- * @param {Number} [pitchJump] - Frequency of pitch jump (Hz)
3436
- * @param {Number} [pitchJumpTime] - Time of pitch jump (seconds)
3437
- * @param {Number} [repeatTime] - Resets some parameters periodically (seconds)
3438
- * @param {Number} [noise] - How much random noise to add (percent)
3439
- * @param {Number} [modulation] - Frequency of modulation wave, negative flips phase (Hz)
3440
- * @param {Number} [bitCrush] - Resamples at a lower frequency in (samples*100)
3441
- * @param {Number} [delay] - Overlap sound with itself for reverb and flanger effects (seconds)
3442
- * @param {Number} [sustainVolume] - Volume level for sustain (percent)
3443
- * @param {Number} [decay] - Decay time, how long to reach sustain after attack (seconds)
3444
- * @param {Number} [tremolo] - Trembling effect, rate controlled by repeat time (percent)
3445
- * @param {Number} [filter] - Filter cutoff frequency, positive for HPF, negative for LPF (Hz)
3432
+ * @param {number} [volume] - Volume scale (percent)
3433
+ * @param {number} [randomness] - How much to randomize frequency (percent Hz)
3434
+ * @param {number} [frequency] - Frequency of sound (Hz)
3435
+ * @param {number} [attack] - Attack time, how fast sound starts (seconds)
3436
+ * @param {number} [sustain] - Sustain time, how long sound holds (seconds)
3437
+ * @param {number} [release] - Release time, how fast sound fades out (seconds)
3438
+ * @param {number} [shape] - Shape of the sound wave
3439
+ * @param {number} [shapeCurve] - Squareness of wave (0=square, 1=normal, 2=pointy)
3440
+ * @param {number} [slide] - How much to slide frequency (kHz/s)
3441
+ * @param {number} [deltaSlide] - How much to change slide (kHz/s/s)
3442
+ * @param {number} [pitchJump] - Frequency of pitch jump (Hz)
3443
+ * @param {number} [pitchJumpTime] - Time of pitch jump (seconds)
3444
+ * @param {number} [repeatTime] - Resets some parameters periodically (seconds)
3445
+ * @param {number} [noise] - How much random noise to add (percent)
3446
+ * @param {number} [modulation] - Frequency of modulation wave, negative flips phase (Hz)
3447
+ * @param {number} [bitCrush] - Resamples at a lower frequency in (samples*100)
3448
+ * @param {number} [delay] - Overlap sound with itself for reverb and flanger effects (seconds)
3449
+ * @param {number} [sustainVolume] - Volume level for sustain (percent)
3450
+ * @param {number} [decay] - Decay time, how long to reach sustain after attack (seconds)
3451
+ * @param {number} [tremolo] - Trembling effect, rate controlled by repeat time (percent)
3452
+ * @param {number} [filter] - Filter cutoff frequency, positive for HPF, negative for LPF (Hz)
3446
3453
  * @return {Array} - Array of audio samples
3447
3454
  * @memberof Audio
3448
3455
  */
@@ -3548,7 +3555,7 @@ function zzfxG
3548
3555
  * @param {Array} instruments - Array of ZzFX sound parameters
3549
3556
  * @param {Array} patterns - Array of pattern data
3550
3557
  * @param {Array} sequence - Array of pattern indexes
3551
- * @param {Number} [BPM] - Playback speed of the song in BPM
3558
+ * @param {number} [BPM] - Playback speed of the song in BPM
3552
3559
  * @return {Array} - Left and right channel sample data
3553
3560
  * @memberof Audio */
3554
3561
  function zzfxM(instruments, patterns, sequence, BPM = 125)
@@ -3660,7 +3667,7 @@ function zzfxM(instruments, patterns, sequence, BPM = 125)
3660
3667
 
3661
3668
 
3662
3669
  /** The tile collision layer grid, use setTileCollisionData and getTileCollisionData to access
3663
- * @type {Array}
3670
+ * @type {Array<number>}
3664
3671
  * @memberof TileCollision */
3665
3672
  let tileCollision = [];
3666
3673
 
@@ -3682,7 +3689,7 @@ function initTileCollision(size)
3682
3689
 
3683
3690
  /** Set tile collision data for a given cell in the grid
3684
3691
  * @param {Vector2} pos
3685
- * @param {Number} [data]
3692
+ * @param {number} [data]
3686
3693
  * @memberof TileCollision */
3687
3694
  function setTileCollisionData(pos, data=0)
3688
3695
  {
@@ -3691,7 +3698,7 @@ function setTileCollisionData(pos, data=0)
3691
3698
 
3692
3699
  /** Get tile collision data for a given cell in the grid
3693
3700
  * @param {Vector2} pos
3694
- * @return {Number}
3701
+ * @return {number}
3695
3702
  * @memberof TileCollision */
3696
3703
  function getTileCollisionData(pos)
3697
3704
  {
@@ -3702,7 +3709,7 @@ function getTileCollisionData(pos)
3702
3709
  * @param {Vector2} pos
3703
3710
  * @param {Vector2} [size=(0,0)]
3704
3711
  * @param {EngineObject} [object]
3705
- * @return {Boolean}
3712
+ * @return {boolean}
3706
3713
  * @memberof TileCollision */
3707
3714
  function tileCollisionTest(pos, size=vec2(), object)
3708
3715
  {
@@ -3783,17 +3790,17 @@ function tileCollisionRaycast(posStart, posEnd, object)
3783
3790
  class TileLayerData
3784
3791
  {
3785
3792
  /** Create a tile layer data object, one for each tile in a TileLayer
3786
- * @param {Number} [tile] - The tile to use, untextured if undefined
3787
- * @param {Number} [direction] - Integer direction of tile, in 90 degree increments
3788
- * @param {Boolean} [mirror] - If the tile should be mirrored along the x axis
3793
+ * @param {number} [tile] - The tile to use, untextured if undefined
3794
+ * @param {number} [direction] - Integer direction of tile, in 90 degree increments
3795
+ * @param {boolean} [mirror] - If the tile should be mirrored along the x axis
3789
3796
  * @param {Color} [color] - Color of the tile */
3790
3797
  constructor(tile, direction=0, mirror=false, color=new Color)
3791
3798
  {
3792
- /** @property {Number} - The tile to use, untextured if undefined */
3799
+ /** @property {number} - The tile to use, untextured if undefined */
3793
3800
  this.tile = tile;
3794
- /** @property {Number} - Integer direction of tile, in 90 degree increments */
3801
+ /** @property {number} - Integer direction of tile, in 90 degree increments */
3795
3802
  this.direction = direction;
3796
- /** @property {Boolean} - If the tile should be mirrored along the x axis */
3803
+ /** @property {boolean} - If the tile should be mirrored along the x axis */
3797
3804
  this.mirror = mirror;
3798
3805
  /** @property {Color} - Color of the tile */
3799
3806
  this.color = color;
@@ -3822,7 +3829,7 @@ class TileLayer extends EngineObject
3822
3829
  * @param {Vector2} [size=tileCollisionSize] - World space size
3823
3830
  * @param {TileInfo} [tileInfo] - Tile info for layer
3824
3831
  * @param {Vector2} [scale=(1,1)] - How much to scale this layer when rendered
3825
- * @param {Number} [renderOrder] - Objects are sorted by renderOrder
3832
+ * @param {number} [renderOrder] - Objects are sorted by renderOrder
3826
3833
  */
3827
3834
  constructor(position, size=tileCollisionSize, tileInfo=tile(), scale=vec2(1), renderOrder=0)
3828
3835
  {
@@ -3834,7 +3841,7 @@ class TileLayer extends EngineObject
3834
3841
  this.context = this.canvas.getContext('2d');
3835
3842
  /** @property {Vector2} - How much to scale this layer when rendered */
3836
3843
  this.scale = scale;
3837
- /** @property {Boolean} - If true this layer will render to overlay canvas and appear above all objects */
3844
+ /** @property {boolean} - If true this layer will render to overlay canvas and appear above all objects */
3838
3845
  this.isOverlay = false;
3839
3846
 
3840
3847
  // init tile data
@@ -3857,7 +3864,7 @@ class TileLayer extends EngineObject
3857
3864
  /** Set data at a given position in the array
3858
3865
  * @param {Vector2} layerPos - Local position in array
3859
3866
  * @param {TileLayerData} data - Data to set
3860
- * @param {Boolean} [redraw] - Force the tile to redraw if true */
3867
+ * @param {boolean} [redraw] - Force the tile to redraw if true */
3861
3868
  setData(layerPos, data, redraw=false)
3862
3869
  {
3863
3870
  if (layerPos.arrayCheck(this.size))
@@ -3910,7 +3917,7 @@ class TileLayer extends EngineObject
3910
3917
 
3911
3918
  /** Call to start the redraw process
3912
3919
  * - This can be used to manually update small parts of the level
3913
- * @param {Boolean} [clear] - Should it clear the canvas before drawing */
3920
+ * @param {boolean} [clear] - Should it clear the canvas before drawing */
3914
3921
  redrawStart(clear=false)
3915
3922
  {
3916
3923
  // save current render settings
@@ -3954,7 +3961,7 @@ class TileLayer extends EngineObject
3954
3961
  * This can be used to clear out tiles when they are destroyed
3955
3962
  * Tiles can also be redrawn if inside a redrawStart/End block
3956
3963
  * @param {Vector2} layerPos
3957
- * @param {Boolean} [clear] - should the old tile be cleared out
3964
+ * @param {boolean} [clear] - should the old tile be cleared out
3958
3965
  */
3959
3966
  drawTileData(layerPos, clear=true)
3960
3967
  {
@@ -3972,7 +3979,7 @@ class TileLayer extends EngineObject
3972
3979
  {
3973
3980
  ASSERT(mainContext == this.context, 'must call redrawStart() before drawing tiles');
3974
3981
  const pos = layerPos.add(vec2(.5));
3975
- const tileInfo = tile(d.tile, s, this.tileInfo.textureIndex);
3982
+ const tileInfo = tile(d.tile, s, this.tileInfo.textureIndex, this.tileInfo.padding);
3976
3983
  drawTile(pos, vec2(1), tileInfo, d.color, d.direction*PI/2, d.mirror);
3977
3984
  }
3978
3985
  }
@@ -3980,8 +3987,8 @@ class TileLayer extends EngineObject
3980
3987
  /** Draw directly to the 2D canvas in world space (bypass webgl)
3981
3988
  * @param {Vector2} pos
3982
3989
  * @param {Vector2} size
3983
- * @param {Number} angle
3984
- * @param {Boolean} mirror
3990
+ * @param {number} angle
3991
+ * @param {boolean} mirror
3985
3992
  * @param {Function} drawFunction */
3986
3993
  drawCanvas2D(pos, size, angle, mirror, drawFunction)
3987
3994
  {
@@ -4001,8 +4008,8 @@ class TileLayer extends EngineObject
4001
4008
  * @param {Vector2} [size=(1,1)]
4002
4009
  * @param {TileInfo} [tileInfo]
4003
4010
  * @param {Color} [color=(1,1,1,1)]
4004
- * @param {Number} [angle=0]
4005
- * @param {Boolean} [mirror=0] */
4011
+ * @param {number} [angle=0]
4012
+ * @param {boolean} [mirror=0] */
4006
4013
  drawTile(pos, size=vec2(1), tileInfo, color=new Color, angle, mirror)
4007
4014
  {
4008
4015
  this.drawCanvas2D(pos, size, angle, mirror, (context)=>
@@ -4029,7 +4036,7 @@ class TileLayer extends EngineObject
4029
4036
  * @param {Vector2} pos
4030
4037
  * @param {Vector2} [size=(1,1)]
4031
4038
  * @param {Color} [color=(1,1,1,1)]
4032
- * @param {Number} [angle=0] */
4039
+ * @param {number} [angle=0] */
4033
4040
  drawRect(pos, size, color, angle)
4034
4041
  { this.drawTile(pos, size, undefined, color, angle); }
4035
4042
  }
@@ -4081,11 +4088,11 @@ class ParticleEmitter extends EngineObject
4081
4088
  * @param {Number} [particleConeAngle] - Cone for start particle angle
4082
4089
  * @param {Number} [fadeRate] - How quick to fade particles at start/end in percent of life
4083
4090
  * @param {Number} [randomness] - Apply extra randomness percent
4084
- * @param {Boolean} [collideTiles] - Do particles collide against tiles
4085
- * @param {Boolean} [additive] - Should particles use additive blend
4086
- * @param {Boolean} [randomColorLinear] - Should color be randomized linearly or across each component
4091
+ * @param {boolean} [collideTiles] - Do particles collide against tiles
4092
+ * @param {boolean} [additive] - Should particles use additive blend
4093
+ * @param {boolean} [randomColorLinear] - Should color be randomized linearly or across each component
4087
4094
  * @param {Number} [renderOrder] - Render order for particles (additive is above other stuff by default)
4088
- * @param {Boolean} [localSpace] - Should it be in local space of emitter (world space is default)
4095
+ * @param {boolean} [localSpace] - Should it be in local space of emitter (world space is default)
4089
4096
  */
4090
4097
  constructor
4091
4098
  (
@@ -4139,7 +4146,7 @@ class ParticleEmitter extends EngineObject
4139
4146
  this.colorEndA = colorEndA;
4140
4147
  /** @property {Color} - Color at end of life 2, randomized between end colors */
4141
4148
  this.colorEndB = colorEndB;
4142
- /** @property {Boolean} - Should color be randomized linearly or across each component */
4149
+ /** @property {boolean} - Should color be randomized linearly or across each component */
4143
4150
  this.randomColorLinear = randomColorLinear;
4144
4151
 
4145
4152
  // particle settings
@@ -4165,11 +4172,11 @@ class ParticleEmitter extends EngineObject
4165
4172
  this.fadeRate = fadeRate;
4166
4173
  /** @property {Number} - Apply extra randomness percent */
4167
4174
  this.randomness = randomness;
4168
- /** @property {Boolean} - Do particles collide against tiles */
4175
+ /** @property {boolean} - Do particles collide against tiles */
4169
4176
  this.collideTiles = collideTiles;
4170
- /** @property {Boolean} - Should particles use additive blend */
4177
+ /** @property {boolean} - Should particles use additive blend */
4171
4178
  this.additive = additive;
4172
- /** @property {Boolean} - Should it be in local space of emitter */
4179
+ /** @property {boolean} - Should it be in local space of emitter */
4173
4180
  this.localSpace = localSpace;
4174
4181
  /** @property {Number} - If non zero the particle is drawn as a trail, stretched in the direction of velocity */
4175
4182
  this.trailScale = 0;
@@ -4279,7 +4286,7 @@ class Particle extends EngineObject
4279
4286
  * @param {Number} sizeStart - Size at start of life
4280
4287
  * @param {Number} sizeEnd - Size at end of life
4281
4288
  * @param {Number} fadeRate - How quick to fade in/out
4282
- * @param {Boolean} additive - Does it use additive blend mode
4289
+ * @param {boolean} additive - Does it use additive blend mode
4283
4290
  * @param {Number} trailScale - If a trail, how long to make it
4284
4291
  * @param {ParticleEmitter} [localSpaceEmitter] - Parent emitter if local space
4285
4292
  * @param {Function} [destroyCallback] - Callback when particle dies
@@ -4301,7 +4308,7 @@ class Particle extends EngineObject
4301
4308
  this.sizeEndDelta = sizeEnd - sizeStart;
4302
4309
  /** @property {Number} - How quick to fade in/out */
4303
4310
  this.fadeRate = fadeRate;
4304
- /** @property {Boolean} - Is it additive */
4311
+ /** @property {boolean} - Is it additive */
4305
4312
  this.additive = additive;
4306
4313
  /** @property {Number} - If a trail, how long to make it */
4307
4314
  this.trailScale = trailScale;
@@ -4476,7 +4483,7 @@ class Medal
4476
4483
  /** @property {String} - Icon for the medal */
4477
4484
  this.icon = icon;
4478
4485
 
4479
- /** @property {Boolean} - Is the medal unlocked? */
4486
+ /** @property {boolean} - Is the medal unlocked? */
4480
4487
  this.unlocked = false;
4481
4488
 
4482
4489
  // load the source image if provided
@@ -4506,8 +4513,9 @@ class Medal
4506
4513
  {
4507
4514
  const context = overlayContext;
4508
4515
  const width = min(medalDisplaySize.x, mainCanvas.width);
4516
+ const height = medalDisplaySize.y;
4509
4517
  const x = overlayCanvas.width - width;
4510
- const y = -medalDisplaySize.y*hidePercent;
4518
+ const y = -height*hidePercent;
4511
4519
 
4512
4520
  // draw containing rect and clip to that region
4513
4521
  context.save();
@@ -4515,25 +4523,34 @@ class Medal
4515
4523
  context.fillStyle = new Color(.9,.9,.9).toString();
4516
4524
  context.strokeStyle = new Color(0,0,0).toString();
4517
4525
  context.lineWidth = 3;
4518
- context.rect(x, y, width, medalDisplaySize.y);
4526
+ context.rect(x, y, width, height);
4519
4527
  context.fill();
4520
4528
  context.stroke();
4521
4529
  context.clip();
4522
4530
 
4523
- // draw the icon and text
4524
- this.renderIcon(vec2(x+15+medalDisplayIconSize/2, y+medalDisplaySize.y/2));
4525
- const pos = vec2(x+medalDisplayIconSize+30, y+28);
4526
- drawTextScreen(this.name, pos, 38, new Color(0,0,0), 0, undefined, 'left');
4527
- pos.y += 32;
4528
- drawTextScreen(this.description, pos, 24, new Color(0,0,0), 0, undefined, 'left');
4531
+ // draw the icon
4532
+ const gap = vec2(.1, .05).scale(height);
4533
+ const medalDisplayIconSize = height - 2*gap.x;
4534
+ this.renderIcon(vec2(x + gap.x + medalDisplayIconSize/2, y + height/2), medalDisplayIconSize);
4535
+
4536
+ // draw the name
4537
+ const nameSize = height*.5;
4538
+ const descriptionSize = height*.3;
4539
+ const pos = vec2(x + medalDisplayIconSize + 2*gap.x, y + gap.y*2 + nameSize/2);
4540
+ const textWidth = width - medalDisplayIconSize - 3*gap.x;
4541
+ drawTextScreen(this.name, pos, nameSize, new Color(0,0,0), 0, undefined, 'left', undefined, textWidth);
4542
+
4543
+ // draw the description
4544
+ pos.y = y + height - gap.y*2 - descriptionSize/2;
4545
+ drawTextScreen(this.description, pos, descriptionSize, new Color(0,0,0), 0, undefined, 'left', undefined, textWidth);
4529
4546
  context.restore();
4530
4547
  }
4531
4548
 
4532
4549
  /** Render the icon for a medal
4533
4550
  * @param {Vector2} pos - Screen space position
4534
- * @param {Number} [size=medalDisplayIconSize] - Screen space size
4551
+ * @param {Number} size - Screen space size
4535
4552
  */
4536
- renderIcon(pos, size=medalDisplayIconSize)
4553
+ renderIcon(pos, size)
4537
4554
  {
4538
4555
  // draw the image or icon
4539
4556
  if (this.image)
@@ -4570,7 +4587,7 @@ let glCanvas;
4570
4587
  let glContext;
4571
4588
 
4572
4589
  /** Should webgl be setup with anti-aliasing? must be set before calling engineInit
4573
- * @type {Boolean}
4590
+ * @type {boolean}
4574
4591
  * @memberof WebGL */
4575
4592
  let glAntialias = true;
4576
4593
 
@@ -4793,7 +4810,7 @@ function glFlush()
4793
4810
 
4794
4811
  /** Draw any sprites still in the buffer and copy to main canvas
4795
4812
  * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} context
4796
- * @param {Boolean} [forceDraw]
4813
+ * @param {boolean} [forceDraw]
4797
4814
  * @memberof WebGL */
4798
4815
  function glCopyToContext(context, forceDraw=false)
4799
4816
  {
@@ -4807,7 +4824,7 @@ function glCopyToContext(context, forceDraw=false)
4807
4824
  }
4808
4825
 
4809
4826
  /** Set anti-aliasing for webgl canvas
4810
- * @param {Boolean} [antialias]
4827
+ * @param {boolean} [antialias]
4811
4828
  * @memberof WebGL */
4812
4829
  function glSetAntialias(antialias=true)
4813
4830
  {
@@ -4872,61 +4889,62 @@ function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba, rgbaAdd
4872
4889
 
4873
4890
 
4874
4891
  /** Name of engine
4875
- * @type {String}
4892
+ * @type {string}
4876
4893
  * @default
4877
4894
  * @memberof Engine */
4878
4895
  const engineName = 'LittleJS';
4879
4896
 
4880
4897
  /** Version of engine
4881
- * @type {String}
4898
+ * @type {string}
4882
4899
  * @default
4883
4900
  * @memberof Engine */
4884
- const engineVersion = '1.11.9';
4901
+ const engineVersion = '1.11.13';
4885
4902
 
4886
4903
  /** Frames per second to update
4887
- * @type {Number}
4904
+ * @type {number}
4888
4905
  * @default
4889
4906
  * @memberof Engine */
4890
4907
  const frameRate = 60;
4891
4908
 
4892
4909
  /** How many seconds each frame lasts, engine uses a fixed time step
4893
- * @type {Number}
4910
+ * @type {number}
4894
4911
  * @default 1/60
4895
4912
  * @memberof Engine */
4896
4913
  const timeDelta = 1/frameRate;
4897
4914
 
4898
4915
  /** Array containing all engine objects
4899
- * @type {Array}
4916
+ * @type {Array<EngineObject>}
4900
4917
  * @memberof Engine */
4901
4918
  let engineObjects = [];
4902
4919
 
4903
4920
  /** Array with only objects set to collide with other objects this frame (for optimization)
4904
- * @type {Array}
4921
+ * @type {Array<EngineObject>}
4905
4922
  * @memberof Engine */
4906
4923
  let engineObjectsCollide = [];
4907
4924
 
4908
4925
  /** Current update frame, used to calculate time
4909
- * @type {Number}
4926
+ * @type {number}
4910
4927
  * @memberof Engine */
4911
4928
  let frame = 0;
4912
4929
 
4913
4930
  /** Current engine time since start in seconds
4914
- * @type {Number}
4931
+ * @type {number}
4915
4932
  * @memberof Engine */
4916
4933
  let time = 0;
4917
4934
 
4918
4935
  /** Actual clock time since start in seconds (not affected by pause or frame rate clamping)
4919
- * @type {Number}
4936
+ * @type {number}
4920
4937
  * @memberof Engine */
4921
4938
  let timeReal = 0;
4922
4939
 
4923
4940
  /** Is the game paused? Causes time and objects to not be updated
4924
- * @type {Boolean}
4941
+ * @type {boolean}
4925
4942
  * @default false
4926
4943
  * @memberof Engine */
4927
4944
  let paused = false;
4945
+
4928
4946
  /** Set if game is paused
4929
- * @param {Boolean} isPaused
4947
+ * @param {boolean} isPaused
4930
4948
  * @memberof Engine */
4931
4949
  function setPaused(isPaused) { paused = isPaused; }
4932
4950
 
@@ -4959,7 +4977,7 @@ function engineAddPlugin(updateFunction, renderFunction)
4959
4977
  * @param {Function} gameUpdatePost - Called after physics and objects are updated, even when paused
4960
4978
  * @param {Function} gameRender - Called before objects are rendered, for drawing the background
4961
4979
  * @param {Function} gameRenderPost - Called after objects are rendered, useful for drawing UI
4962
- * @param {Array} [imageSources=[]] - List of images to load
4980
+ * @param {Array<string>} [imageSources=[]] - List of images to load
4963
4981
  * @param {HTMLElement} [rootElement] - Root element to attach to, the document body by default
4964
4982
  * @memberof Engine */
4965
4983
  function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, imageSources=[], rootElement=document.body)
@@ -5255,9 +5273,9 @@ function engineObjectsDestroy()
5255
5273
 
5256
5274
  /** Collects all object within a given area
5257
5275
  * @param {Vector2} [pos] - Center of test area, or undefined for all objects
5258
- * @param {Number|Vector2} [size] - Radius of circle if float, rectangle size if Vector2
5259
- * @param {Array} [objects=engineObjects] - List of objects to check
5260
- * @return {Array} - List of collected objects
5276
+ * @param {Vector2|number} [size] - Radius of circle if float, rectangle size if Vector2
5277
+ * @param {Array<EngineObject>} [objects=engineObjects] - List of objects to check
5278
+ * @return {Array<EngineObject>} - List of collected objects
5261
5279
  * @memberof Engine */
5262
5280
  function engineObjectsCollect(pos, size, objects=engineObjects)
5263
5281
  {
@@ -5283,9 +5301,9 @@ function engineObjectsCollect(pos, size, objects=engineObjects)
5283
5301
 
5284
5302
  /** Triggers a callback for each object within a given area
5285
5303
  * @param {Vector2} [pos] - Center of test area, or undefined for all objects
5286
- * @param {Number|Vector2} [size] - Radius of circle if float, rectangle size if Vector2
5304
+ * @param {Vector2|number} [size] - Radius of circle if float, rectangle size if Vector2
5287
5305
  * @param {Function} [callbackFunction] - Calls this function on every object that passes the test
5288
- * @param {Array} [objects=engineObjects] - List of objects to check
5306
+ * @param {Array<EngineObject>} [objects=engineObjects] - List of objects to check
5289
5307
  * @memberof Engine */
5290
5308
  function engineObjectsCallback(pos, size, callbackFunction, objects=engineObjects)
5291
5309
  { engineObjectsCollect(pos, size, objects).forEach(o => callbackFunction(o)); }
@@ -5293,8 +5311,8 @@ function engineObjectsCallback(pos, size, callbackFunction, objects=engineObject
5293
5311
  /** Return a list of objects intersecting a ray
5294
5312
  * @param {Vector2} start
5295
5313
  * @param {Vector2} end
5296
- * @param {Array} [objects=engineObjects] - List of objects to check
5297
- * @return {Array} - List of objects hit
5314
+ * @param {Array<EngineObject>} [objects=engineObjects] - List of objects to check
5315
+ * @return {Array<EngineObject>} - List of objects hit
5298
5316
  * @memberof Engine */
5299
5317
  function engineObjectsRaycast(start, end, objects=engineObjects)
5300
5318
  {