littlejsengine 1.11.8 → 1.11.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/littlejs.d.ts +496 -493
- package/dist/littlejs.esm.js +533 -522
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +531 -520
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +487 -479
- package/examples/index.html +8 -2
- package/examples/module/game.js +2 -2
- package/examples/shorts/base.html +1 -1
- package/examples/starter/game.js +8 -1
- package/examples/typescript/build/dist/littlejs.esm.js +4834 -0
- package/examples/typescript/build/examples/typescript/build.js +24 -0
- package/examples/typescript/build/examples/typescript/game.js +102 -0
- package/examples/typescript/build.bat +5 -0
- package/examples/typescript/build.js +33 -0
- package/examples/typescript/game.js +102 -0
- package/examples/typescript/game.ts +134 -0
- package/examples/typescript/index.html +10 -0
- package/examples/typescript/tiles.png +0 -0
- package/examples/typescript/tsconfig.json +8 -0
- package/package.json +1 -1
- package/plugins/newgrounds.js +38 -34
- package/plugins/postProcess.js +18 -4
- package/plugins/uiSystem.js +196 -30
- package/reference.md +3 -3
- package/src/engine.js +21 -20
- package/src/engineAudio.js +59 -59
- package/src/engineDebug.js +44 -41
- package/src/engineDraw.js +58 -58
- package/src/engineExport.js +2 -2
- package/src/engineInput.js +30 -30
- package/src/engineMedals.js +1 -1
- package/src/engineObject.js +42 -37
- package/src/engineParticles.js +10 -10
- package/src/engineSettings.js +74 -72
- package/src/engineTileLayer.js +21 -21
- package/src/engineUtilities.js +168 -168
- package/src/engineWebGL.js +3 -3
package/dist/littlejs.release.js
CHANGED
|
@@ -51,112 +51,112 @@ function debugSaveDataURL(){}
|
|
|
51
51
|
|
|
52
52
|
|
|
53
53
|
/** A shortcut to get Math.PI
|
|
54
|
-
* @type {
|
|
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 {
|
|
61
|
-
* @return {
|
|
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 {
|
|
67
|
-
* @param {
|
|
68
|
-
* @return {
|
|
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 {
|
|
74
|
-
* @param {
|
|
75
|
-
* @return {
|
|
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 {
|
|
81
|
-
* @return {
|
|
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 {
|
|
87
|
-
* @param {
|
|
88
|
-
* @return {
|
|
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 {
|
|
94
|
-
* @param {
|
|
95
|
-
* @param {
|
|
96
|
-
* @return {
|
|
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 {
|
|
102
|
-
* @param {
|
|
103
|
-
* @param {
|
|
104
|
-
* @return {
|
|
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 {
|
|
111
|
-
* @param {
|
|
112
|
-
* @param {
|
|
113
|
-
* @return {
|
|
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 {
|
|
119
|
-
* @param {
|
|
120
|
-
* @param {
|
|
121
|
-
* @returns {
|
|
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 {
|
|
128
|
-
* @param {
|
|
129
|
-
* @param {
|
|
130
|
-
* @param {
|
|
131
|
-
* @returns {
|
|
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 {
|
|
138
|
-
* @param {
|
|
139
|
-
* @returns {
|
|
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 {
|
|
145
|
-
* @param {
|
|
146
|
-
* @param {
|
|
147
|
-
* @returns {
|
|
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 {
|
|
153
|
-
* @return {
|
|
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 {
|
|
159
|
-
* @return {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
219
|
-
* @param {
|
|
220
|
-
* @param {
|
|
221
|
-
* @return {
|
|
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 {
|
|
228
|
-
* @return {
|
|
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 {
|
|
239
|
-
* @param {
|
|
240
|
-
* @return {
|
|
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 {
|
|
247
|
-
* @param {
|
|
248
|
-
* @return {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
265
|
-
* @param {
|
|
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 {
|
|
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,34 +295,34 @@ 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 {
|
|
298
|
+
* @param {number} seed - Starting seed */
|
|
299
299
|
constructor(seed)
|
|
300
300
|
{
|
|
301
|
-
/** @property {
|
|
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 {
|
|
307
|
-
* @param {
|
|
308
|
-
* @return {
|
|
306
|
+
* @param {number} [valueA]
|
|
307
|
+
* @param {number} [valueB]
|
|
308
|
+
* @return {number} */
|
|
309
309
|
float(valueA=1, valueB=0)
|
|
310
310
|
{
|
|
311
311
|
// xorshift algorithm
|
|
312
312
|
this.seed ^= this.seed << 13;
|
|
313
313
|
this.seed ^= this.seed >>> 17;
|
|
314
314
|
this.seed ^= this.seed << 5;
|
|
315
|
-
return valueB + (valueA - valueB) *
|
|
315
|
+
return valueB + (valueA - valueB) * ((this.seed >>> 0) / 2**32);
|
|
316
316
|
}
|
|
317
317
|
|
|
318
318
|
/** Returns a floored seeded random value the two values passed in
|
|
319
|
-
* @param {
|
|
320
|
-
* @param {
|
|
321
|
-
* @return {
|
|
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 {
|
|
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 {
|
|
334
|
-
* @param {
|
|
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 {
|
|
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 {
|
|
371
|
-
* @param {
|
|
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 {
|
|
374
|
+
/** @property {number} - X axis location */
|
|
375
375
|
this.x = x;
|
|
376
|
-
/** @property {
|
|
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 {
|
|
383
|
-
* @param {
|
|
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 {
|
|
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 {
|
|
443
|
+
* @return {number} */
|
|
444
444
|
length() { return this.lengthSquared()**.5; }
|
|
445
445
|
|
|
446
446
|
/** Returns the length of this vector squared
|
|
447
|
-
* @return {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
488
|
+
* @return {number} */
|
|
489
489
|
dot(v)
|
|
490
490
|
{
|
|
491
491
|
ASSERT(isVector2(v));
|
|
@@ -494,20 +494,20 @@ 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 {
|
|
497
|
+
* @return {number} */
|
|
498
498
|
cross(v)
|
|
499
499
|
{
|
|
500
500
|
ASSERT(isVector2(v));
|
|
501
501
|
return this.x*v.y - this.y*v.x;
|
|
502
502
|
}
|
|
503
503
|
|
|
504
|
-
/** Returns the angle of this vector, up is angle 0
|
|
505
|
-
* @return {
|
|
504
|
+
/** Returns the clockwise angle of this vector, up is angle 0
|
|
505
|
+
* @return {number} */
|
|
506
506
|
angle() { return Math.atan2(this.x, this.y); }
|
|
507
507
|
|
|
508
|
-
/** Sets this vector with angle and length passed in
|
|
509
|
-
* @param {
|
|
510
|
-
* @param {
|
|
508
|
+
/** Sets this vector with clockwise angle and length passed in
|
|
509
|
+
* @param {number} [angle]
|
|
510
|
+
* @param {number} [length]
|
|
511
511
|
* @return {Vector2} */
|
|
512
512
|
setAngle(angle=0, length=1)
|
|
513
513
|
{
|
|
@@ -516,18 +516,18 @@ class Vector2
|
|
|
516
516
|
return this;
|
|
517
517
|
}
|
|
518
518
|
|
|
519
|
-
/** Returns copy of this vector rotated by the angle passed in
|
|
520
|
-
* @param {
|
|
519
|
+
/** Returns copy of this vector rotated by the clockwise angle passed in
|
|
520
|
+
* @param {number} angle
|
|
521
521
|
* @return {Vector2} */
|
|
522
522
|
rotate(angle)
|
|
523
523
|
{
|
|
524
|
-
const c = Math.cos(angle), s = Math.sin(angle);
|
|
525
|
-
return new Vector2(this.x*c
|
|
524
|
+
const c = Math.cos(-angle), s = Math.sin(-angle);
|
|
525
|
+
return new Vector2(this.x*c - this.y*s, this.x*s + this.y*c);
|
|
526
526
|
}
|
|
527
527
|
|
|
528
528
|
/** Set the integer direction of this vector, corresponding to multiples of 90 degree rotation (0-3)
|
|
529
|
-
* @param {
|
|
530
|
-
* @param {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
577
|
-
* @return {
|
|
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 {
|
|
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 {
|
|
598
|
-
* @param {
|
|
599
|
-
* @param {
|
|
600
|
-
* @param {
|
|
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 {
|
|
609
|
-
* @param {
|
|
610
|
-
* @param {
|
|
611
|
-
* @param {
|
|
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 {
|
|
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 {
|
|
638
|
-
* @param {
|
|
639
|
-
* @param {
|
|
640
|
-
* @param {
|
|
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 {
|
|
643
|
+
/** @property {number} - Red */
|
|
644
644
|
this.r = r;
|
|
645
|
-
/** @property {
|
|
645
|
+
/** @property {number} - Green */
|
|
646
646
|
this.g = g;
|
|
647
|
-
/** @property {
|
|
647
|
+
/** @property {number} - Blue */
|
|
648
648
|
this.b = b;
|
|
649
|
-
/** @property {
|
|
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 {
|
|
656
|
-
* @param {
|
|
657
|
-
* @param {
|
|
658
|
-
* @param {
|
|
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 {
|
|
712
|
-
* @param {
|
|
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 {
|
|
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 {
|
|
733
|
-
* @param {
|
|
734
|
-
* @param {
|
|
735
|
-
* @param {
|
|
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 {
|
|
784
|
-
* @param {
|
|
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 {
|
|
799
|
-
* @return {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
847
|
+
* @return {boolean} */
|
|
848
848
|
isValid()
|
|
849
849
|
{
|
|
850
850
|
return typeof this.r == 'number' && !isNaN(this.r)
|
|
@@ -857,57 +857,57 @@ class Color
|
|
|
857
857
|
///////////////////////////////////////////////////////////////////////////////
|
|
858
858
|
// default colors
|
|
859
859
|
|
|
860
|
-
/** Color - White
|
|
860
|
+
/** Color - White #ffffff
|
|
861
861
|
* @type {Color}
|
|
862
862
|
* @memberof Utilities */
|
|
863
|
-
const WHITE = rgb();
|
|
863
|
+
const WHITE = rgb();
|
|
864
864
|
|
|
865
|
-
/** Color - Black
|
|
865
|
+
/** Color - Black #000000
|
|
866
866
|
* @type {Color}
|
|
867
867
|
* @memberof Utilities */
|
|
868
868
|
const BLACK = rgb(0,0,0);
|
|
869
869
|
|
|
870
|
-
/** Color - Gray
|
|
870
|
+
/** Color - Gray #808080
|
|
871
871
|
* @type {Color}
|
|
872
872
|
* @memberof Utilities */
|
|
873
873
|
const GRAY = rgb(.5,.5,.5);
|
|
874
874
|
|
|
875
|
-
/** Color - Red
|
|
875
|
+
/** Color - Red #ff0000
|
|
876
876
|
* @type {Color}
|
|
877
877
|
* @memberof Utilities */
|
|
878
878
|
const RED = rgb(1,0,0);
|
|
879
879
|
|
|
880
|
-
/** Color - Orange
|
|
880
|
+
/** Color - Orange #ff8000
|
|
881
881
|
* @type {Color}
|
|
882
882
|
* @memberof Utilities */
|
|
883
883
|
const ORANGE = rgb(1,.5,0);
|
|
884
884
|
|
|
885
|
-
/** Color - Yellow
|
|
885
|
+
/** Color - Yellow #ffff00
|
|
886
886
|
* @type {Color}
|
|
887
887
|
* @memberof Utilities */
|
|
888
888
|
const YELLOW = rgb(1,1,0);
|
|
889
889
|
|
|
890
|
-
/** Color - Green
|
|
890
|
+
/** Color - Green #00ff00
|
|
891
891
|
* @type {Color}
|
|
892
892
|
* @memberof Utilities */
|
|
893
893
|
const GREEN = rgb(0,1,0);
|
|
894
894
|
|
|
895
|
-
/** Color - Cyan
|
|
895
|
+
/** Color - Cyan #00ffff
|
|
896
896
|
* @type {Color}
|
|
897
897
|
* @memberof Utilities */
|
|
898
898
|
const CYAN = rgb(0,1,1);
|
|
899
899
|
|
|
900
|
-
/** Color - Blue
|
|
900
|
+
/** Color - Blue #0000ff
|
|
901
901
|
* @type {Color}
|
|
902
902
|
* @memberof Utilities */
|
|
903
903
|
const BLUE = rgb(0,0,1);
|
|
904
904
|
|
|
905
|
-
/** Color - Purple
|
|
905
|
+
/** Color - Purple #8000ff
|
|
906
906
|
* @type {Color}
|
|
907
907
|
* @memberof Utilities */
|
|
908
908
|
const PURPLE = rgb(.5,0,1);
|
|
909
909
|
|
|
910
|
-
/** Color - Magenta
|
|
910
|
+
/** Color - Magenta #ff00ff
|
|
911
911
|
* @type {Color}
|
|
912
912
|
* @memberof Utilities */
|
|
913
913
|
const MAGENTA = rgb(1,0,1);
|
|
@@ -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 {
|
|
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 {
|
|
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 {
|
|
940
|
+
* @return {boolean} */
|
|
941
941
|
isSet() { return this.time != undefined; }
|
|
942
942
|
|
|
943
943
|
/** Returns true if set and has not elapsed
|
|
944
|
-
* @return {
|
|
944
|
+
* @return {boolean} */
|
|
945
945
|
active() { return time < this.time; }
|
|
946
946
|
|
|
947
947
|
/** Returns true if set and elapsed
|
|
948
|
-
* @return {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
985
|
+
* @type {number}
|
|
986
986
|
* @default
|
|
987
987
|
* @memberof Settings */
|
|
988
988
|
let cameraScale = 32;
|
|
@@ -1004,31 +1004,33 @@ 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
|
-
*
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
1033
|
+
* @type {boolean}
|
|
1032
1034
|
* @default
|
|
1033
1035
|
* @memberof Settings */
|
|
1034
1036
|
let headlessMode = false;
|
|
@@ -1037,13 +1039,13 @@ let headlessMode = false;
|
|
|
1037
1039
|
// WebGL settings
|
|
1038
1040
|
|
|
1039
1041
|
/** Enable webgl rendering, webgl can be disabled and removed from build (with some features disabled)
|
|
1040
|
-
* @type {
|
|
1042
|
+
* @type {boolean}
|
|
1041
1043
|
* @default
|
|
1042
1044
|
* @memberof Settings */
|
|
1043
1045
|
let glEnable = true;
|
|
1044
1046
|
|
|
1045
1047
|
/** Fixes slow rendering in some browsers by not compositing the WebGL canvas
|
|
1046
|
-
* @type {
|
|
1048
|
+
* @type {boolean}
|
|
1047
1049
|
* @default
|
|
1048
1050
|
* @memberof Settings */
|
|
1049
1051
|
let glOverlay = true;
|
|
@@ -1058,7 +1060,7 @@ let glOverlay = true;
|
|
|
1058
1060
|
let tileSizeDefault = vec2(16);
|
|
1059
1061
|
|
|
1060
1062
|
/** How many pixels smaller to draw tiles to prevent bleeding from neighbors
|
|
1061
|
-
* @type {
|
|
1063
|
+
* @type {number}
|
|
1062
1064
|
* @default
|
|
1063
1065
|
* @memberof Settings */
|
|
1064
1066
|
let tileFixBleedScale = 0;
|
|
@@ -1067,55 +1069,55 @@ let tileFixBleedScale = 0;
|
|
|
1067
1069
|
// Object settings
|
|
1068
1070
|
|
|
1069
1071
|
/** Enable physics solver for collisions between objects
|
|
1070
|
-
* @type {
|
|
1072
|
+
* @type {boolean}
|
|
1071
1073
|
* @default
|
|
1072
1074
|
* @memberof Settings */
|
|
1073
1075
|
let enablePhysicsSolver = true;
|
|
1074
1076
|
|
|
1075
1077
|
/** Default object mass for collision calculations (how heavy objects are)
|
|
1076
|
-
* @type {
|
|
1078
|
+
* @type {number}
|
|
1077
1079
|
* @default
|
|
1078
1080
|
* @memberof Settings */
|
|
1079
1081
|
let objectDefaultMass = 1;
|
|
1080
1082
|
|
|
1081
1083
|
/** How much to slow velocity by each frame (0-1)
|
|
1082
|
-
* @type {
|
|
1084
|
+
* @type {number}
|
|
1083
1085
|
* @default
|
|
1084
1086
|
* @memberof Settings */
|
|
1085
1087
|
let objectDefaultDamping = 1;
|
|
1086
1088
|
|
|
1087
1089
|
/** How much to slow angular velocity each frame (0-1)
|
|
1088
|
-
* @type {
|
|
1090
|
+
* @type {number}
|
|
1089
1091
|
* @default
|
|
1090
1092
|
* @memberof Settings */
|
|
1091
1093
|
let objectDefaultAngleDamping = 1;
|
|
1092
1094
|
|
|
1093
1095
|
/** How much to bounce when a collision occurs (0-1)
|
|
1094
|
-
* @type {
|
|
1096
|
+
* @type {number}
|
|
1095
1097
|
* @default
|
|
1096
1098
|
* @memberof Settings */
|
|
1097
1099
|
let objectDefaultElasticity = 0;
|
|
1098
1100
|
|
|
1099
1101
|
/** How much to slow when touching (0-1)
|
|
1100
|
-
* @type {
|
|
1102
|
+
* @type {number}
|
|
1101
1103
|
* @default
|
|
1102
1104
|
* @memberof Settings */
|
|
1103
1105
|
let objectDefaultFriction = .8;
|
|
1104
1106
|
|
|
1105
1107
|
/** Clamp max speed to avoid fast objects missing collisions
|
|
1106
|
-
* @type {
|
|
1108
|
+
* @type {number}
|
|
1107
1109
|
* @default
|
|
1108
1110
|
* @memberof Settings */
|
|
1109
1111
|
let objectMaxSpeed = 1;
|
|
1110
1112
|
|
|
1111
1113
|
/** How much gravity to apply to objects along the Y axis, negative is down
|
|
1112
|
-
* @type {
|
|
1114
|
+
* @type {number}
|
|
1113
1115
|
* @default
|
|
1114
1116
|
* @memberof Settings */
|
|
1115
1117
|
let gravity = 0;
|
|
1116
1118
|
|
|
1117
1119
|
/** Scales emit rate of particles, useful for low graphics mode (0 disables particle emitters)
|
|
1118
|
-
* @type {
|
|
1120
|
+
* @type {number}
|
|
1119
1121
|
* @default
|
|
1120
1122
|
* @memberof Settings */
|
|
1121
1123
|
let particleEmitRateScale = 1;
|
|
@@ -1124,26 +1126,26 @@ let particleEmitRateScale = 1;
|
|
|
1124
1126
|
// Input settings
|
|
1125
1127
|
|
|
1126
1128
|
/** Should gamepads be allowed
|
|
1127
|
-
* @type {
|
|
1129
|
+
* @type {boolean}
|
|
1128
1130
|
* @default
|
|
1129
1131
|
* @memberof Settings */
|
|
1130
1132
|
let gamepadsEnable = true;
|
|
1131
1133
|
|
|
1132
1134
|
/** If true, the dpad input is also routed to the left analog stick (for better accessability)
|
|
1133
|
-
* @type {
|
|
1135
|
+
* @type {boolean}
|
|
1134
1136
|
* @default
|
|
1135
1137
|
* @memberof Settings */
|
|
1136
1138
|
let gamepadDirectionEmulateStick = true;
|
|
1137
1139
|
|
|
1138
1140
|
/** If true the WASD keys are also routed to the direction keys (for better accessability)
|
|
1139
|
-
* @type {
|
|
1141
|
+
* @type {boolean}
|
|
1140
1142
|
* @default
|
|
1141
1143
|
* @memberof Settings */
|
|
1142
1144
|
let inputWASDEmulateDirection = true;
|
|
1143
1145
|
|
|
1144
1146
|
/** True if touch input is enabled for mobile devices
|
|
1145
1147
|
* - Touch events will be routed to mouse events
|
|
1146
|
-
* @type {
|
|
1148
|
+
* @type {boolean}
|
|
1147
1149
|
* @default
|
|
1148
1150
|
* @memberof Settings */
|
|
1149
1151
|
let touchInputEnable = true;
|
|
@@ -1151,31 +1153,31 @@ let touchInputEnable = true;
|
|
|
1151
1153
|
/** True if touch gamepad should appear on mobile devices
|
|
1152
1154
|
* - Supports left analog stick, 4 face buttons and start button (button 9)
|
|
1153
1155
|
* - Must be set by end of gameInit to be activated
|
|
1154
|
-
* @type {
|
|
1156
|
+
* @type {boolean}
|
|
1155
1157
|
* @default
|
|
1156
1158
|
* @memberof Settings */
|
|
1157
1159
|
let touchGamepadEnable = false;
|
|
1158
1160
|
|
|
1159
1161
|
/** True if touch gamepad should be analog stick or false to use if 8 way dpad
|
|
1160
|
-
* @type {
|
|
1162
|
+
* @type {boolean}
|
|
1161
1163
|
* @default
|
|
1162
1164
|
* @memberof Settings */
|
|
1163
1165
|
let touchGamepadAnalog = true;
|
|
1164
1166
|
|
|
1165
1167
|
/** Size of virtual gamepad for touch devices in pixels
|
|
1166
|
-
* @type {
|
|
1168
|
+
* @type {number}
|
|
1167
1169
|
* @default
|
|
1168
1170
|
* @memberof Settings */
|
|
1169
1171
|
let touchGamepadSize = 99;
|
|
1170
1172
|
|
|
1171
1173
|
/** Transparency of touch gamepad overlay
|
|
1172
|
-
* @type {
|
|
1174
|
+
* @type {number}
|
|
1173
1175
|
* @default
|
|
1174
1176
|
* @memberof Settings */
|
|
1175
1177
|
let touchGamepadAlpha = .3;
|
|
1176
1178
|
|
|
1177
1179
|
/** Allow vibration hardware if it exists
|
|
1178
|
-
* @type {
|
|
1180
|
+
* @type {boolean}
|
|
1179
1181
|
* @default
|
|
1180
1182
|
* @memberof Settings */
|
|
1181
1183
|
let vibrateEnable = true;
|
|
@@ -1184,25 +1186,25 @@ let vibrateEnable = true;
|
|
|
1184
1186
|
// Audio settings
|
|
1185
1187
|
|
|
1186
1188
|
/** All audio code can be disabled and removed from build
|
|
1187
|
-
* @type {
|
|
1189
|
+
* @type {boolean}
|
|
1188
1190
|
* @default
|
|
1189
1191
|
* @memberof Settings */
|
|
1190
1192
|
let soundEnable = true;
|
|
1191
1193
|
|
|
1192
1194
|
/** Volume scale to apply to all sound, music and speech
|
|
1193
|
-
* @type {
|
|
1195
|
+
* @type {number}
|
|
1194
1196
|
* @default
|
|
1195
1197
|
* @memberof Settings */
|
|
1196
1198
|
let soundVolume = .3;
|
|
1197
1199
|
|
|
1198
1200
|
/** Default range where sound no longer plays
|
|
1199
|
-
* @type {
|
|
1201
|
+
* @type {number}
|
|
1200
1202
|
* @default
|
|
1201
1203
|
* @memberof Settings */
|
|
1202
1204
|
let soundDefaultRange = 40;
|
|
1203
1205
|
|
|
1204
1206
|
/** Default range percent to start tapering off sound (0-1)
|
|
1205
|
-
* @type {
|
|
1207
|
+
* @type {number}
|
|
1206
1208
|
* @default
|
|
1207
1209
|
* @memberof Settings */
|
|
1208
1210
|
let soundDefaultTaper = .7;
|
|
@@ -1211,13 +1213,13 @@ let soundDefaultTaper = .7;
|
|
|
1211
1213
|
// Medals settings
|
|
1212
1214
|
|
|
1213
1215
|
/** How long to show medals for in seconds
|
|
1214
|
-
* @type {
|
|
1216
|
+
* @type {number}
|
|
1215
1217
|
* @default
|
|
1216
1218
|
* @memberof Settings */
|
|
1217
1219
|
let medalDisplayTime = 5;
|
|
1218
1220
|
|
|
1219
1221
|
/** How quickly to slide on/off medals in seconds
|
|
1220
|
-
* @type {
|
|
1222
|
+
* @type {number}
|
|
1221
1223
|
* @default
|
|
1222
1224
|
* @memberof Settings */
|
|
1223
1225
|
let medalDisplaySlideTime = .5;
|
|
@@ -1229,13 +1231,13 @@ let medalDisplaySlideTime = .5;
|
|
|
1229
1231
|
let medalDisplaySize = vec2(640, 80);
|
|
1230
1232
|
|
|
1231
1233
|
/** Size of icon in medal display
|
|
1232
|
-
* @type {
|
|
1234
|
+
* @type {number}
|
|
1233
1235
|
* @default
|
|
1234
1236
|
* @memberof Settings */
|
|
1235
1237
|
let medalDisplayIconSize = 50;
|
|
1236
1238
|
|
|
1237
1239
|
/** Set to stop medals from being unlockable (like if cheats are enabled)
|
|
1238
|
-
* @type {
|
|
1240
|
+
* @type {boolean}
|
|
1239
1241
|
* @default
|
|
1240
1242
|
* @memberof Settings */
|
|
1241
1243
|
let medalsPreventUnlock = false;
|
|
@@ -1249,7 +1251,7 @@ let medalsPreventUnlock = false;
|
|
|
1249
1251
|
function setCameraPos(pos) { cameraPos = pos; }
|
|
1250
1252
|
|
|
1251
1253
|
/** Set scale of camera in world space
|
|
1252
|
-
* @param {
|
|
1254
|
+
* @param {number} scale
|
|
1253
1255
|
* @memberof Settings */
|
|
1254
1256
|
function setCameraScale(scale) { cameraScale = scale; }
|
|
1255
1257
|
|
|
@@ -1264,37 +1266,37 @@ function setCanvasMaxSize(size) { canvasMaxSize = size; }
|
|
|
1264
1266
|
function setCanvasFixedSize(size) { canvasFixedSize = size; }
|
|
1265
1267
|
|
|
1266
1268
|
/** Use nearest neighbor scaling algorithm for canvas for more pixelated look
|
|
1267
|
-
* @param {
|
|
1269
|
+
* @param {boolean} pixelated
|
|
1268
1270
|
* @memberof Settings */
|
|
1269
1271
|
function setCanvasPixelated(pixelated) { canvasPixelated = pixelated; }
|
|
1270
1272
|
|
|
1271
1273
|
/** Disables texture filtering for crisper pixel art
|
|
1272
|
-
* @param {
|
|
1274
|
+
* @param {boolean} pixelated
|
|
1273
1275
|
* @memberof Settings */
|
|
1274
1276
|
function setTilesPixelated(pixelated) { tilesPixelated = pixelated; }
|
|
1275
1277
|
|
|
1276
1278
|
/** Set default font used for text rendering
|
|
1277
|
-
* @param {
|
|
1279
|
+
* @param {string} font
|
|
1278
1280
|
* @memberof Settings */
|
|
1279
1281
|
function setFontDefault(font) { fontDefault = font; }
|
|
1280
1282
|
|
|
1281
1283
|
/** Set if the LittleJS splash screen be shown on startup
|
|
1282
|
-
* @param {
|
|
1284
|
+
* @param {boolean} show
|
|
1283
1285
|
* @memberof Settings */
|
|
1284
1286
|
function setShowSplashScreen(show) { showSplashScreen = show; }
|
|
1285
1287
|
|
|
1286
1288
|
/** Set to disable rendering, audio, and input for servers
|
|
1287
|
-
* @param {
|
|
1289
|
+
* @param {boolean} headless
|
|
1288
1290
|
* @memberof Settings */
|
|
1289
1291
|
function setHeadlessMode(headless) { headlessMode = headless; }
|
|
1290
1292
|
|
|
1291
1293
|
/** Set if webgl rendering is enabled
|
|
1292
|
-
* @param {
|
|
1294
|
+
* @param {boolean} enable
|
|
1293
1295
|
* @memberof Settings */
|
|
1294
1296
|
function setGlEnable(enable) { glEnable = enable; }
|
|
1295
1297
|
|
|
1296
1298
|
/** Set to not composite the WebGL canvas
|
|
1297
|
-
* @param {
|
|
1299
|
+
* @param {boolean} overlay
|
|
1298
1300
|
* @memberof Settings */
|
|
1299
1301
|
function setGlOverlay(overlay) { glOverlay = overlay; }
|
|
1300
1302
|
|
|
@@ -1304,107 +1306,107 @@ function setGlOverlay(overlay) { glOverlay = overlay; }
|
|
|
1304
1306
|
function setTileSizeDefault(size) { tileSizeDefault = size; }
|
|
1305
1307
|
|
|
1306
1308
|
/** Set to prevent tile bleeding from neighbors in pixels
|
|
1307
|
-
* @param {
|
|
1309
|
+
* @param {number} scale
|
|
1308
1310
|
* @memberof Settings */
|
|
1309
1311
|
function setTileFixBleedScale(scale) { tileFixBleedScale = scale; }
|
|
1310
1312
|
|
|
1311
1313
|
/** Set if collisions between objects are enabled
|
|
1312
|
-
* @param {
|
|
1314
|
+
* @param {boolean} enable
|
|
1313
1315
|
* @memberof Settings */
|
|
1314
1316
|
function setEnablePhysicsSolver(enable) { enablePhysicsSolver = enable; }
|
|
1315
1317
|
|
|
1316
1318
|
/** Set default object mass for collision calculations
|
|
1317
|
-
* @param {
|
|
1319
|
+
* @param {number} mass
|
|
1318
1320
|
* @memberof Settings */
|
|
1319
1321
|
function setObjectDefaultMass(mass) { objectDefaultMass = mass; }
|
|
1320
1322
|
|
|
1321
1323
|
/** Set how much to slow velocity by each frame
|
|
1322
|
-
* @param {
|
|
1324
|
+
* @param {number} damp
|
|
1323
1325
|
* @memberof Settings */
|
|
1324
1326
|
function setObjectDefaultDamping(damp) { objectDefaultDamping = damp; }
|
|
1325
1327
|
|
|
1326
1328
|
/** Set how much to slow angular velocity each frame
|
|
1327
|
-
* @param {
|
|
1329
|
+
* @param {number} damp
|
|
1328
1330
|
* @memberof Settings */
|
|
1329
1331
|
function setObjectDefaultAngleDamping(damp) { objectDefaultAngleDamping = damp; }
|
|
1330
1332
|
|
|
1331
1333
|
/** Set how much to bounce when a collision occur
|
|
1332
|
-
* @param {
|
|
1334
|
+
* @param {number} elasticity
|
|
1333
1335
|
* @memberof Settings */
|
|
1334
1336
|
function setObjectDefaultElasticity(elasticity) { objectDefaultElasticity = elasticity; }
|
|
1335
1337
|
|
|
1336
1338
|
/** Set how much to slow when touching
|
|
1337
|
-
* @param {
|
|
1339
|
+
* @param {number} friction
|
|
1338
1340
|
* @memberof Settings */
|
|
1339
1341
|
function setObjectDefaultFriction(friction) { objectDefaultFriction = friction; }
|
|
1340
1342
|
|
|
1341
1343
|
/** Set max speed to avoid fast objects missing collisions
|
|
1342
|
-
* @param {
|
|
1344
|
+
* @param {number} speed
|
|
1343
1345
|
* @memberof Settings */
|
|
1344
1346
|
function setObjectMaxSpeed(speed) { objectMaxSpeed = speed; }
|
|
1345
1347
|
|
|
1346
1348
|
/** Set how much gravity to apply to objects along the Y axis
|
|
1347
|
-
* @param {
|
|
1349
|
+
* @param {number} newGravity
|
|
1348
1350
|
* @memberof Settings */
|
|
1349
1351
|
function setGravity(newGravity) { gravity = newGravity; }
|
|
1350
1352
|
|
|
1351
1353
|
/** Set to scales emit rate of particles
|
|
1352
|
-
* @param {
|
|
1354
|
+
* @param {number} scale
|
|
1353
1355
|
* @memberof Settings */
|
|
1354
1356
|
function setParticleEmitRateScale(scale) { particleEmitRateScale = scale; }
|
|
1355
1357
|
|
|
1356
1358
|
/** Set if gamepads are enabled
|
|
1357
|
-
* @param {
|
|
1359
|
+
* @param {boolean} enable
|
|
1358
1360
|
* @memberof Settings */
|
|
1359
1361
|
function setGamepadsEnable(enable) { gamepadsEnable = enable; }
|
|
1360
1362
|
|
|
1361
1363
|
/** Set if the dpad input is also routed to the left analog stick
|
|
1362
|
-
* @param {
|
|
1364
|
+
* @param {boolean} enable
|
|
1363
1365
|
* @memberof Settings */
|
|
1364
1366
|
function setGamepadDirectionEmulateStick(enable) { gamepadDirectionEmulateStick = enable; }
|
|
1365
1367
|
|
|
1366
1368
|
/** Set if true the WASD keys are also routed to the direction keys
|
|
1367
|
-
* @param {
|
|
1369
|
+
* @param {boolean} enable
|
|
1368
1370
|
* @memberof Settings */
|
|
1369
1371
|
function setInputWASDEmulateDirection(enable) { inputWASDEmulateDirection = enable; }
|
|
1370
1372
|
|
|
1371
1373
|
/** Set if touch input is allowed
|
|
1372
|
-
* @param {
|
|
1374
|
+
* @param {boolean} enable
|
|
1373
1375
|
* @memberof Settings */
|
|
1374
1376
|
function setTouchInputEnable(enable) { touchInputEnable = enable; }
|
|
1375
1377
|
|
|
1376
1378
|
/** Set if touch gamepad should appear on mobile devices
|
|
1377
|
-
* @param {
|
|
1379
|
+
* @param {boolean} enable
|
|
1378
1380
|
* @memberof Settings */
|
|
1379
1381
|
function setTouchGamepadEnable(enable) { touchGamepadEnable = enable; }
|
|
1380
1382
|
|
|
1381
1383
|
/** Set if touch gamepad should be analog stick or 8 way dpad
|
|
1382
|
-
* @param {
|
|
1384
|
+
* @param {boolean} analog
|
|
1383
1385
|
* @memberof Settings */
|
|
1384
1386
|
function setTouchGamepadAnalog(analog) { touchGamepadAnalog = analog; }
|
|
1385
1387
|
|
|
1386
1388
|
/** Set size of virtual gamepad for touch devices in pixels
|
|
1387
|
-
* @param {
|
|
1389
|
+
* @param {number} size
|
|
1388
1390
|
* @memberof Settings */
|
|
1389
1391
|
function setTouchGamepadSize(size) { touchGamepadSize = size; }
|
|
1390
1392
|
|
|
1391
1393
|
/** Set transparency of touch gamepad overlay
|
|
1392
|
-
* @param {
|
|
1394
|
+
* @param {number} alpha
|
|
1393
1395
|
* @memberof Settings */
|
|
1394
1396
|
function setTouchGamepadAlpha(alpha) { touchGamepadAlpha = alpha; }
|
|
1395
1397
|
|
|
1396
1398
|
/** Set to allow vibration hardware if it exists
|
|
1397
|
-
* @param {
|
|
1399
|
+
* @param {boolean} enable
|
|
1398
1400
|
* @memberof Settings */
|
|
1399
1401
|
function setVibrateEnable(enable) { vibrateEnable = enable; }
|
|
1400
1402
|
|
|
1401
1403
|
/** Set to disable all audio code
|
|
1402
|
-
* @param {
|
|
1404
|
+
* @param {boolean} enable
|
|
1403
1405
|
* @memberof Settings */
|
|
1404
1406
|
function setSoundEnable(enable) { soundEnable = enable; }
|
|
1405
1407
|
|
|
1406
1408
|
/** Set volume scale to apply to all sound, music and speech
|
|
1407
|
-
* @param {
|
|
1409
|
+
* @param {number} volume
|
|
1408
1410
|
* @memberof Settings */
|
|
1409
1411
|
function setSoundVolume(volume)
|
|
1410
1412
|
{
|
|
@@ -1414,22 +1416,22 @@ function setSoundVolume(volume)
|
|
|
1414
1416
|
}
|
|
1415
1417
|
|
|
1416
1418
|
/** Set default range where sound no longer plays
|
|
1417
|
-
* @param {
|
|
1419
|
+
* @param {number} range
|
|
1418
1420
|
* @memberof Settings */
|
|
1419
1421
|
function setSoundDefaultRange(range) { soundDefaultRange = range; }
|
|
1420
1422
|
|
|
1421
1423
|
/** Set default range percent to start tapering off sound
|
|
1422
|
-
* @param {
|
|
1424
|
+
* @param {number} taper
|
|
1423
1425
|
* @memberof Settings */
|
|
1424
1426
|
function setSoundDefaultTaper(taper) { soundDefaultTaper = taper; }
|
|
1425
1427
|
|
|
1426
1428
|
/** Set how long to show medals for in seconds
|
|
1427
|
-
* @param {
|
|
1429
|
+
* @param {number} time
|
|
1428
1430
|
* @memberof Settings */
|
|
1429
1431
|
function setMedalDisplayTime(time) { medalDisplayTime = time; }
|
|
1430
1432
|
|
|
1431
1433
|
/** Set how quickly to slide on/off medals in seconds
|
|
1432
|
-
* @param {
|
|
1434
|
+
* @param {number} time
|
|
1433
1435
|
* @memberof Settings */
|
|
1434
1436
|
function setMedalDisplaySlideTime(time) { medalDisplaySlideTime = time; }
|
|
1435
1437
|
|
|
@@ -1439,22 +1441,22 @@ function setMedalDisplaySlideTime(time) { medalDisplaySlideTime = time; }
|
|
|
1439
1441
|
function setMedalDisplaySize(size) { medalDisplaySize = size; }
|
|
1440
1442
|
|
|
1441
1443
|
/** Set size of icon in medal display
|
|
1442
|
-
* @param {
|
|
1444
|
+
* @param {number} size
|
|
1443
1445
|
* @memberof Settings */
|
|
1444
1446
|
function setMedalDisplayIconSize(size) { medalDisplayIconSize = size; }
|
|
1445
1447
|
|
|
1446
1448
|
/** Set to stop medals from being unlockable
|
|
1447
|
-
* @param {
|
|
1449
|
+
* @param {boolean} preventUnlock
|
|
1448
1450
|
* @memberof Settings */
|
|
1449
1451
|
function setMedalsPreventUnlock(preventUnlock) { medalsPreventUnlock = preventUnlock; }
|
|
1450
1452
|
|
|
1451
1453
|
/** Set if watermark with FPS should be shown
|
|
1452
|
-
* @param {
|
|
1454
|
+
* @param {boolean} show
|
|
1453
1455
|
* @memberof Debug */
|
|
1454
1456
|
function setShowWatermark(show) { showWatermark = show; }
|
|
1455
1457
|
|
|
1456
1458
|
/** Set key code used to toggle debug mode, Esc by default
|
|
1457
|
-
* @param {
|
|
1459
|
+
* @param {string} key
|
|
1458
1460
|
* @memberof Debug */
|
|
1459
1461
|
function setDebugKey(key) { debugKey = key; }
|
|
1460
1462
|
/**
|
|
@@ -1494,9 +1496,9 @@ class EngineObject
|
|
|
1494
1496
|
* @param {Vector2} [pos=(0,0)] - World space position of the object
|
|
1495
1497
|
* @param {Vector2} [size=(1,1)] - World space size of the object
|
|
1496
1498
|
* @param {TileInfo} [tileInfo] - Tile info to render object (undefined is untextured)
|
|
1497
|
-
* @param {
|
|
1499
|
+
* @param {number} [angle] - Angle the object is rotated by
|
|
1498
1500
|
* @param {Color} [color=(1,1,1,1)] - Color to apply to tile when rendered
|
|
1499
|
-
* @param {
|
|
1501
|
+
* @param {number} [renderOrder] - Objects sorted by renderOrder before being rendered
|
|
1500
1502
|
*/
|
|
1501
1503
|
constructor(pos=vec2(), size=vec2(1), tileInfo, angle=0, color=new Color, renderOrder=0)
|
|
1502
1504
|
{
|
|
@@ -1512,57 +1514,59 @@ class EngineObject
|
|
|
1512
1514
|
this.drawSize = undefined;
|
|
1513
1515
|
/** @property {TileInfo} - Tile info to render object (undefined is untextured) */
|
|
1514
1516
|
this.tileInfo = tileInfo;
|
|
1515
|
-
/** @property {
|
|
1517
|
+
/** @property {number} - Angle to rotate the object */
|
|
1516
1518
|
this.angle = angle;
|
|
1517
1519
|
/** @property {Color} - Color to apply when rendered */
|
|
1518
1520
|
this.color = color;
|
|
1519
1521
|
/** @property {Color} - Additive color to apply when rendered */
|
|
1520
1522
|
this.additiveColor = undefined;
|
|
1521
|
-
/** @property {
|
|
1523
|
+
/** @property {boolean} - Should it flip along y axis when rendered */
|
|
1522
1524
|
this.mirror = false;
|
|
1523
1525
|
|
|
1524
1526
|
// physical properties
|
|
1525
|
-
/** @property {
|
|
1527
|
+
/** @property {number} [mass=objectDefaultMass] - How heavy the object is, static if 0 */
|
|
1526
1528
|
this.mass = objectDefaultMass;
|
|
1527
|
-
/** @property {
|
|
1529
|
+
/** @property {number} [damping=objectDefaultDamping] - How much to slow down velocity each frame (0-1) */
|
|
1528
1530
|
this.damping = objectDefaultDamping;
|
|
1529
|
-
/** @property {
|
|
1531
|
+
/** @property {number} [angleDamping=objectDefaultAngleDamping] - How much to slow down rotation each frame (0-1) */
|
|
1530
1532
|
this.angleDamping = objectDefaultAngleDamping;
|
|
1531
|
-
/** @property {
|
|
1533
|
+
/** @property {number} [elasticity=objectDefaultElasticity] - How bouncy the object is when colliding (0-1) */
|
|
1532
1534
|
this.elasticity = objectDefaultElasticity;
|
|
1533
|
-
/** @property {
|
|
1535
|
+
/** @property {number} [friction=objectDefaultFriction] - How much friction to apply when sliding (0-1) */
|
|
1534
1536
|
this.friction = objectDefaultFriction;
|
|
1535
|
-
/** @property {
|
|
1537
|
+
/** @property {number} - How much to scale gravity by for this object */
|
|
1536
1538
|
this.gravityScale = 1;
|
|
1537
|
-
/** @property {
|
|
1539
|
+
/** @property {number} - Objects are sorted by render order */
|
|
1538
1540
|
this.renderOrder = renderOrder;
|
|
1539
1541
|
/** @property {Vector2} - Velocity of the object */
|
|
1540
1542
|
this.velocity = vec2();
|
|
1541
|
-
/** @property {
|
|
1543
|
+
/** @property {number} - Angular velocity of the object */
|
|
1542
1544
|
this.angleVelocity = 0;
|
|
1543
|
-
/** @property {
|
|
1545
|
+
/** @property {number} - Track when object was created */
|
|
1544
1546
|
this.spawnTime = time;
|
|
1545
|
-
/** @property {Array} - List of children of this object */
|
|
1547
|
+
/** @property {Array<EngineObject>} - List of children of this object */
|
|
1546
1548
|
this.children = [];
|
|
1547
|
-
/** @property {
|
|
1549
|
+
/** @property {boolean} - Limit object speed using linear or circular math */
|
|
1548
1550
|
this.clampSpeedLinear = true;
|
|
1551
|
+
/** @property {EngineObject} - Object we are standing on, if any */
|
|
1552
|
+
this.groundObject = undefined;
|
|
1549
1553
|
|
|
1550
1554
|
// parent child system
|
|
1551
1555
|
/** @property {EngineObject} - Parent of object if in local space */
|
|
1552
1556
|
this.parent = undefined;
|
|
1553
1557
|
/** @property {Vector2} - Local position if child */
|
|
1554
1558
|
this.localPos = vec2();
|
|
1555
|
-
/** @property {
|
|
1559
|
+
/** @property {number} - Local angle if child */
|
|
1556
1560
|
this.localAngle = 0;
|
|
1557
1561
|
|
|
1558
1562
|
// collision flags
|
|
1559
|
-
/** @property {
|
|
1563
|
+
/** @property {boolean} - Object collides with the tile collision */
|
|
1560
1564
|
this.collideTiles = false;
|
|
1561
|
-
/** @property {
|
|
1565
|
+
/** @property {boolean} - Object collides with solid objects */
|
|
1562
1566
|
this.collideSolidObjects = false;
|
|
1563
|
-
/** @property {
|
|
1567
|
+
/** @property {boolean} - Object collides with and blocks other objects */
|
|
1564
1568
|
this.isSolid = false;
|
|
1565
|
-
/** @property {
|
|
1569
|
+
/** @property {boolean} - Object collides with raycasts */
|
|
1566
1570
|
this.collideRaycast = false;
|
|
1567
1571
|
|
|
1568
1572
|
// add to list of objects
|
|
@@ -1577,7 +1581,7 @@ class EngineObject
|
|
|
1577
1581
|
{
|
|
1578
1582
|
// copy parent pos/angle
|
|
1579
1583
|
const mirror = parent.getMirrorSign();
|
|
1580
|
-
this.pos = this.localPos.multiply(vec2(mirror,1)).rotate(
|
|
1584
|
+
this.pos = this.localPos.multiply(vec2(mirror,1)).rotate(parent.angle).add(parent.pos);
|
|
1581
1585
|
this.angle = mirror*this.localAngle + parent.angle;
|
|
1582
1586
|
}
|
|
1583
1587
|
|
|
@@ -1632,7 +1636,7 @@ class EngineObject
|
|
|
1632
1636
|
// apply friction in local space of ground object
|
|
1633
1637
|
const groundSpeed = this.groundObject.velocity ? this.groundObject.velocity.x : 0;
|
|
1634
1638
|
this.velocity.x = groundSpeed + (this.velocity.x - groundSpeed) * this.friction;
|
|
1635
|
-
this.groundObject =
|
|
1639
|
+
this.groundObject = undefined;
|
|
1636
1640
|
//debugOverlay && debugPhysics && debugPoint(this.pos.subtract(vec2(0,this.size.y/2)), '#0f0');
|
|
1637
1641
|
}
|
|
1638
1642
|
|
|
@@ -1749,18 +1753,21 @@ class EngineObject
|
|
|
1749
1753
|
// bounce velocity
|
|
1750
1754
|
this.velocity.y *= -this.elasticity;
|
|
1751
1755
|
|
|
1752
|
-
|
|
1753
|
-
if (this.groundObject = wasMovingDown)
|
|
1756
|
+
if (wasMovingDown)
|
|
1754
1757
|
{
|
|
1755
1758
|
// adjust position to slightly above nearest tile boundary
|
|
1756
1759
|
// this prevents gap between object and ground
|
|
1757
1760
|
const epsilon = .0001;
|
|
1758
1761
|
this.pos.y = (oldPos.y-this.size.y/2|0)+this.size.y/2+epsilon;
|
|
1762
|
+
|
|
1763
|
+
// set ground object to self for tile collision
|
|
1764
|
+
this.groundObject = this;
|
|
1759
1765
|
}
|
|
1760
1766
|
else
|
|
1761
1767
|
{
|
|
1762
1768
|
// move to previous position
|
|
1763
1769
|
this.pos.y = oldPos.y;
|
|
1770
|
+
this.groundObject = undefined;
|
|
1764
1771
|
}
|
|
1765
1772
|
}
|
|
1766
1773
|
if (isBlockedX)
|
|
@@ -1805,26 +1812,26 @@ class EngineObject
|
|
|
1805
1812
|
|
|
1806
1813
|
/** Convert from local space to world space for a vector (rotation only)
|
|
1807
1814
|
* @param {Vector2} vec - local space vector */
|
|
1808
|
-
localToWorldVector(vec) { return vec.rotate(
|
|
1815
|
+
localToWorldVector(vec) { return vec.rotate(this.angle); }
|
|
1809
1816
|
|
|
1810
1817
|
/** Convert from world space to local space for a vector (rotation only)
|
|
1811
1818
|
* @param {Vector2} vec - world space vector */
|
|
1812
|
-
worldToLocalVector(vec) { return vec.rotate(this.angle); }
|
|
1819
|
+
worldToLocalVector(vec) { return vec.rotate(-this.angle); }
|
|
1813
1820
|
|
|
1814
1821
|
/** Called to check if a tile collision should be resolved
|
|
1815
|
-
* @param {
|
|
1822
|
+
* @param {number} tileData - the value of the tile at the position
|
|
1816
1823
|
* @param {Vector2} pos - tile where the collision occurred
|
|
1817
|
-
* @return {
|
|
1824
|
+
* @return {boolean} - true if the collision should be resolved */
|
|
1818
1825
|
collideWithTile(tileData, pos) { return tileData > 0; }
|
|
1819
1826
|
|
|
1820
1827
|
/** Called to check if a object collision should be resolved
|
|
1821
1828
|
* @param {EngineObject} object - the object to test against
|
|
1822
|
-
* @return {
|
|
1829
|
+
* @return {boolean} - true if the collision should be resolved
|
|
1823
1830
|
*/
|
|
1824
1831
|
collideWithObject(object) { return true; }
|
|
1825
1832
|
|
|
1826
1833
|
/** How long since the object was created
|
|
1827
|
-
* @return {
|
|
1834
|
+
* @return {number} */
|
|
1828
1835
|
getAliveTime() { return time - this.spawnTime; }
|
|
1829
1836
|
|
|
1830
1837
|
/** Apply acceleration to this object (adjust velocity, not affected by mass)
|
|
@@ -1836,13 +1843,13 @@ class EngineObject
|
|
|
1836
1843
|
applyForce(force) { this.applyAcceleration(force.scale(1/this.mass)); }
|
|
1837
1844
|
|
|
1838
1845
|
/** Get the direction of the mirror
|
|
1839
|
-
* @return {
|
|
1846
|
+
* @return {number} -1 if this.mirror is true, or 1 if not mirrored */
|
|
1840
1847
|
getMirrorSign() { return this.mirror ? -1 : 1; }
|
|
1841
1848
|
|
|
1842
1849
|
/** Attaches a child to this with a given local transform
|
|
1843
1850
|
* @param {EngineObject} child
|
|
1844
1851
|
* @param {Vector2} [localPos=(0,0)]
|
|
1845
|
-
* @param {
|
|
1852
|
+
* @param {number} [localAngle] */
|
|
1846
1853
|
addChild(child, localPos=vec2(), localAngle=0)
|
|
1847
1854
|
{
|
|
1848
1855
|
ASSERT(!child.parent && !this.children.includes(child));
|
|
@@ -1862,10 +1869,10 @@ class EngineObject
|
|
|
1862
1869
|
}
|
|
1863
1870
|
|
|
1864
1871
|
/** Set how this object collides
|
|
1865
|
-
* @param {
|
|
1866
|
-
* @param {
|
|
1867
|
-
* @param {
|
|
1868
|
-
* @param {
|
|
1872
|
+
* @param {boolean} [collideSolidObjects] - Does it collide with solid objects?
|
|
1873
|
+
* @param {boolean} [isSolid] - Does it collide with and block other objects? (expensive in large numbers)
|
|
1874
|
+
* @param {boolean} [collideTiles] - Does it collide with the tile collision?
|
|
1875
|
+
* @param {boolean} [collideRaycast] - Does it collide with raycasts? */
|
|
1869
1876
|
setCollision(collideSolidObjects=true, isSolid=true, collideTiles=true, collideRaycast=true)
|
|
1870
1877
|
{
|
|
1871
1878
|
ASSERT(collideSolidObjects || !isSolid, 'solid objects must be set to collide');
|
|
@@ -1877,7 +1884,7 @@ class EngineObject
|
|
|
1877
1884
|
}
|
|
1878
1885
|
|
|
1879
1886
|
/** Returns string containing info about this object for debugging
|
|
1880
|
-
* @return {
|
|
1887
|
+
* @return {string} */
|
|
1881
1888
|
toString()
|
|
1882
1889
|
{
|
|
1883
1890
|
if (debug)
|
|
@@ -1975,10 +1982,10 @@ let drawCount;
|
|
|
1975
1982
|
* Create a tile info object using a grid based system
|
|
1976
1983
|
* - This can take vecs or floats for easier use and conversion
|
|
1977
1984
|
* - If an index is passed in, the tile size and index will determine the position
|
|
1978
|
-
* @param {
|
|
1979
|
-
* @param {
|
|
1980
|
-
* @param {
|
|
1981
|
-
* @param {
|
|
1985
|
+
* @param {Vector2|number} [pos=0] - Index of tile in sheet
|
|
1986
|
+
* @param {Vector2|number} [size=tileSizeDefault] - Size of tile in pixels
|
|
1987
|
+
* @param {number} [textureIndex] - Texture index to use
|
|
1988
|
+
* @param {number} [padding] - How many pixels padding around tiles
|
|
1982
1989
|
* @return {TileInfo}
|
|
1983
1990
|
* @example
|
|
1984
1991
|
* tile(2) // a tile at index 2 using the default tile size of 16
|
|
@@ -2022,8 +2029,8 @@ class TileInfo
|
|
|
2022
2029
|
/** Create a tile info object
|
|
2023
2030
|
* @param {Vector2} [pos=(0,0)] - Top left corner of tile in pixels
|
|
2024
2031
|
* @param {Vector2} [size=tileSizeDefault] - Size of tile in pixels
|
|
2025
|
-
* @param {
|
|
2026
|
-
* @param {
|
|
2032
|
+
* @param {number} [textureIndex] - Texture index to use
|
|
2033
|
+
* @param {number} [padding] - How many pixels padding around tiles
|
|
2027
2034
|
*/
|
|
2028
2035
|
constructor(pos=vec2(), size=tileSizeDefault, textureIndex=0, padding=0)
|
|
2029
2036
|
{
|
|
@@ -2031,9 +2038,9 @@ class TileInfo
|
|
|
2031
2038
|
this.pos = pos.copy();
|
|
2032
2039
|
/** @property {Vector2} - Size of tile in pixels */
|
|
2033
2040
|
this.size = size.copy();
|
|
2034
|
-
/** @property {
|
|
2041
|
+
/** @property {number} - Texture index to use */
|
|
2035
2042
|
this.textureIndex = textureIndex;
|
|
2036
|
-
/** @property {
|
|
2043
|
+
/** @property {number} - How many pixels padding around tiles */
|
|
2037
2044
|
this.padding = padding;
|
|
2038
2045
|
}
|
|
2039
2046
|
|
|
@@ -2045,7 +2052,7 @@ class TileInfo
|
|
|
2045
2052
|
{ return new TileInfo(this.pos.add(offset), this.size, this.textureIndex); }
|
|
2046
2053
|
|
|
2047
2054
|
/** Returns a copy of this tile offset by a number of animation frames
|
|
2048
|
-
* @param {
|
|
2055
|
+
* @param {number} frame - Offset to apply in animation frames
|
|
2049
2056
|
* @return {TileInfo}
|
|
2050
2057
|
*/
|
|
2051
2058
|
frame(frame)
|
|
@@ -2117,11 +2124,11 @@ function getCameraSize() { return mainCanvasSize.scale(1/cameraScale); }
|
|
|
2117
2124
|
* @param {Vector2} [size=(1,1)] - Size of the tile in world space
|
|
2118
2125
|
* @param {TileInfo}[tileInfo] - Tile info to use, untextured if undefined
|
|
2119
2126
|
* @param {Color} [color=(1,1,1,1)] - Color to modulate with
|
|
2120
|
-
* @param {
|
|
2121
|
-
* @param {
|
|
2127
|
+
* @param {number} [angle] - Angle to rotate by
|
|
2128
|
+
* @param {boolean} [mirror] - If true image is flipped along the Y axis
|
|
2122
2129
|
* @param {Color} [additiveColor=(0,0,0,0)] - Additive color to be applied
|
|
2123
|
-
* @param {
|
|
2124
|
-
* @param {
|
|
2130
|
+
* @param {boolean} [useWebGL=glEnable] - Use accelerated WebGL rendering
|
|
2131
|
+
* @param {boolean} [screenSpace=false] - If true the pos and size are in screen space
|
|
2125
2132
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context] - Canvas 2D context to draw to
|
|
2126
2133
|
* @memberof Draw */
|
|
2127
2134
|
function drawTile(pos, size=vec2(1), tileInfo, color=new Color,
|
|
@@ -2196,9 +2203,9 @@ function drawTile(pos, size=vec2(1), tileInfo, color=new Color,
|
|
|
2196
2203
|
* @param {Vector2} pos
|
|
2197
2204
|
* @param {Vector2} [size=(1,1)]
|
|
2198
2205
|
* @param {Color} [color=(1,1,1,1)]
|
|
2199
|
-
* @param {
|
|
2200
|
-
* @param {
|
|
2201
|
-
* @param {
|
|
2206
|
+
* @param {number} [angle]
|
|
2207
|
+
* @param {boolean} [useWebGL=glEnable]
|
|
2208
|
+
* @param {boolean} [screenSpace=false]
|
|
2202
2209
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
|
|
2203
2210
|
* @memberof Draw */
|
|
2204
2211
|
function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
|
|
@@ -2209,10 +2216,10 @@ function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
|
|
|
2209
2216
|
/** Draw colored line between two points
|
|
2210
2217
|
* @param {Vector2} posA
|
|
2211
2218
|
* @param {Vector2} posB
|
|
2212
|
-
* @param {
|
|
2219
|
+
* @param {number} [thickness]
|
|
2213
2220
|
* @param {Color} [color=(1,1,1,1)]
|
|
2214
|
-
* @param {
|
|
2215
|
-
* @param {
|
|
2221
|
+
* @param {boolean} [useWebGL=glEnable]
|
|
2222
|
+
* @param {boolean} [screenSpace=false]
|
|
2216
2223
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
|
|
2217
2224
|
* @memberof Draw */
|
|
2218
2225
|
function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace, context)
|
|
@@ -2223,11 +2230,11 @@ function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace, contex
|
|
|
2223
2230
|
}
|
|
2224
2231
|
|
|
2225
2232
|
/** Draw colored polygon using passed in points
|
|
2226
|
-
* @param {Array} points - Array of Vector2 points
|
|
2233
|
+
* @param {Array<Vector2>} points - Array of Vector2 points
|
|
2227
2234
|
* @param {Color} [color=(1,1,1,1)]
|
|
2228
|
-
* @param {
|
|
2235
|
+
* @param {number} [lineWidth=0]
|
|
2229
2236
|
* @param {Color} [lineColor=(0,0,0,1)]
|
|
2230
|
-
* @param {
|
|
2237
|
+
* @param {boolean} [screenSpace=false]
|
|
2231
2238
|
* @param {CanvasRenderingContext2D} [context=mainContext]
|
|
2232
2239
|
* @memberof Draw */
|
|
2233
2240
|
function drawPoly(points, color=new Color, lineWidth=0, lineColor=new Color(0,0,0), screenSpace, context=mainContext)
|
|
@@ -2249,13 +2256,13 @@ function drawPoly(points, color=new Color, lineWidth=0, lineColor=new Color(0,0,
|
|
|
2249
2256
|
|
|
2250
2257
|
/** Draw colored ellipse using passed in point
|
|
2251
2258
|
* @param {Vector2} pos
|
|
2252
|
-
* @param {
|
|
2253
|
-
* @param {
|
|
2254
|
-
* @param {
|
|
2259
|
+
* @param {number} [width=1]
|
|
2260
|
+
* @param {number} [height=1]
|
|
2261
|
+
* @param {number} [angle=0]
|
|
2255
2262
|
* @param {Color} [color=(1,1,1,1)]
|
|
2256
|
-
* @param {
|
|
2263
|
+
* @param {number} [lineWidth=0]
|
|
2257
2264
|
* @param {Color} [lineColor=(0,0,0,1)]
|
|
2258
|
-
* @param {
|
|
2265
|
+
* @param {boolean} [screenSpace=false]
|
|
2259
2266
|
* @param {CanvasRenderingContext2D} [context=mainContext]
|
|
2260
2267
|
* @memberof Draw */
|
|
2261
2268
|
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 +2289,11 @@ function drawEllipse(pos, width=1, height=1, angle=0, color=new Color, lineWidth
|
|
|
2282
2289
|
|
|
2283
2290
|
/** Draw colored circle using passed in point
|
|
2284
2291
|
* @param {Vector2} pos
|
|
2285
|
-
* @param {
|
|
2292
|
+
* @param {number} [radius=1]
|
|
2286
2293
|
* @param {Color} [color=(1,1,1,1)]
|
|
2287
|
-
* @param {
|
|
2294
|
+
* @param {number} [lineWidth=0]
|
|
2288
2295
|
* @param {Color} [lineColor=(0,0,0,1)]
|
|
2289
|
-
* @param {
|
|
2296
|
+
* @param {boolean} [screenSpace=false]
|
|
2290
2297
|
* @param {CanvasRenderingContext2D} [context=mainContext]
|
|
2291
2298
|
* @memberof Draw */
|
|
2292
2299
|
function drawCircle(pos, radius=1, color=new Color, lineWidth=0, lineColor=new Color(0,0,0), screenSpace, context=mainContext)
|
|
@@ -2295,10 +2302,10 @@ function drawCircle(pos, radius=1, color=new Color, lineWidth=0, lineColor=new C
|
|
|
2295
2302
|
/** Draw directly to a 2d canvas context in world space
|
|
2296
2303
|
* @param {Vector2} pos
|
|
2297
2304
|
* @param {Vector2} size
|
|
2298
|
-
* @param {
|
|
2299
|
-
* @param {
|
|
2305
|
+
* @param {number} angle
|
|
2306
|
+
* @param {boolean} mirror
|
|
2300
2307
|
* @param {Function} drawFunction
|
|
2301
|
-
* @param {
|
|
2308
|
+
* @param {boolean} [screenSpace=false]
|
|
2302
2309
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=mainContext]
|
|
2303
2310
|
* @memberof Draw */
|
|
2304
2311
|
function drawCanvas2D(pos, size, angle, mirror, drawFunction, screenSpace, context=mainContext)
|
|
@@ -2319,15 +2326,15 @@ function drawCanvas2D(pos, size, angle, mirror, drawFunction, screenSpace, conte
|
|
|
2319
2326
|
|
|
2320
2327
|
/** Draw text on main canvas in world space
|
|
2321
2328
|
* Automatically splits new lines into rows
|
|
2322
|
-
* @param {
|
|
2329
|
+
* @param {string} text
|
|
2323
2330
|
* @param {Vector2} pos
|
|
2324
|
-
* @param {
|
|
2331
|
+
* @param {number} [size]
|
|
2325
2332
|
* @param {Color} [color=(1,1,1,1)]
|
|
2326
|
-
* @param {
|
|
2333
|
+
* @param {number} [lineWidth]
|
|
2327
2334
|
* @param {Color} [lineColor=(0,0,0,1)]
|
|
2328
2335
|
* @param {CanvasTextAlign} [textAlign='center']
|
|
2329
|
-
* @param {
|
|
2330
|
-
* @param {
|
|
2336
|
+
* @param {string} [font=fontDefault]
|
|
2337
|
+
* @param {number} [maxWidth]
|
|
2331
2338
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=mainContext]
|
|
2332
2339
|
* @memberof Draw */
|
|
2333
2340
|
function drawText(text, pos, size=1, color, lineWidth=0, lineColor, textAlign, font, maxWidth, context=mainContext)
|
|
@@ -2337,15 +2344,15 @@ function drawText(text, pos, size=1, color, lineWidth=0, lineColor, textAlign, f
|
|
|
2337
2344
|
|
|
2338
2345
|
/** Draw text on overlay canvas in world space
|
|
2339
2346
|
* Automatically splits new lines into rows
|
|
2340
|
-
* @param {
|
|
2347
|
+
* @param {string} text
|
|
2341
2348
|
* @param {Vector2} pos
|
|
2342
|
-
* @param {
|
|
2349
|
+
* @param {number} [size]
|
|
2343
2350
|
* @param {Color} [color=(1,1,1,1)]
|
|
2344
|
-
* @param {
|
|
2351
|
+
* @param {number} [lineWidth]
|
|
2345
2352
|
* @param {Color} [lineColor=(0,0,0,1)]
|
|
2346
2353
|
* @param {CanvasTextAlign} [textAlign='center']
|
|
2347
|
-
* @param {
|
|
2348
|
-
* @param {
|
|
2354
|
+
* @param {string} [font=fontDefault]
|
|
2355
|
+
* @param {number} [maxWidth]
|
|
2349
2356
|
* @memberof Draw */
|
|
2350
2357
|
function drawTextOverlay(text, pos, size=1, color, lineWidth=0, lineColor, textAlign, font, maxWidth)
|
|
2351
2358
|
{
|
|
@@ -2354,15 +2361,15 @@ function drawTextOverlay(text, pos, size=1, color, lineWidth=0, lineColor, textA
|
|
|
2354
2361
|
|
|
2355
2362
|
/** Draw text on overlay canvas in screen space
|
|
2356
2363
|
* Automatically splits new lines into rows
|
|
2357
|
-
* @param {
|
|
2364
|
+
* @param {string} text
|
|
2358
2365
|
* @param {Vector2} pos
|
|
2359
|
-
* @param {
|
|
2366
|
+
* @param {number} [size]
|
|
2360
2367
|
* @param {Color} [color=(1,1,1,1)]
|
|
2361
|
-
* @param {
|
|
2368
|
+
* @param {number} [lineWidth]
|
|
2362
2369
|
* @param {Color} [lineColor=(0,0,0,1)]
|
|
2363
2370
|
* @param {CanvasTextAlign} [textAlign]
|
|
2364
|
-
* @param {
|
|
2365
|
-
* @param {
|
|
2371
|
+
* @param {string} [font=fontDefault]
|
|
2372
|
+
* @param {number} [maxWidth]
|
|
2366
2373
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=overlayContext]
|
|
2367
2374
|
* @memberof Draw */
|
|
2368
2375
|
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 +2395,8 @@ function drawTextScreen(text, pos, size=1, color=new Color, lineWidth=0, lineCol
|
|
|
2388
2395
|
}
|
|
2389
2396
|
|
|
2390
2397
|
/** Enable normal or additive blend mode
|
|
2391
|
-
* @param {
|
|
2392
|
-
* @param {
|
|
2398
|
+
* @param {boolean} [additive]
|
|
2399
|
+
* @param {boolean} [useWebGL=glEnable]
|
|
2393
2400
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=mainContext]
|
|
2394
2401
|
* @memberof Draw */
|
|
2395
2402
|
function setBlendMode(additive, useWebGL=glEnable, context)
|
|
@@ -2456,10 +2463,10 @@ class FontImage
|
|
|
2456
2463
|
}
|
|
2457
2464
|
|
|
2458
2465
|
/** Draw text in world space using the image font
|
|
2459
|
-
* @param {
|
|
2466
|
+
* @param {string} text
|
|
2460
2467
|
* @param {Vector2} pos
|
|
2461
|
-
* @param {
|
|
2462
|
-
* @param {
|
|
2468
|
+
* @param {number} [scale=.25]
|
|
2469
|
+
* @param {boolean} [center]
|
|
2463
2470
|
*/
|
|
2464
2471
|
drawText(text, pos, scale=1, center)
|
|
2465
2472
|
{
|
|
@@ -2467,10 +2474,10 @@ class FontImage
|
|
|
2467
2474
|
}
|
|
2468
2475
|
|
|
2469
2476
|
/** Draw text in screen space using the image font
|
|
2470
|
-
* @param {
|
|
2477
|
+
* @param {string} text
|
|
2471
2478
|
* @param {Vector2} pos
|
|
2472
|
-
* @param {
|
|
2473
|
-
* @param {
|
|
2479
|
+
* @param {number} [scale]
|
|
2480
|
+
* @param {boolean} [center]
|
|
2474
2481
|
*/
|
|
2475
2482
|
drawTextScreen(text, pos, scale=4, center)
|
|
2476
2483
|
{
|
|
@@ -2508,7 +2515,7 @@ class FontImage
|
|
|
2508
2515
|
// Display functions
|
|
2509
2516
|
|
|
2510
2517
|
/** Returns true if fullscreen mode is active
|
|
2511
|
-
* @return {
|
|
2518
|
+
* @return {boolean}
|
|
2512
2519
|
* @memberof Draw */
|
|
2513
2520
|
function isFullscreen() { return !!document.fullscreenElement; }
|
|
2514
2521
|
|
|
@@ -2527,7 +2534,7 @@ function toggleFullscreen()
|
|
|
2527
2534
|
}
|
|
2528
2535
|
|
|
2529
2536
|
/** Set the cursor style
|
|
2530
|
-
* @param {
|
|
2537
|
+
* @param {string} cursorStyle - CSS cursor style (auto, none, crosshair, etc)
|
|
2531
2538
|
* @memberof Draw */
|
|
2532
2539
|
function setCursor(cursorStyle = 'auto')
|
|
2533
2540
|
{
|
|
@@ -2547,9 +2554,9 @@ function setCursor(cursorStyle = 'auto')
|
|
|
2547
2554
|
|
|
2548
2555
|
|
|
2549
2556
|
/** Returns true if device key is down
|
|
2550
|
-
* @param {
|
|
2551
|
-
* @param {
|
|
2552
|
-
* @return {
|
|
2557
|
+
* @param {string|number} key
|
|
2558
|
+
* @param {number} [device]
|
|
2559
|
+
* @return {boolean}
|
|
2553
2560
|
* @memberof Input */
|
|
2554
2561
|
function keyIsDown(key, device=0)
|
|
2555
2562
|
{
|
|
@@ -2558,9 +2565,9 @@ function keyIsDown(key, device=0)
|
|
|
2558
2565
|
}
|
|
2559
2566
|
|
|
2560
2567
|
/** Returns true if device key was pressed this frame
|
|
2561
|
-
* @param {
|
|
2562
|
-
* @param {
|
|
2563
|
-
* @return {
|
|
2568
|
+
* @param {string|number} key
|
|
2569
|
+
* @param {number} [device]
|
|
2570
|
+
* @return {boolean}
|
|
2564
2571
|
* @memberof Input */
|
|
2565
2572
|
function keyWasPressed(key, device=0)
|
|
2566
2573
|
{
|
|
@@ -2569,9 +2576,9 @@ function keyWasPressed(key, device=0)
|
|
|
2569
2576
|
}
|
|
2570
2577
|
|
|
2571
2578
|
/** Returns true if device key was released this frame
|
|
2572
|
-
* @param {
|
|
2573
|
-
* @param {
|
|
2574
|
-
* @return {
|
|
2579
|
+
* @param {string|number} key
|
|
2580
|
+
* @param {number} [device]
|
|
2581
|
+
* @return {boolean}
|
|
2575
2582
|
* @memberof Input */
|
|
2576
2583
|
function keyWasReleased(key, device=0)
|
|
2577
2584
|
{
|
|
@@ -2594,22 +2601,22 @@ function clearInput() { inputData = [[]]; touchGamepadButtons = []; }
|
|
|
2594
2601
|
|
|
2595
2602
|
/** Returns true if mouse button is down
|
|
2596
2603
|
* @function
|
|
2597
|
-
* @param {
|
|
2598
|
-
* @return {
|
|
2604
|
+
* @param {number} button
|
|
2605
|
+
* @return {boolean}
|
|
2599
2606
|
* @memberof Input */
|
|
2600
2607
|
const mouseIsDown = keyIsDown;
|
|
2601
2608
|
|
|
2602
2609
|
/** Returns true if mouse button was pressed
|
|
2603
2610
|
* @function
|
|
2604
|
-
* @param {
|
|
2605
|
-
* @return {
|
|
2611
|
+
* @param {number} button
|
|
2612
|
+
* @return {boolean}
|
|
2606
2613
|
* @memberof Input */
|
|
2607
2614
|
const mouseWasPressed = keyWasPressed;
|
|
2608
2615
|
|
|
2609
2616
|
/** Returns true if mouse button was released
|
|
2610
2617
|
* @function
|
|
2611
|
-
* @param {
|
|
2612
|
-
* @return {
|
|
2618
|
+
* @param {number} button
|
|
2619
|
+
* @return {boolean}
|
|
2613
2620
|
* @memberof Input */
|
|
2614
2621
|
const mouseWasReleased = keyWasReleased;
|
|
2615
2622
|
|
|
@@ -2624,47 +2631,47 @@ let mousePos = vec2();
|
|
|
2624
2631
|
let mousePosScreen = vec2();
|
|
2625
2632
|
|
|
2626
2633
|
/** Mouse wheel delta this frame
|
|
2627
|
-
* @type {
|
|
2634
|
+
* @type {number}
|
|
2628
2635
|
* @memberof Input */
|
|
2629
2636
|
let mouseWheel = 0;
|
|
2630
2637
|
|
|
2631
2638
|
/** Returns true if user is using gamepad (has more recently pressed a gamepad button)
|
|
2632
|
-
* @type {
|
|
2639
|
+
* @type {boolean}
|
|
2633
2640
|
* @memberof Input */
|
|
2634
2641
|
let isUsingGamepad = false;
|
|
2635
2642
|
|
|
2636
2643
|
/** Prevents input continuing to the default browser handling (false by default)
|
|
2637
|
-
* @type {
|
|
2644
|
+
* @type {boolean}
|
|
2638
2645
|
* @memberof Input */
|
|
2639
2646
|
let preventDefaultInput = false;
|
|
2640
2647
|
|
|
2641
2648
|
/** Returns true if gamepad button is down
|
|
2642
|
-
* @param {
|
|
2643
|
-
* @param {
|
|
2644
|
-
* @return {
|
|
2649
|
+
* @param {number} button
|
|
2650
|
+
* @param {number} [gamepad]
|
|
2651
|
+
* @return {boolean}
|
|
2645
2652
|
* @memberof Input */
|
|
2646
2653
|
function gamepadIsDown(button, gamepad=0)
|
|
2647
2654
|
{ return keyIsDown(button, gamepad+1); }
|
|
2648
2655
|
|
|
2649
2656
|
/** Returns true if gamepad button was pressed
|
|
2650
|
-
* @param {
|
|
2651
|
-
* @param {
|
|
2652
|
-
* @return {
|
|
2657
|
+
* @param {number} button
|
|
2658
|
+
* @param {number} [gamepad]
|
|
2659
|
+
* @return {boolean}
|
|
2653
2660
|
* @memberof Input */
|
|
2654
2661
|
function gamepadWasPressed(button, gamepad=0)
|
|
2655
2662
|
{ return keyWasPressed(button, gamepad+1); }
|
|
2656
2663
|
|
|
2657
2664
|
/** Returns true if gamepad button was released
|
|
2658
|
-
* @param {
|
|
2659
|
-
* @param {
|
|
2660
|
-
* @return {
|
|
2665
|
+
* @param {number} button
|
|
2666
|
+
* @param {number} [gamepad]
|
|
2667
|
+
* @return {boolean}
|
|
2661
2668
|
* @memberof Input */
|
|
2662
2669
|
function gamepadWasReleased(button, gamepad=0)
|
|
2663
2670
|
{ return keyWasReleased(button, gamepad+1); }
|
|
2664
2671
|
|
|
2665
2672
|
/** Returns gamepad stick value
|
|
2666
|
-
* @param {
|
|
2667
|
-
* @param {
|
|
2673
|
+
* @param {number} stick
|
|
2674
|
+
* @param {number} [gamepad]
|
|
2668
2675
|
* @return {Vector2}
|
|
2669
2676
|
* @memberof Input */
|
|
2670
2677
|
function gamepadStick(stick, gamepad=0)
|
|
@@ -2867,7 +2874,7 @@ function gamepadsUpdate()
|
|
|
2867
2874
|
///////////////////////////////////////////////////////////////////////////////
|
|
2868
2875
|
|
|
2869
2876
|
/** Pulse the vibration hardware if it exists
|
|
2870
|
-
* @param {
|
|
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); }
|
|
@@ -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 {
|
|
3106
|
-
* @param {
|
|
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 {
|
|
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 {
|
|
3122
|
+
/** @property {number} - At what percentage of range should it start tapering off */
|
|
3116
3123
|
this.taper = taper;
|
|
3117
3124
|
|
|
3118
|
-
/** @property {
|
|
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 {
|
|
3135
|
-
* @param {
|
|
3136
|
-
* @param {
|
|
3137
|
-
* @param {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
3228
|
-
* @param {
|
|
3229
|
-
* @param {
|
|
3230
|
-
* @param {
|
|
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 {
|
|
3254
|
-
* @param {
|
|
3255
|
-
* @param {
|
|
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,
|
|
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 {
|
|
3312
|
-
* @param {
|
|
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 {
|
|
3321
|
-
* @param {
|
|
3322
|
-
* @param {
|
|
3323
|
-
* @param {
|
|
3324
|
-
* @param {
|
|
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 {
|
|
3352
|
-
* @param {
|
|
3353
|
-
* @return {
|
|
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 {
|
|
3363
|
-
* @param {
|
|
3364
|
-
* @param {
|
|
3365
|
-
* @param {
|
|
3366
|
-
* @param {
|
|
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 {
|
|
3426
|
-
* @param {
|
|
3427
|
-
* @param {
|
|
3428
|
-
* @param {
|
|
3429
|
-
* @param {
|
|
3430
|
-
* @param {
|
|
3431
|
-
* @param {
|
|
3432
|
-
* @param {
|
|
3433
|
-
* @param {
|
|
3434
|
-
* @param {
|
|
3435
|
-
* @param {
|
|
3436
|
-
* @param {
|
|
3437
|
-
* @param {
|
|
3438
|
-
* @param {
|
|
3439
|
-
* @param {
|
|
3440
|
-
* @param {
|
|
3441
|
-
* @param {
|
|
3442
|
-
* @param {
|
|
3443
|
-
* @param {
|
|
3444
|
-
* @param {
|
|
3445
|
-
* @param {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
3787
|
-
* @param {
|
|
3788
|
-
* @param {
|
|
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 {
|
|
3799
|
+
/** @property {number} - The tile to use, untextured if undefined */
|
|
3793
3800
|
this.tile = tile;
|
|
3794
|
-
/** @property {
|
|
3801
|
+
/** @property {number} - Integer direction of tile, in 90 degree increments */
|
|
3795
3802
|
this.direction = direction;
|
|
3796
|
-
/** @property {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
3984
|
-
* @param {
|
|
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 {
|
|
4005
|
-
* @param {
|
|
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 {
|
|
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 {
|
|
4085
|
-
* @param {
|
|
4086
|
-
* @param {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
4175
|
+
/** @property {boolean} - Do particles collide against tiles */
|
|
4169
4176
|
this.collideTiles = collideTiles;
|
|
4170
|
-
/** @property {
|
|
4177
|
+
/** @property {boolean} - Should particles use additive blend */
|
|
4171
4178
|
this.additive = additive;
|
|
4172
|
-
/** @property {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
4486
|
+
/** @property {boolean} - Is the medal unlocked? */
|
|
4480
4487
|
this.unlocked = false;
|
|
4481
4488
|
|
|
4482
4489
|
// load the source image if provided
|
|
@@ -4570,7 +4577,7 @@ let glCanvas;
|
|
|
4570
4577
|
let glContext;
|
|
4571
4578
|
|
|
4572
4579
|
/** Should webgl be setup with anti-aliasing? must be set before calling engineInit
|
|
4573
|
-
* @type {
|
|
4580
|
+
* @type {boolean}
|
|
4574
4581
|
* @memberof WebGL */
|
|
4575
4582
|
let glAntialias = true;
|
|
4576
4583
|
|
|
@@ -4793,7 +4800,7 @@ function glFlush()
|
|
|
4793
4800
|
|
|
4794
4801
|
/** Draw any sprites still in the buffer and copy to main canvas
|
|
4795
4802
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} context
|
|
4796
|
-
* @param {
|
|
4803
|
+
* @param {boolean} [forceDraw]
|
|
4797
4804
|
* @memberof WebGL */
|
|
4798
4805
|
function glCopyToContext(context, forceDraw=false)
|
|
4799
4806
|
{
|
|
@@ -4807,7 +4814,7 @@ function glCopyToContext(context, forceDraw=false)
|
|
|
4807
4814
|
}
|
|
4808
4815
|
|
|
4809
4816
|
/** Set anti-aliasing for webgl canvas
|
|
4810
|
-
* @param {
|
|
4817
|
+
* @param {boolean} [antialias]
|
|
4811
4818
|
* @memberof WebGL */
|
|
4812
4819
|
function glSetAntialias(antialias=true)
|
|
4813
4820
|
{
|
|
@@ -4872,61 +4879,62 @@ function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba, rgbaAdd
|
|
|
4872
4879
|
|
|
4873
4880
|
|
|
4874
4881
|
/** Name of engine
|
|
4875
|
-
* @type {
|
|
4882
|
+
* @type {string}
|
|
4876
4883
|
* @default
|
|
4877
4884
|
* @memberof Engine */
|
|
4878
4885
|
const engineName = 'LittleJS';
|
|
4879
4886
|
|
|
4880
4887
|
/** Version of engine
|
|
4881
|
-
* @type {
|
|
4888
|
+
* @type {string}
|
|
4882
4889
|
* @default
|
|
4883
4890
|
* @memberof Engine */
|
|
4884
|
-
const engineVersion = '1.11.
|
|
4891
|
+
const engineVersion = '1.11.10';
|
|
4885
4892
|
|
|
4886
4893
|
/** Frames per second to update
|
|
4887
|
-
* @type {
|
|
4894
|
+
* @type {number}
|
|
4888
4895
|
* @default
|
|
4889
4896
|
* @memberof Engine */
|
|
4890
4897
|
const frameRate = 60;
|
|
4891
4898
|
|
|
4892
4899
|
/** How many seconds each frame lasts, engine uses a fixed time step
|
|
4893
|
-
* @type {
|
|
4900
|
+
* @type {number}
|
|
4894
4901
|
* @default 1/60
|
|
4895
4902
|
* @memberof Engine */
|
|
4896
4903
|
const timeDelta = 1/frameRate;
|
|
4897
4904
|
|
|
4898
4905
|
/** Array containing all engine objects
|
|
4899
|
-
* @type {Array}
|
|
4906
|
+
* @type {Array<EngineObject>}
|
|
4900
4907
|
* @memberof Engine */
|
|
4901
4908
|
let engineObjects = [];
|
|
4902
4909
|
|
|
4903
4910
|
/** Array with only objects set to collide with other objects this frame (for optimization)
|
|
4904
|
-
* @type {Array}
|
|
4911
|
+
* @type {Array<EngineObject>}
|
|
4905
4912
|
* @memberof Engine */
|
|
4906
4913
|
let engineObjectsCollide = [];
|
|
4907
4914
|
|
|
4908
4915
|
/** Current update frame, used to calculate time
|
|
4909
|
-
* @type {
|
|
4916
|
+
* @type {number}
|
|
4910
4917
|
* @memberof Engine */
|
|
4911
4918
|
let frame = 0;
|
|
4912
4919
|
|
|
4913
4920
|
/** Current engine time since start in seconds
|
|
4914
|
-
* @type {
|
|
4921
|
+
* @type {number}
|
|
4915
4922
|
* @memberof Engine */
|
|
4916
4923
|
let time = 0;
|
|
4917
4924
|
|
|
4918
4925
|
/** Actual clock time since start in seconds (not affected by pause or frame rate clamping)
|
|
4919
|
-
* @type {
|
|
4926
|
+
* @type {number}
|
|
4920
4927
|
* @memberof Engine */
|
|
4921
4928
|
let timeReal = 0;
|
|
4922
4929
|
|
|
4923
4930
|
/** Is the game paused? Causes time and objects to not be updated
|
|
4924
|
-
* @type {
|
|
4931
|
+
* @type {boolean}
|
|
4925
4932
|
* @default false
|
|
4926
4933
|
* @memberof Engine */
|
|
4927
4934
|
let paused = false;
|
|
4935
|
+
|
|
4928
4936
|
/** Set if game is paused
|
|
4929
|
-
* @param {
|
|
4937
|
+
* @param {boolean} isPaused
|
|
4930
4938
|
* @memberof Engine */
|
|
4931
4939
|
function setPaused(isPaused) { paused = isPaused; }
|
|
4932
4940
|
|
|
@@ -4959,7 +4967,7 @@ function engineAddPlugin(updateFunction, renderFunction)
|
|
|
4959
4967
|
* @param {Function} gameUpdatePost - Called after physics and objects are updated, even when paused
|
|
4960
4968
|
* @param {Function} gameRender - Called before objects are rendered, for drawing the background
|
|
4961
4969
|
* @param {Function} gameRenderPost - Called after objects are rendered, useful for drawing UI
|
|
4962
|
-
* @param {Array} [imageSources=[]] - List of images to load
|
|
4970
|
+
* @param {Array<string>} [imageSources=[]] - List of images to load
|
|
4963
4971
|
* @param {HTMLElement} [rootElement] - Root element to attach to, the document body by default
|
|
4964
4972
|
* @memberof Engine */
|
|
4965
4973
|
function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, imageSources=[], rootElement=document.body)
|
|
@@ -5255,9 +5263,9 @@ function engineObjectsDestroy()
|
|
|
5255
5263
|
|
|
5256
5264
|
/** Collects all object within a given area
|
|
5257
5265
|
* @param {Vector2} [pos] - Center of test area, or undefined for all objects
|
|
5258
|
-
* @param {
|
|
5259
|
-
* @param {Array} [objects=engineObjects] - List of objects to check
|
|
5260
|
-
* @return {Array} - List of collected objects
|
|
5266
|
+
* @param {Vector2|number} [size] - Radius of circle if float, rectangle size if Vector2
|
|
5267
|
+
* @param {Array<EngineObject>} [objects=engineObjects] - List of objects to check
|
|
5268
|
+
* @return {Array<EngineObject>} - List of collected objects
|
|
5261
5269
|
* @memberof Engine */
|
|
5262
5270
|
function engineObjectsCollect(pos, size, objects=engineObjects)
|
|
5263
5271
|
{
|
|
@@ -5283,9 +5291,9 @@ function engineObjectsCollect(pos, size, objects=engineObjects)
|
|
|
5283
5291
|
|
|
5284
5292
|
/** Triggers a callback for each object within a given area
|
|
5285
5293
|
* @param {Vector2} [pos] - Center of test area, or undefined for all objects
|
|
5286
|
-
* @param {
|
|
5294
|
+
* @param {Vector2|number} [size] - Radius of circle if float, rectangle size if Vector2
|
|
5287
5295
|
* @param {Function} [callbackFunction] - Calls this function on every object that passes the test
|
|
5288
|
-
* @param {Array} [objects=engineObjects] - List of objects to check
|
|
5296
|
+
* @param {Array<EngineObject>} [objects=engineObjects] - List of objects to check
|
|
5289
5297
|
* @memberof Engine */
|
|
5290
5298
|
function engineObjectsCallback(pos, size, callbackFunction, objects=engineObjects)
|
|
5291
5299
|
{ engineObjectsCollect(pos, size, objects).forEach(o => callbackFunction(o)); }
|
|
@@ -5293,8 +5301,8 @@ function engineObjectsCallback(pos, size, callbackFunction, objects=engineObject
|
|
|
5293
5301
|
/** Return a list of objects intersecting a ray
|
|
5294
5302
|
* @param {Vector2} start
|
|
5295
5303
|
* @param {Vector2} end
|
|
5296
|
-
* @param {Array} [objects=engineObjects] - List of objects to check
|
|
5297
|
-
* @return {Array} - List of objects hit
|
|
5304
|
+
* @param {Array<EngineObject>} [objects=engineObjects] - List of objects to check
|
|
5305
|
+
* @return {Array<EngineObject>} - List of objects hit
|
|
5298
5306
|
* @memberof Engine */
|
|
5299
5307
|
function engineObjectsRaycast(start, end, objects=engineObjects)
|
|
5300
5308
|
{
|