littlejsengine 1.11.9 → 1.11.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/littlejs.d.ts +485 -492
- package/dist/littlejs.esm.js +548 -529
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +546 -525
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +502 -484
- package/examples/htmlMenu/game.js +11 -1
- package/examples/htmlMenu/index.html +1 -10
- package/examples/module/game.js +2 -2
- package/examples/shorts/base.html +1 -1
- package/examples/starter/build/index.html +2 -0
- package/examples/starter/build/index.js +1 -0
- package/examples/starter/build/tiles.png +0 -0
- package/examples/starter/build.js +13 -3
- package/examples/starter/game.js +8 -1
- package/examples/starter/game.zip +0 -0
- 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 +44 -35
- package/plugins/postProcess.js +18 -4
- package/plugins/uiSystem.js +196 -30
- 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 -4
- package/src/engineInput.js +40 -35
- package/src/engineMedals.js +21 -11
- package/src/engineObject.js +42 -35
- package/src/engineParticles.js +10 -10
- package/src/engineSettings.js +77 -82
- package/src/engineTileLayer.js +21 -21
- package/src/engineUtilities.js +150 -150
- 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,17 +295,17 @@ function randColor(colorA=new Color, colorB=new Color(0,0,0,1), linear=false)
|
|
|
295
295
|
class RandomGenerator
|
|
296
296
|
{
|
|
297
297
|
/** Create a random number generator with the seed passed in
|
|
298
|
-
* @param {
|
|
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
|
|
@@ -316,13 +316,13 @@ class RandomGenerator
|
|
|
316
316
|
}
|
|
317
317
|
|
|
318
318
|
/** Returns a floored seeded random value the two values passed in
|
|
319
|
-
* @param {
|
|
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,7 +494,7 @@ class Vector2
|
|
|
494
494
|
|
|
495
495
|
/** Returns the cross product of this and the vector passed in
|
|
496
496
|
* @param {Vector2} v - other vector
|
|
497
|
-
* @return {
|
|
497
|
+
* @return {number} */
|
|
498
498
|
cross(v)
|
|
499
499
|
{
|
|
500
500
|
ASSERT(isVector2(v));
|
|
@@ -502,12 +502,12 @@ class Vector2
|
|
|
502
502
|
}
|
|
503
503
|
|
|
504
504
|
/** Returns the clockwise angle of this vector, up is angle 0
|
|
505
|
-
* @return {
|
|
505
|
+
* @return {number} */
|
|
506
506
|
angle() { return Math.atan2(this.x, this.y); }
|
|
507
507
|
|
|
508
508
|
/** Sets this vector with clockwise angle and length passed in
|
|
509
|
-
* @param {
|
|
510
|
-
* @param {
|
|
509
|
+
* @param {number} [angle]
|
|
510
|
+
* @param {number} [length]
|
|
511
511
|
* @return {Vector2} */
|
|
512
512
|
setAngle(angle=0, length=1)
|
|
513
513
|
{
|
|
@@ -517,7 +517,7 @@ class Vector2
|
|
|
517
517
|
}
|
|
518
518
|
|
|
519
519
|
/** Returns copy of this vector rotated by the clockwise angle passed in
|
|
520
|
-
* @param {
|
|
520
|
+
* @param {number} angle
|
|
521
521
|
* @return {Vector2} */
|
|
522
522
|
rotate(angle)
|
|
523
523
|
{
|
|
@@ -526,8 +526,8 @@ class Vector2
|
|
|
526
526
|
}
|
|
527
527
|
|
|
528
528
|
/** Set the integer direction of this vector, corresponding to multiples of 90 degree rotation (0-3)
|
|
529
|
-
* @param {
|
|
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)
|
|
@@ -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,34 @@ let canvasMaxSize = vec2(1920, 1080);
|
|
|
1004
1004
|
let canvasFixedSize = vec2();
|
|
1005
1005
|
|
|
1006
1006
|
/** Use nearest neighbor scaling algorithm for canvas for more pixelated look
|
|
1007
|
-
*
|
|
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
|
-
*
|
|
1033
|
+
* - Must be set before startup to take effect
|
|
1034
|
+
* @type {boolean}
|
|
1032
1035
|
* @default
|
|
1033
1036
|
* @memberof Settings */
|
|
1034
1037
|
let headlessMode = false;
|
|
@@ -1037,13 +1040,15 @@ let headlessMode = false;
|
|
|
1037
1040
|
// WebGL settings
|
|
1038
1041
|
|
|
1039
1042
|
/** Enable webgl rendering, webgl can be disabled and removed from build (with some features disabled)
|
|
1040
|
-
*
|
|
1043
|
+
* - Must be set before startup to take effect
|
|
1044
|
+
* @type {boolean}
|
|
1041
1045
|
* @default
|
|
1042
1046
|
* @memberof Settings */
|
|
1043
1047
|
let glEnable = true;
|
|
1044
1048
|
|
|
1045
1049
|
/** Fixes slow rendering in some browsers by not compositing the WebGL canvas
|
|
1046
|
-
*
|
|
1050
|
+
* - Must be set before startup to take effect
|
|
1051
|
+
* @type {boolean}
|
|
1047
1052
|
* @default
|
|
1048
1053
|
* @memberof Settings */
|
|
1049
1054
|
let glOverlay = true;
|
|
@@ -1058,7 +1063,7 @@ let glOverlay = true;
|
|
|
1058
1063
|
let tileSizeDefault = vec2(16);
|
|
1059
1064
|
|
|
1060
1065
|
/** How many pixels smaller to draw tiles to prevent bleeding from neighbors
|
|
1061
|
-
* @type {
|
|
1066
|
+
* @type {number}
|
|
1062
1067
|
* @default
|
|
1063
1068
|
* @memberof Settings */
|
|
1064
1069
|
let tileFixBleedScale = 0;
|
|
@@ -1067,55 +1072,55 @@ let tileFixBleedScale = 0;
|
|
|
1067
1072
|
// Object settings
|
|
1068
1073
|
|
|
1069
1074
|
/** Enable physics solver for collisions between objects
|
|
1070
|
-
* @type {
|
|
1075
|
+
* @type {boolean}
|
|
1071
1076
|
* @default
|
|
1072
1077
|
* @memberof Settings */
|
|
1073
1078
|
let enablePhysicsSolver = true;
|
|
1074
1079
|
|
|
1075
1080
|
/** Default object mass for collision calculations (how heavy objects are)
|
|
1076
|
-
* @type {
|
|
1081
|
+
* @type {number}
|
|
1077
1082
|
* @default
|
|
1078
1083
|
* @memberof Settings */
|
|
1079
1084
|
let objectDefaultMass = 1;
|
|
1080
1085
|
|
|
1081
1086
|
/** How much to slow velocity by each frame (0-1)
|
|
1082
|
-
* @type {
|
|
1087
|
+
* @type {number}
|
|
1083
1088
|
* @default
|
|
1084
1089
|
* @memberof Settings */
|
|
1085
1090
|
let objectDefaultDamping = 1;
|
|
1086
1091
|
|
|
1087
1092
|
/** How much to slow angular velocity each frame (0-1)
|
|
1088
|
-
* @type {
|
|
1093
|
+
* @type {number}
|
|
1089
1094
|
* @default
|
|
1090
1095
|
* @memberof Settings */
|
|
1091
1096
|
let objectDefaultAngleDamping = 1;
|
|
1092
1097
|
|
|
1093
1098
|
/** How much to bounce when a collision occurs (0-1)
|
|
1094
|
-
* @type {
|
|
1099
|
+
* @type {number}
|
|
1095
1100
|
* @default
|
|
1096
1101
|
* @memberof Settings */
|
|
1097
1102
|
let objectDefaultElasticity = 0;
|
|
1098
1103
|
|
|
1099
1104
|
/** How much to slow when touching (0-1)
|
|
1100
|
-
* @type {
|
|
1105
|
+
* @type {number}
|
|
1101
1106
|
* @default
|
|
1102
1107
|
* @memberof Settings */
|
|
1103
1108
|
let objectDefaultFriction = .8;
|
|
1104
1109
|
|
|
1105
1110
|
/** Clamp max speed to avoid fast objects missing collisions
|
|
1106
|
-
* @type {
|
|
1111
|
+
* @type {number}
|
|
1107
1112
|
* @default
|
|
1108
1113
|
* @memberof Settings */
|
|
1109
1114
|
let objectMaxSpeed = 1;
|
|
1110
1115
|
|
|
1111
1116
|
/** How much gravity to apply to objects along the Y axis, negative is down
|
|
1112
|
-
* @type {
|
|
1117
|
+
* @type {number}
|
|
1113
1118
|
* @default
|
|
1114
1119
|
* @memberof Settings */
|
|
1115
1120
|
let gravity = 0;
|
|
1116
1121
|
|
|
1117
1122
|
/** Scales emit rate of particles, useful for low graphics mode (0 disables particle emitters)
|
|
1118
|
-
* @type {
|
|
1123
|
+
* @type {number}
|
|
1119
1124
|
* @default
|
|
1120
1125
|
* @memberof Settings */
|
|
1121
1126
|
let particleEmitRateScale = 1;
|
|
@@ -1124,58 +1129,59 @@ let particleEmitRateScale = 1;
|
|
|
1124
1129
|
// Input settings
|
|
1125
1130
|
|
|
1126
1131
|
/** Should gamepads be allowed
|
|
1127
|
-
* @type {
|
|
1132
|
+
* @type {boolean}
|
|
1128
1133
|
* @default
|
|
1129
1134
|
* @memberof Settings */
|
|
1130
1135
|
let gamepadsEnable = true;
|
|
1131
1136
|
|
|
1132
1137
|
/** If true, the dpad input is also routed to the left analog stick (for better accessability)
|
|
1133
|
-
* @type {
|
|
1138
|
+
* @type {boolean}
|
|
1134
1139
|
* @default
|
|
1135
1140
|
* @memberof Settings */
|
|
1136
1141
|
let gamepadDirectionEmulateStick = true;
|
|
1137
1142
|
|
|
1138
1143
|
/** If true the WASD keys are also routed to the direction keys (for better accessability)
|
|
1139
|
-
* @type {
|
|
1144
|
+
* @type {boolean}
|
|
1140
1145
|
* @default
|
|
1141
1146
|
* @memberof Settings */
|
|
1142
1147
|
let inputWASDEmulateDirection = true;
|
|
1143
1148
|
|
|
1144
1149
|
/** True if touch input is enabled for mobile devices
|
|
1145
1150
|
* - Touch events will be routed to mouse events
|
|
1146
|
-
*
|
|
1151
|
+
* - Must be set before startup to take effect
|
|
1152
|
+
* @type {boolean}
|
|
1147
1153
|
* @default
|
|
1148
1154
|
* @memberof Settings */
|
|
1149
1155
|
let touchInputEnable = true;
|
|
1150
1156
|
|
|
1151
1157
|
/** True if touch gamepad should appear on mobile devices
|
|
1152
1158
|
* - Supports left analog stick, 4 face buttons and start button (button 9)
|
|
1153
|
-
* - Must be set
|
|
1154
|
-
* @type {
|
|
1159
|
+
* - Must be set before startup to take effect
|
|
1160
|
+
* @type {boolean}
|
|
1155
1161
|
* @default
|
|
1156
1162
|
* @memberof Settings */
|
|
1157
1163
|
let touchGamepadEnable = false;
|
|
1158
1164
|
|
|
1159
1165
|
/** True if touch gamepad should be analog stick or false to use if 8 way dpad
|
|
1160
|
-
* @type {
|
|
1166
|
+
* @type {boolean}
|
|
1161
1167
|
* @default
|
|
1162
1168
|
* @memberof Settings */
|
|
1163
1169
|
let touchGamepadAnalog = true;
|
|
1164
1170
|
|
|
1165
1171
|
/** Size of virtual gamepad for touch devices in pixels
|
|
1166
|
-
* @type {
|
|
1172
|
+
* @type {number}
|
|
1167
1173
|
* @default
|
|
1168
1174
|
* @memberof Settings */
|
|
1169
1175
|
let touchGamepadSize = 99;
|
|
1170
1176
|
|
|
1171
1177
|
/** Transparency of touch gamepad overlay
|
|
1172
|
-
* @type {
|
|
1178
|
+
* @type {number}
|
|
1173
1179
|
* @default
|
|
1174
1180
|
* @memberof Settings */
|
|
1175
1181
|
let touchGamepadAlpha = .3;
|
|
1176
1182
|
|
|
1177
1183
|
/** Allow vibration hardware if it exists
|
|
1178
|
-
* @type {
|
|
1184
|
+
* @type {boolean}
|
|
1179
1185
|
* @default
|
|
1180
1186
|
* @memberof Settings */
|
|
1181
1187
|
let vibrateEnable = true;
|
|
@@ -1184,25 +1190,25 @@ let vibrateEnable = true;
|
|
|
1184
1190
|
// Audio settings
|
|
1185
1191
|
|
|
1186
1192
|
/** All audio code can be disabled and removed from build
|
|
1187
|
-
* @type {
|
|
1193
|
+
* @type {boolean}
|
|
1188
1194
|
* @default
|
|
1189
1195
|
* @memberof Settings */
|
|
1190
1196
|
let soundEnable = true;
|
|
1191
1197
|
|
|
1192
1198
|
/** Volume scale to apply to all sound, music and speech
|
|
1193
|
-
* @type {
|
|
1199
|
+
* @type {number}
|
|
1194
1200
|
* @default
|
|
1195
1201
|
* @memberof Settings */
|
|
1196
1202
|
let soundVolume = .3;
|
|
1197
1203
|
|
|
1198
1204
|
/** Default range where sound no longer plays
|
|
1199
|
-
* @type {
|
|
1205
|
+
* @type {number}
|
|
1200
1206
|
* @default
|
|
1201
1207
|
* @memberof Settings */
|
|
1202
1208
|
let soundDefaultRange = 40;
|
|
1203
1209
|
|
|
1204
1210
|
/** Default range percent to start tapering off sound (0-1)
|
|
1205
|
-
* @type {
|
|
1211
|
+
* @type {number}
|
|
1206
1212
|
* @default
|
|
1207
1213
|
* @memberof Settings */
|
|
1208
1214
|
let soundDefaultTaper = .7;
|
|
@@ -1211,13 +1217,13 @@ let soundDefaultTaper = .7;
|
|
|
1211
1217
|
// Medals settings
|
|
1212
1218
|
|
|
1213
1219
|
/** How long to show medals for in seconds
|
|
1214
|
-
* @type {
|
|
1220
|
+
* @type {number}
|
|
1215
1221
|
* @default
|
|
1216
1222
|
* @memberof Settings */
|
|
1217
1223
|
let medalDisplayTime = 5;
|
|
1218
1224
|
|
|
1219
1225
|
/** How quickly to slide on/off medals in seconds
|
|
1220
|
-
* @type {
|
|
1226
|
+
* @type {number}
|
|
1221
1227
|
* @default
|
|
1222
1228
|
* @memberof Settings */
|
|
1223
1229
|
let medalDisplaySlideTime = .5;
|
|
@@ -1228,14 +1234,8 @@ let medalDisplaySlideTime = .5;
|
|
|
1228
1234
|
* @memberof Settings */
|
|
1229
1235
|
let medalDisplaySize = vec2(640, 80);
|
|
1230
1236
|
|
|
1231
|
-
/** Size of icon in medal display
|
|
1232
|
-
* @type {Number}
|
|
1233
|
-
* @default
|
|
1234
|
-
* @memberof Settings */
|
|
1235
|
-
let medalDisplayIconSize = 50;
|
|
1236
|
-
|
|
1237
1237
|
/** Set to stop medals from being unlockable (like if cheats are enabled)
|
|
1238
|
-
* @type {
|
|
1238
|
+
* @type {boolean}
|
|
1239
1239
|
* @default
|
|
1240
1240
|
* @memberof Settings */
|
|
1241
1241
|
let medalsPreventUnlock = false;
|
|
@@ -1249,7 +1249,7 @@ let medalsPreventUnlock = false;
|
|
|
1249
1249
|
function setCameraPos(pos) { cameraPos = pos; }
|
|
1250
1250
|
|
|
1251
1251
|
/** Set scale of camera in world space
|
|
1252
|
-
* @param {
|
|
1252
|
+
* @param {number} scale
|
|
1253
1253
|
* @memberof Settings */
|
|
1254
1254
|
function setCameraScale(scale) { cameraScale = scale; }
|
|
1255
1255
|
|
|
@@ -1264,37 +1264,37 @@ function setCanvasMaxSize(size) { canvasMaxSize = size; }
|
|
|
1264
1264
|
function setCanvasFixedSize(size) { canvasFixedSize = size; }
|
|
1265
1265
|
|
|
1266
1266
|
/** Use nearest neighbor scaling algorithm for canvas for more pixelated look
|
|
1267
|
-
* @param {
|
|
1267
|
+
* @param {boolean} pixelated
|
|
1268
1268
|
* @memberof Settings */
|
|
1269
1269
|
function setCanvasPixelated(pixelated) { canvasPixelated = pixelated; }
|
|
1270
1270
|
|
|
1271
1271
|
/** Disables texture filtering for crisper pixel art
|
|
1272
|
-
* @param {
|
|
1272
|
+
* @param {boolean} pixelated
|
|
1273
1273
|
* @memberof Settings */
|
|
1274
1274
|
function setTilesPixelated(pixelated) { tilesPixelated = pixelated; }
|
|
1275
1275
|
|
|
1276
1276
|
/** Set default font used for text rendering
|
|
1277
|
-
* @param {
|
|
1277
|
+
* @param {string} font
|
|
1278
1278
|
* @memberof Settings */
|
|
1279
1279
|
function setFontDefault(font) { fontDefault = font; }
|
|
1280
1280
|
|
|
1281
1281
|
/** Set if the LittleJS splash screen be shown on startup
|
|
1282
|
-
* @param {
|
|
1282
|
+
* @param {boolean} show
|
|
1283
1283
|
* @memberof Settings */
|
|
1284
1284
|
function setShowSplashScreen(show) { showSplashScreen = show; }
|
|
1285
1285
|
|
|
1286
1286
|
/** Set to disable rendering, audio, and input for servers
|
|
1287
|
-
* @param {
|
|
1287
|
+
* @param {boolean} headless
|
|
1288
1288
|
* @memberof Settings */
|
|
1289
1289
|
function setHeadlessMode(headless) { headlessMode = headless; }
|
|
1290
1290
|
|
|
1291
1291
|
/** Set if webgl rendering is enabled
|
|
1292
|
-
* @param {
|
|
1292
|
+
* @param {boolean} enable
|
|
1293
1293
|
* @memberof Settings */
|
|
1294
1294
|
function setGlEnable(enable) { glEnable = enable; }
|
|
1295
1295
|
|
|
1296
1296
|
/** Set to not composite the WebGL canvas
|
|
1297
|
-
* @param {
|
|
1297
|
+
* @param {boolean} overlay
|
|
1298
1298
|
* @memberof Settings */
|
|
1299
1299
|
function setGlOverlay(overlay) { glOverlay = overlay; }
|
|
1300
1300
|
|
|
@@ -1304,107 +1304,107 @@ function setGlOverlay(overlay) { glOverlay = overlay; }
|
|
|
1304
1304
|
function setTileSizeDefault(size) { tileSizeDefault = size; }
|
|
1305
1305
|
|
|
1306
1306
|
/** Set to prevent tile bleeding from neighbors in pixels
|
|
1307
|
-
* @param {
|
|
1307
|
+
* @param {number} scale
|
|
1308
1308
|
* @memberof Settings */
|
|
1309
1309
|
function setTileFixBleedScale(scale) { tileFixBleedScale = scale; }
|
|
1310
1310
|
|
|
1311
1311
|
/** Set if collisions between objects are enabled
|
|
1312
|
-
* @param {
|
|
1312
|
+
* @param {boolean} enable
|
|
1313
1313
|
* @memberof Settings */
|
|
1314
1314
|
function setEnablePhysicsSolver(enable) { enablePhysicsSolver = enable; }
|
|
1315
1315
|
|
|
1316
1316
|
/** Set default object mass for collision calculations
|
|
1317
|
-
* @param {
|
|
1317
|
+
* @param {number} mass
|
|
1318
1318
|
* @memberof Settings */
|
|
1319
1319
|
function setObjectDefaultMass(mass) { objectDefaultMass = mass; }
|
|
1320
1320
|
|
|
1321
1321
|
/** Set how much to slow velocity by each frame
|
|
1322
|
-
* @param {
|
|
1322
|
+
* @param {number} damp
|
|
1323
1323
|
* @memberof Settings */
|
|
1324
1324
|
function setObjectDefaultDamping(damp) { objectDefaultDamping = damp; }
|
|
1325
1325
|
|
|
1326
1326
|
/** Set how much to slow angular velocity each frame
|
|
1327
|
-
* @param {
|
|
1327
|
+
* @param {number} damp
|
|
1328
1328
|
* @memberof Settings */
|
|
1329
1329
|
function setObjectDefaultAngleDamping(damp) { objectDefaultAngleDamping = damp; }
|
|
1330
1330
|
|
|
1331
1331
|
/** Set how much to bounce when a collision occur
|
|
1332
|
-
* @param {
|
|
1332
|
+
* @param {number} elasticity
|
|
1333
1333
|
* @memberof Settings */
|
|
1334
1334
|
function setObjectDefaultElasticity(elasticity) { objectDefaultElasticity = elasticity; }
|
|
1335
1335
|
|
|
1336
1336
|
/** Set how much to slow when touching
|
|
1337
|
-
* @param {
|
|
1337
|
+
* @param {number} friction
|
|
1338
1338
|
* @memberof Settings */
|
|
1339
1339
|
function setObjectDefaultFriction(friction) { objectDefaultFriction = friction; }
|
|
1340
1340
|
|
|
1341
1341
|
/** Set max speed to avoid fast objects missing collisions
|
|
1342
|
-
* @param {
|
|
1342
|
+
* @param {number} speed
|
|
1343
1343
|
* @memberof Settings */
|
|
1344
1344
|
function setObjectMaxSpeed(speed) { objectMaxSpeed = speed; }
|
|
1345
1345
|
|
|
1346
1346
|
/** Set how much gravity to apply to objects along the Y axis
|
|
1347
|
-
* @param {
|
|
1347
|
+
* @param {number} newGravity
|
|
1348
1348
|
* @memberof Settings */
|
|
1349
1349
|
function setGravity(newGravity) { gravity = newGravity; }
|
|
1350
1350
|
|
|
1351
1351
|
/** Set to scales emit rate of particles
|
|
1352
|
-
* @param {
|
|
1352
|
+
* @param {number} scale
|
|
1353
1353
|
* @memberof Settings */
|
|
1354
1354
|
function setParticleEmitRateScale(scale) { particleEmitRateScale = scale; }
|
|
1355
1355
|
|
|
1356
1356
|
/** Set if gamepads are enabled
|
|
1357
|
-
* @param {
|
|
1357
|
+
* @param {boolean} enable
|
|
1358
1358
|
* @memberof Settings */
|
|
1359
1359
|
function setGamepadsEnable(enable) { gamepadsEnable = enable; }
|
|
1360
1360
|
|
|
1361
1361
|
/** Set if the dpad input is also routed to the left analog stick
|
|
1362
|
-
* @param {
|
|
1362
|
+
* @param {boolean} enable
|
|
1363
1363
|
* @memberof Settings */
|
|
1364
1364
|
function setGamepadDirectionEmulateStick(enable) { gamepadDirectionEmulateStick = enable; }
|
|
1365
1365
|
|
|
1366
1366
|
/** Set if true the WASD keys are also routed to the direction keys
|
|
1367
|
-
* @param {
|
|
1367
|
+
* @param {boolean} enable
|
|
1368
1368
|
* @memberof Settings */
|
|
1369
1369
|
function setInputWASDEmulateDirection(enable) { inputWASDEmulateDirection = enable; }
|
|
1370
1370
|
|
|
1371
1371
|
/** Set if touch input is allowed
|
|
1372
|
-
* @param {
|
|
1372
|
+
* @param {boolean} enable
|
|
1373
1373
|
* @memberof Settings */
|
|
1374
1374
|
function setTouchInputEnable(enable) { touchInputEnable = enable; }
|
|
1375
1375
|
|
|
1376
1376
|
/** Set if touch gamepad should appear on mobile devices
|
|
1377
|
-
* @param {
|
|
1377
|
+
* @param {boolean} enable
|
|
1378
1378
|
* @memberof Settings */
|
|
1379
1379
|
function setTouchGamepadEnable(enable) { touchGamepadEnable = enable; }
|
|
1380
1380
|
|
|
1381
1381
|
/** Set if touch gamepad should be analog stick or 8 way dpad
|
|
1382
|
-
* @param {
|
|
1382
|
+
* @param {boolean} analog
|
|
1383
1383
|
* @memberof Settings */
|
|
1384
1384
|
function setTouchGamepadAnalog(analog) { touchGamepadAnalog = analog; }
|
|
1385
1385
|
|
|
1386
1386
|
/** Set size of virtual gamepad for touch devices in pixels
|
|
1387
|
-
* @param {
|
|
1387
|
+
* @param {number} size
|
|
1388
1388
|
* @memberof Settings */
|
|
1389
1389
|
function setTouchGamepadSize(size) { touchGamepadSize = size; }
|
|
1390
1390
|
|
|
1391
1391
|
/** Set transparency of touch gamepad overlay
|
|
1392
|
-
* @param {
|
|
1392
|
+
* @param {number} alpha
|
|
1393
1393
|
* @memberof Settings */
|
|
1394
1394
|
function setTouchGamepadAlpha(alpha) { touchGamepadAlpha = alpha; }
|
|
1395
1395
|
|
|
1396
1396
|
/** Set to allow vibration hardware if it exists
|
|
1397
|
-
* @param {
|
|
1397
|
+
* @param {boolean} enable
|
|
1398
1398
|
* @memberof Settings */
|
|
1399
1399
|
function setVibrateEnable(enable) { vibrateEnable = enable; }
|
|
1400
1400
|
|
|
1401
1401
|
/** Set to disable all audio code
|
|
1402
|
-
* @param {
|
|
1402
|
+
* @param {boolean} enable
|
|
1403
1403
|
* @memberof Settings */
|
|
1404
1404
|
function setSoundEnable(enable) { soundEnable = enable; }
|
|
1405
1405
|
|
|
1406
1406
|
/** Set volume scale to apply to all sound, music and speech
|
|
1407
|
-
* @param {
|
|
1407
|
+
* @param {number} volume
|
|
1408
1408
|
* @memberof Settings */
|
|
1409
1409
|
function setSoundVolume(volume)
|
|
1410
1410
|
{
|
|
@@ -1414,22 +1414,22 @@ function setSoundVolume(volume)
|
|
|
1414
1414
|
}
|
|
1415
1415
|
|
|
1416
1416
|
/** Set default range where sound no longer plays
|
|
1417
|
-
* @param {
|
|
1417
|
+
* @param {number} range
|
|
1418
1418
|
* @memberof Settings */
|
|
1419
1419
|
function setSoundDefaultRange(range) { soundDefaultRange = range; }
|
|
1420
1420
|
|
|
1421
1421
|
/** Set default range percent to start tapering off sound
|
|
1422
|
-
* @param {
|
|
1422
|
+
* @param {number} taper
|
|
1423
1423
|
* @memberof Settings */
|
|
1424
1424
|
function setSoundDefaultTaper(taper) { soundDefaultTaper = taper; }
|
|
1425
1425
|
|
|
1426
1426
|
/** Set how long to show medals for in seconds
|
|
1427
|
-
* @param {
|
|
1427
|
+
* @param {number} time
|
|
1428
1428
|
* @memberof Settings */
|
|
1429
1429
|
function setMedalDisplayTime(time) { medalDisplayTime = time; }
|
|
1430
1430
|
|
|
1431
1431
|
/** Set how quickly to slide on/off medals in seconds
|
|
1432
|
-
* @param {
|
|
1432
|
+
* @param {number} time
|
|
1433
1433
|
* @memberof Settings */
|
|
1434
1434
|
function setMedalDisplaySlideTime(time) { medalDisplaySlideTime = time; }
|
|
1435
1435
|
|
|
@@ -1438,23 +1438,18 @@ function setMedalDisplaySlideTime(time) { medalDisplaySlideTime = time; }
|
|
|
1438
1438
|
* @memberof Settings */
|
|
1439
1439
|
function setMedalDisplaySize(size) { medalDisplaySize = size; }
|
|
1440
1440
|
|
|
1441
|
-
/** Set size of icon in medal display
|
|
1442
|
-
* @param {Number} size
|
|
1443
|
-
* @memberof Settings */
|
|
1444
|
-
function setMedalDisplayIconSize(size) { medalDisplayIconSize = size; }
|
|
1445
|
-
|
|
1446
1441
|
/** Set to stop medals from being unlockable
|
|
1447
|
-
* @param {
|
|
1442
|
+
* @param {boolean} preventUnlock
|
|
1448
1443
|
* @memberof Settings */
|
|
1449
1444
|
function setMedalsPreventUnlock(preventUnlock) { medalsPreventUnlock = preventUnlock; }
|
|
1450
1445
|
|
|
1451
1446
|
/** Set if watermark with FPS should be shown
|
|
1452
|
-
* @param {
|
|
1447
|
+
* @param {boolean} show
|
|
1453
1448
|
* @memberof Debug */
|
|
1454
1449
|
function setShowWatermark(show) { showWatermark = show; }
|
|
1455
1450
|
|
|
1456
1451
|
/** Set key code used to toggle debug mode, Esc by default
|
|
1457
|
-
* @param {
|
|
1452
|
+
* @param {string} key
|
|
1458
1453
|
* @memberof Debug */
|
|
1459
1454
|
function setDebugKey(key) { debugKey = key; }
|
|
1460
1455
|
/**
|
|
@@ -1494,9 +1489,9 @@ class EngineObject
|
|
|
1494
1489
|
* @param {Vector2} [pos=(0,0)] - World space position of the object
|
|
1495
1490
|
* @param {Vector2} [size=(1,1)] - World space size of the object
|
|
1496
1491
|
* @param {TileInfo} [tileInfo] - Tile info to render object (undefined is untextured)
|
|
1497
|
-
* @param {
|
|
1492
|
+
* @param {number} [angle] - Angle the object is rotated by
|
|
1498
1493
|
* @param {Color} [color=(1,1,1,1)] - Color to apply to tile when rendered
|
|
1499
|
-
* @param {
|
|
1494
|
+
* @param {number} [renderOrder] - Objects sorted by renderOrder before being rendered
|
|
1500
1495
|
*/
|
|
1501
1496
|
constructor(pos=vec2(), size=vec2(1), tileInfo, angle=0, color=new Color, renderOrder=0)
|
|
1502
1497
|
{
|
|
@@ -1512,57 +1507,59 @@ class EngineObject
|
|
|
1512
1507
|
this.drawSize = undefined;
|
|
1513
1508
|
/** @property {TileInfo} - Tile info to render object (undefined is untextured) */
|
|
1514
1509
|
this.tileInfo = tileInfo;
|
|
1515
|
-
/** @property {
|
|
1510
|
+
/** @property {number} - Angle to rotate the object */
|
|
1516
1511
|
this.angle = angle;
|
|
1517
1512
|
/** @property {Color} - Color to apply when rendered */
|
|
1518
1513
|
this.color = color;
|
|
1519
1514
|
/** @property {Color} - Additive color to apply when rendered */
|
|
1520
1515
|
this.additiveColor = undefined;
|
|
1521
|
-
/** @property {
|
|
1516
|
+
/** @property {boolean} - Should it flip along y axis when rendered */
|
|
1522
1517
|
this.mirror = false;
|
|
1523
1518
|
|
|
1524
1519
|
// physical properties
|
|
1525
|
-
/** @property {
|
|
1520
|
+
/** @property {number} [mass=objectDefaultMass] - How heavy the object is, static if 0 */
|
|
1526
1521
|
this.mass = objectDefaultMass;
|
|
1527
|
-
/** @property {
|
|
1522
|
+
/** @property {number} [damping=objectDefaultDamping] - How much to slow down velocity each frame (0-1) */
|
|
1528
1523
|
this.damping = objectDefaultDamping;
|
|
1529
|
-
/** @property {
|
|
1524
|
+
/** @property {number} [angleDamping=objectDefaultAngleDamping] - How much to slow down rotation each frame (0-1) */
|
|
1530
1525
|
this.angleDamping = objectDefaultAngleDamping;
|
|
1531
|
-
/** @property {
|
|
1526
|
+
/** @property {number} [elasticity=objectDefaultElasticity] - How bouncy the object is when colliding (0-1) */
|
|
1532
1527
|
this.elasticity = objectDefaultElasticity;
|
|
1533
|
-
/** @property {
|
|
1528
|
+
/** @property {number} [friction=objectDefaultFriction] - How much friction to apply when sliding (0-1) */
|
|
1534
1529
|
this.friction = objectDefaultFriction;
|
|
1535
|
-
/** @property {
|
|
1530
|
+
/** @property {number} - How much to scale gravity by for this object */
|
|
1536
1531
|
this.gravityScale = 1;
|
|
1537
|
-
/** @property {
|
|
1532
|
+
/** @property {number} - Objects are sorted by render order */
|
|
1538
1533
|
this.renderOrder = renderOrder;
|
|
1539
1534
|
/** @property {Vector2} - Velocity of the object */
|
|
1540
1535
|
this.velocity = vec2();
|
|
1541
|
-
/** @property {
|
|
1536
|
+
/** @property {number} - Angular velocity of the object */
|
|
1542
1537
|
this.angleVelocity = 0;
|
|
1543
|
-
/** @property {
|
|
1538
|
+
/** @property {number} - Track when object was created */
|
|
1544
1539
|
this.spawnTime = time;
|
|
1545
|
-
/** @property {Array} - List of children of this object */
|
|
1540
|
+
/** @property {Array<EngineObject>} - List of children of this object */
|
|
1546
1541
|
this.children = [];
|
|
1547
|
-
/** @property {
|
|
1542
|
+
/** @property {boolean} - Limit object speed using linear or circular math */
|
|
1548
1543
|
this.clampSpeedLinear = true;
|
|
1544
|
+
/** @property {EngineObject} - Object we are standing on, if any */
|
|
1545
|
+
this.groundObject = undefined;
|
|
1549
1546
|
|
|
1550
1547
|
// parent child system
|
|
1551
1548
|
/** @property {EngineObject} - Parent of object if in local space */
|
|
1552
1549
|
this.parent = undefined;
|
|
1553
1550
|
/** @property {Vector2} - Local position if child */
|
|
1554
1551
|
this.localPos = vec2();
|
|
1555
|
-
/** @property {
|
|
1552
|
+
/** @property {number} - Local angle if child */
|
|
1556
1553
|
this.localAngle = 0;
|
|
1557
1554
|
|
|
1558
1555
|
// collision flags
|
|
1559
|
-
/** @property {
|
|
1556
|
+
/** @property {boolean} - Object collides with the tile collision */
|
|
1560
1557
|
this.collideTiles = false;
|
|
1561
|
-
/** @property {
|
|
1558
|
+
/** @property {boolean} - Object collides with solid objects */
|
|
1562
1559
|
this.collideSolidObjects = false;
|
|
1563
|
-
/** @property {
|
|
1560
|
+
/** @property {boolean} - Object collides with and blocks other objects */
|
|
1564
1561
|
this.isSolid = false;
|
|
1565
|
-
/** @property {
|
|
1562
|
+
/** @property {boolean} - Object collides with raycasts */
|
|
1566
1563
|
this.collideRaycast = false;
|
|
1567
1564
|
|
|
1568
1565
|
// add to list of objects
|
|
@@ -1630,9 +1627,10 @@ class EngineObject
|
|
|
1630
1627
|
if (this.groundObject)
|
|
1631
1628
|
{
|
|
1632
1629
|
// apply friction in local space of ground object
|
|
1633
|
-
const groundSpeed = this.groundObject
|
|
1630
|
+
const groundSpeed = this.groundObject != this && this.groundObject.velocity ?
|
|
1631
|
+
this.groundObject.velocity.x : 0;
|
|
1634
1632
|
this.velocity.x = groundSpeed + (this.velocity.x - groundSpeed) * this.friction;
|
|
1635
|
-
this.groundObject =
|
|
1633
|
+
this.groundObject = undefined;
|
|
1636
1634
|
//debugOverlay && debugPhysics && debugPoint(this.pos.subtract(vec2(0,this.size.y/2)), '#0f0');
|
|
1637
1635
|
}
|
|
1638
1636
|
|
|
@@ -1749,18 +1747,22 @@ class EngineObject
|
|
|
1749
1747
|
// bounce velocity
|
|
1750
1748
|
this.velocity.y *= -this.elasticity;
|
|
1751
1749
|
|
|
1752
|
-
|
|
1753
|
-
if (this.groundObject = wasMovingDown)
|
|
1750
|
+
if (wasMovingDown)
|
|
1754
1751
|
{
|
|
1755
1752
|
// adjust position to slightly above nearest tile boundary
|
|
1756
1753
|
// this prevents gap between object and ground
|
|
1757
1754
|
const epsilon = .0001;
|
|
1758
1755
|
this.pos.y = (oldPos.y-this.size.y/2|0)+this.size.y/2+epsilon;
|
|
1756
|
+
|
|
1757
|
+
// set ground object to self for tile collision
|
|
1758
|
+
// TODO: rework system so tile collision is its own object
|
|
1759
|
+
this.groundObject = this;
|
|
1759
1760
|
}
|
|
1760
1761
|
else
|
|
1761
1762
|
{
|
|
1762
1763
|
// move to previous position
|
|
1763
1764
|
this.pos.y = oldPos.y;
|
|
1765
|
+
this.groundObject = undefined;
|
|
1764
1766
|
}
|
|
1765
1767
|
}
|
|
1766
1768
|
if (isBlockedX)
|
|
@@ -1812,19 +1814,19 @@ class EngineObject
|
|
|
1812
1814
|
worldToLocalVector(vec) { return vec.rotate(-this.angle); }
|
|
1813
1815
|
|
|
1814
1816
|
/** Called to check if a tile collision should be resolved
|
|
1815
|
-
* @param {
|
|
1817
|
+
* @param {number} tileData - the value of the tile at the position
|
|
1816
1818
|
* @param {Vector2} pos - tile where the collision occurred
|
|
1817
|
-
* @return {
|
|
1819
|
+
* @return {boolean} - true if the collision should be resolved */
|
|
1818
1820
|
collideWithTile(tileData, pos) { return tileData > 0; }
|
|
1819
1821
|
|
|
1820
1822
|
/** Called to check if a object collision should be resolved
|
|
1821
1823
|
* @param {EngineObject} object - the object to test against
|
|
1822
|
-
* @return {
|
|
1824
|
+
* @return {boolean} - true if the collision should be resolved
|
|
1823
1825
|
*/
|
|
1824
1826
|
collideWithObject(object) { return true; }
|
|
1825
1827
|
|
|
1826
1828
|
/** How long since the object was created
|
|
1827
|
-
* @return {
|
|
1829
|
+
* @return {number} */
|
|
1828
1830
|
getAliveTime() { return time - this.spawnTime; }
|
|
1829
1831
|
|
|
1830
1832
|
/** Apply acceleration to this object (adjust velocity, not affected by mass)
|
|
@@ -1836,13 +1838,13 @@ class EngineObject
|
|
|
1836
1838
|
applyForce(force) { this.applyAcceleration(force.scale(1/this.mass)); }
|
|
1837
1839
|
|
|
1838
1840
|
/** Get the direction of the mirror
|
|
1839
|
-
* @return {
|
|
1841
|
+
* @return {number} -1 if this.mirror is true, or 1 if not mirrored */
|
|
1840
1842
|
getMirrorSign() { return this.mirror ? -1 : 1; }
|
|
1841
1843
|
|
|
1842
1844
|
/** Attaches a child to this with a given local transform
|
|
1843
1845
|
* @param {EngineObject} child
|
|
1844
1846
|
* @param {Vector2} [localPos=(0,0)]
|
|
1845
|
-
* @param {
|
|
1847
|
+
* @param {number} [localAngle] */
|
|
1846
1848
|
addChild(child, localPos=vec2(), localAngle=0)
|
|
1847
1849
|
{
|
|
1848
1850
|
ASSERT(!child.parent && !this.children.includes(child));
|
|
@@ -1862,10 +1864,10 @@ class EngineObject
|
|
|
1862
1864
|
}
|
|
1863
1865
|
|
|
1864
1866
|
/** Set how this object collides
|
|
1865
|
-
* @param {
|
|
1866
|
-
* @param {
|
|
1867
|
-
* @param {
|
|
1868
|
-
* @param {
|
|
1867
|
+
* @param {boolean} [collideSolidObjects] - Does it collide with solid objects?
|
|
1868
|
+
* @param {boolean} [isSolid] - Does it collide with and block other objects? (expensive in large numbers)
|
|
1869
|
+
* @param {boolean} [collideTiles] - Does it collide with the tile collision?
|
|
1870
|
+
* @param {boolean} [collideRaycast] - Does it collide with raycasts? */
|
|
1869
1871
|
setCollision(collideSolidObjects=true, isSolid=true, collideTiles=true, collideRaycast=true)
|
|
1870
1872
|
{
|
|
1871
1873
|
ASSERT(collideSolidObjects || !isSolid, 'solid objects must be set to collide');
|
|
@@ -1877,7 +1879,7 @@ class EngineObject
|
|
|
1877
1879
|
}
|
|
1878
1880
|
|
|
1879
1881
|
/** Returns string containing info about this object for debugging
|
|
1880
|
-
* @return {
|
|
1882
|
+
* @return {string} */
|
|
1881
1883
|
toString()
|
|
1882
1884
|
{
|
|
1883
1885
|
if (debug)
|
|
@@ -1975,10 +1977,10 @@ let drawCount;
|
|
|
1975
1977
|
* Create a tile info object using a grid based system
|
|
1976
1978
|
* - This can take vecs or floats for easier use and conversion
|
|
1977
1979
|
* - If an index is passed in, the tile size and index will determine the position
|
|
1978
|
-
* @param {
|
|
1979
|
-
* @param {
|
|
1980
|
-
* @param {
|
|
1981
|
-
* @param {
|
|
1980
|
+
* @param {Vector2|number} [pos=0] - Index of tile in sheet
|
|
1981
|
+
* @param {Vector2|number} [size=tileSizeDefault] - Size of tile in pixels
|
|
1982
|
+
* @param {number} [textureIndex] - Texture index to use
|
|
1983
|
+
* @param {number} [padding] - How many pixels padding around tiles
|
|
1982
1984
|
* @return {TileInfo}
|
|
1983
1985
|
* @example
|
|
1984
1986
|
* tile(2) // a tile at index 2 using the default tile size of 16
|
|
@@ -2022,8 +2024,8 @@ class TileInfo
|
|
|
2022
2024
|
/** Create a tile info object
|
|
2023
2025
|
* @param {Vector2} [pos=(0,0)] - Top left corner of tile in pixels
|
|
2024
2026
|
* @param {Vector2} [size=tileSizeDefault] - Size of tile in pixels
|
|
2025
|
-
* @param {
|
|
2026
|
-
* @param {
|
|
2027
|
+
* @param {number} [textureIndex] - Texture index to use
|
|
2028
|
+
* @param {number} [padding] - How many pixels padding around tiles
|
|
2027
2029
|
*/
|
|
2028
2030
|
constructor(pos=vec2(), size=tileSizeDefault, textureIndex=0, padding=0)
|
|
2029
2031
|
{
|
|
@@ -2031,9 +2033,9 @@ class TileInfo
|
|
|
2031
2033
|
this.pos = pos.copy();
|
|
2032
2034
|
/** @property {Vector2} - Size of tile in pixels */
|
|
2033
2035
|
this.size = size.copy();
|
|
2034
|
-
/** @property {
|
|
2036
|
+
/** @property {number} - Texture index to use */
|
|
2035
2037
|
this.textureIndex = textureIndex;
|
|
2036
|
-
/** @property {
|
|
2038
|
+
/** @property {number} - How many pixels padding around tiles */
|
|
2037
2039
|
this.padding = padding;
|
|
2038
2040
|
}
|
|
2039
2041
|
|
|
@@ -2045,7 +2047,7 @@ class TileInfo
|
|
|
2045
2047
|
{ return new TileInfo(this.pos.add(offset), this.size, this.textureIndex); }
|
|
2046
2048
|
|
|
2047
2049
|
/** Returns a copy of this tile offset by a number of animation frames
|
|
2048
|
-
* @param {
|
|
2050
|
+
* @param {number} frame - Offset to apply in animation frames
|
|
2049
2051
|
* @return {TileInfo}
|
|
2050
2052
|
*/
|
|
2051
2053
|
frame(frame)
|
|
@@ -2117,11 +2119,11 @@ function getCameraSize() { return mainCanvasSize.scale(1/cameraScale); }
|
|
|
2117
2119
|
* @param {Vector2} [size=(1,1)] - Size of the tile in world space
|
|
2118
2120
|
* @param {TileInfo}[tileInfo] - Tile info to use, untextured if undefined
|
|
2119
2121
|
* @param {Color} [color=(1,1,1,1)] - Color to modulate with
|
|
2120
|
-
* @param {
|
|
2121
|
-
* @param {
|
|
2122
|
+
* @param {number} [angle] - Angle to rotate by
|
|
2123
|
+
* @param {boolean} [mirror] - If true image is flipped along the Y axis
|
|
2122
2124
|
* @param {Color} [additiveColor=(0,0,0,0)] - Additive color to be applied
|
|
2123
|
-
* @param {
|
|
2124
|
-
* @param {
|
|
2125
|
+
* @param {boolean} [useWebGL=glEnable] - Use accelerated WebGL rendering
|
|
2126
|
+
* @param {boolean} [screenSpace=false] - If true the pos and size are in screen space
|
|
2125
2127
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context] - Canvas 2D context to draw to
|
|
2126
2128
|
* @memberof Draw */
|
|
2127
2129
|
function drawTile(pos, size=vec2(1), tileInfo, color=new Color,
|
|
@@ -2196,9 +2198,9 @@ function drawTile(pos, size=vec2(1), tileInfo, color=new Color,
|
|
|
2196
2198
|
* @param {Vector2} pos
|
|
2197
2199
|
* @param {Vector2} [size=(1,1)]
|
|
2198
2200
|
* @param {Color} [color=(1,1,1,1)]
|
|
2199
|
-
* @param {
|
|
2200
|
-
* @param {
|
|
2201
|
-
* @param {
|
|
2201
|
+
* @param {number} [angle]
|
|
2202
|
+
* @param {boolean} [useWebGL=glEnable]
|
|
2203
|
+
* @param {boolean} [screenSpace=false]
|
|
2202
2204
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
|
|
2203
2205
|
* @memberof Draw */
|
|
2204
2206
|
function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
|
|
@@ -2209,10 +2211,10 @@ function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
|
|
|
2209
2211
|
/** Draw colored line between two points
|
|
2210
2212
|
* @param {Vector2} posA
|
|
2211
2213
|
* @param {Vector2} posB
|
|
2212
|
-
* @param {
|
|
2214
|
+
* @param {number} [thickness]
|
|
2213
2215
|
* @param {Color} [color=(1,1,1,1)]
|
|
2214
|
-
* @param {
|
|
2215
|
-
* @param {
|
|
2216
|
+
* @param {boolean} [useWebGL=glEnable]
|
|
2217
|
+
* @param {boolean} [screenSpace=false]
|
|
2216
2218
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
|
|
2217
2219
|
* @memberof Draw */
|
|
2218
2220
|
function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace, context)
|
|
@@ -2223,11 +2225,11 @@ function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace, contex
|
|
|
2223
2225
|
}
|
|
2224
2226
|
|
|
2225
2227
|
/** Draw colored polygon using passed in points
|
|
2226
|
-
* @param {Array} points - Array of Vector2 points
|
|
2228
|
+
* @param {Array<Vector2>} points - Array of Vector2 points
|
|
2227
2229
|
* @param {Color} [color=(1,1,1,1)]
|
|
2228
|
-
* @param {
|
|
2230
|
+
* @param {number} [lineWidth=0]
|
|
2229
2231
|
* @param {Color} [lineColor=(0,0,0,1)]
|
|
2230
|
-
* @param {
|
|
2232
|
+
* @param {boolean} [screenSpace=false]
|
|
2231
2233
|
* @param {CanvasRenderingContext2D} [context=mainContext]
|
|
2232
2234
|
* @memberof Draw */
|
|
2233
2235
|
function drawPoly(points, color=new Color, lineWidth=0, lineColor=new Color(0,0,0), screenSpace, context=mainContext)
|
|
@@ -2249,13 +2251,13 @@ function drawPoly(points, color=new Color, lineWidth=0, lineColor=new Color(0,0,
|
|
|
2249
2251
|
|
|
2250
2252
|
/** Draw colored ellipse using passed in point
|
|
2251
2253
|
* @param {Vector2} pos
|
|
2252
|
-
* @param {
|
|
2253
|
-
* @param {
|
|
2254
|
-
* @param {
|
|
2254
|
+
* @param {number} [width=1]
|
|
2255
|
+
* @param {number} [height=1]
|
|
2256
|
+
* @param {number} [angle=0]
|
|
2255
2257
|
* @param {Color} [color=(1,1,1,1)]
|
|
2256
|
-
* @param {
|
|
2258
|
+
* @param {number} [lineWidth=0]
|
|
2257
2259
|
* @param {Color} [lineColor=(0,0,0,1)]
|
|
2258
|
-
* @param {
|
|
2260
|
+
* @param {boolean} [screenSpace=false]
|
|
2259
2261
|
* @param {CanvasRenderingContext2D} [context=mainContext]
|
|
2260
2262
|
* @memberof Draw */
|
|
2261
2263
|
function drawEllipse(pos, width=1, height=1, angle=0, color=new Color, lineWidth=0, lineColor=new Color(0,0,0), screenSpace, context=mainContext)
|
|
@@ -2282,11 +2284,11 @@ function drawEllipse(pos, width=1, height=1, angle=0, color=new Color, lineWidth
|
|
|
2282
2284
|
|
|
2283
2285
|
/** Draw colored circle using passed in point
|
|
2284
2286
|
* @param {Vector2} pos
|
|
2285
|
-
* @param {
|
|
2287
|
+
* @param {number} [radius=1]
|
|
2286
2288
|
* @param {Color} [color=(1,1,1,1)]
|
|
2287
|
-
* @param {
|
|
2289
|
+
* @param {number} [lineWidth=0]
|
|
2288
2290
|
* @param {Color} [lineColor=(0,0,0,1)]
|
|
2289
|
-
* @param {
|
|
2291
|
+
* @param {boolean} [screenSpace=false]
|
|
2290
2292
|
* @param {CanvasRenderingContext2D} [context=mainContext]
|
|
2291
2293
|
* @memberof Draw */
|
|
2292
2294
|
function drawCircle(pos, radius=1, color=new Color, lineWidth=0, lineColor=new Color(0,0,0), screenSpace, context=mainContext)
|
|
@@ -2295,10 +2297,10 @@ function drawCircle(pos, radius=1, color=new Color, lineWidth=0, lineColor=new C
|
|
|
2295
2297
|
/** Draw directly to a 2d canvas context in world space
|
|
2296
2298
|
* @param {Vector2} pos
|
|
2297
2299
|
* @param {Vector2} size
|
|
2298
|
-
* @param {
|
|
2299
|
-
* @param {
|
|
2300
|
+
* @param {number} angle
|
|
2301
|
+
* @param {boolean} mirror
|
|
2300
2302
|
* @param {Function} drawFunction
|
|
2301
|
-
* @param {
|
|
2303
|
+
* @param {boolean} [screenSpace=false]
|
|
2302
2304
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=mainContext]
|
|
2303
2305
|
* @memberof Draw */
|
|
2304
2306
|
function drawCanvas2D(pos, size, angle, mirror, drawFunction, screenSpace, context=mainContext)
|
|
@@ -2319,15 +2321,15 @@ function drawCanvas2D(pos, size, angle, mirror, drawFunction, screenSpace, conte
|
|
|
2319
2321
|
|
|
2320
2322
|
/** Draw text on main canvas in world space
|
|
2321
2323
|
* Automatically splits new lines into rows
|
|
2322
|
-
* @param {
|
|
2324
|
+
* @param {string} text
|
|
2323
2325
|
* @param {Vector2} pos
|
|
2324
|
-
* @param {
|
|
2326
|
+
* @param {number} [size]
|
|
2325
2327
|
* @param {Color} [color=(1,1,1,1)]
|
|
2326
|
-
* @param {
|
|
2328
|
+
* @param {number} [lineWidth]
|
|
2327
2329
|
* @param {Color} [lineColor=(0,0,0,1)]
|
|
2328
2330
|
* @param {CanvasTextAlign} [textAlign='center']
|
|
2329
|
-
* @param {
|
|
2330
|
-
* @param {
|
|
2331
|
+
* @param {string} [font=fontDefault]
|
|
2332
|
+
* @param {number} [maxWidth]
|
|
2331
2333
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=mainContext]
|
|
2332
2334
|
* @memberof Draw */
|
|
2333
2335
|
function drawText(text, pos, size=1, color, lineWidth=0, lineColor, textAlign, font, maxWidth, context=mainContext)
|
|
@@ -2337,15 +2339,15 @@ function drawText(text, pos, size=1, color, lineWidth=0, lineColor, textAlign, f
|
|
|
2337
2339
|
|
|
2338
2340
|
/** Draw text on overlay canvas in world space
|
|
2339
2341
|
* Automatically splits new lines into rows
|
|
2340
|
-
* @param {
|
|
2342
|
+
* @param {string} text
|
|
2341
2343
|
* @param {Vector2} pos
|
|
2342
|
-
* @param {
|
|
2344
|
+
* @param {number} [size]
|
|
2343
2345
|
* @param {Color} [color=(1,1,1,1)]
|
|
2344
|
-
* @param {
|
|
2346
|
+
* @param {number} [lineWidth]
|
|
2345
2347
|
* @param {Color} [lineColor=(0,0,0,1)]
|
|
2346
2348
|
* @param {CanvasTextAlign} [textAlign='center']
|
|
2347
|
-
* @param {
|
|
2348
|
-
* @param {
|
|
2349
|
+
* @param {string} [font=fontDefault]
|
|
2350
|
+
* @param {number} [maxWidth]
|
|
2349
2351
|
* @memberof Draw */
|
|
2350
2352
|
function drawTextOverlay(text, pos, size=1, color, lineWidth=0, lineColor, textAlign, font, maxWidth)
|
|
2351
2353
|
{
|
|
@@ -2354,15 +2356,15 @@ function drawTextOverlay(text, pos, size=1, color, lineWidth=0, lineColor, textA
|
|
|
2354
2356
|
|
|
2355
2357
|
/** Draw text on overlay canvas in screen space
|
|
2356
2358
|
* Automatically splits new lines into rows
|
|
2357
|
-
* @param {
|
|
2359
|
+
* @param {string} text
|
|
2358
2360
|
* @param {Vector2} pos
|
|
2359
|
-
* @param {
|
|
2361
|
+
* @param {number} [size]
|
|
2360
2362
|
* @param {Color} [color=(1,1,1,1)]
|
|
2361
|
-
* @param {
|
|
2363
|
+
* @param {number} [lineWidth]
|
|
2362
2364
|
* @param {Color} [lineColor=(0,0,0,1)]
|
|
2363
2365
|
* @param {CanvasTextAlign} [textAlign]
|
|
2364
|
-
* @param {
|
|
2365
|
-
* @param {
|
|
2366
|
+
* @param {string} [font=fontDefault]
|
|
2367
|
+
* @param {number} [maxWidth]
|
|
2366
2368
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=overlayContext]
|
|
2367
2369
|
* @memberof Draw */
|
|
2368
2370
|
function drawTextScreen(text, pos, size=1, color=new Color, lineWidth=0, lineColor=new Color(0,0,0), textAlign='center', font=fontDefault, maxWidth=undefined, context=overlayContext)
|
|
@@ -2388,8 +2390,8 @@ function drawTextScreen(text, pos, size=1, color=new Color, lineWidth=0, lineCol
|
|
|
2388
2390
|
}
|
|
2389
2391
|
|
|
2390
2392
|
/** Enable normal or additive blend mode
|
|
2391
|
-
* @param {
|
|
2392
|
-
* @param {
|
|
2393
|
+
* @param {boolean} [additive]
|
|
2394
|
+
* @param {boolean} [useWebGL=glEnable]
|
|
2393
2395
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=mainContext]
|
|
2394
2396
|
* @memberof Draw */
|
|
2395
2397
|
function setBlendMode(additive, useWebGL=glEnable, context)
|
|
@@ -2456,10 +2458,10 @@ class FontImage
|
|
|
2456
2458
|
}
|
|
2457
2459
|
|
|
2458
2460
|
/** Draw text in world space using the image font
|
|
2459
|
-
* @param {
|
|
2461
|
+
* @param {string} text
|
|
2460
2462
|
* @param {Vector2} pos
|
|
2461
|
-
* @param {
|
|
2462
|
-
* @param {
|
|
2463
|
+
* @param {number} [scale=.25]
|
|
2464
|
+
* @param {boolean} [center]
|
|
2463
2465
|
*/
|
|
2464
2466
|
drawText(text, pos, scale=1, center)
|
|
2465
2467
|
{
|
|
@@ -2467,10 +2469,10 @@ class FontImage
|
|
|
2467
2469
|
}
|
|
2468
2470
|
|
|
2469
2471
|
/** Draw text in screen space using the image font
|
|
2470
|
-
* @param {
|
|
2472
|
+
* @param {string} text
|
|
2471
2473
|
* @param {Vector2} pos
|
|
2472
|
-
* @param {
|
|
2473
|
-
* @param {
|
|
2474
|
+
* @param {number} [scale]
|
|
2475
|
+
* @param {boolean} [center]
|
|
2474
2476
|
*/
|
|
2475
2477
|
drawTextScreen(text, pos, scale=4, center)
|
|
2476
2478
|
{
|
|
@@ -2508,7 +2510,7 @@ class FontImage
|
|
|
2508
2510
|
// Display functions
|
|
2509
2511
|
|
|
2510
2512
|
/** Returns true if fullscreen mode is active
|
|
2511
|
-
* @return {
|
|
2513
|
+
* @return {boolean}
|
|
2512
2514
|
* @memberof Draw */
|
|
2513
2515
|
function isFullscreen() { return !!document.fullscreenElement; }
|
|
2514
2516
|
|
|
@@ -2527,7 +2529,7 @@ function toggleFullscreen()
|
|
|
2527
2529
|
}
|
|
2528
2530
|
|
|
2529
2531
|
/** Set the cursor style
|
|
2530
|
-
* @param {
|
|
2532
|
+
* @param {string} cursorStyle - CSS cursor style (auto, none, crosshair, etc)
|
|
2531
2533
|
* @memberof Draw */
|
|
2532
2534
|
function setCursor(cursorStyle = 'auto')
|
|
2533
2535
|
{
|
|
@@ -2547,9 +2549,9 @@ function setCursor(cursorStyle = 'auto')
|
|
|
2547
2549
|
|
|
2548
2550
|
|
|
2549
2551
|
/** Returns true if device key is down
|
|
2550
|
-
* @param {
|
|
2551
|
-
* @param {
|
|
2552
|
-
* @return {
|
|
2552
|
+
* @param {string|number} key
|
|
2553
|
+
* @param {number} [device]
|
|
2554
|
+
* @return {boolean}
|
|
2553
2555
|
* @memberof Input */
|
|
2554
2556
|
function keyIsDown(key, device=0)
|
|
2555
2557
|
{
|
|
@@ -2558,9 +2560,9 @@ function keyIsDown(key, device=0)
|
|
|
2558
2560
|
}
|
|
2559
2561
|
|
|
2560
2562
|
/** Returns true if device key was pressed this frame
|
|
2561
|
-
* @param {
|
|
2562
|
-
* @param {
|
|
2563
|
-
* @return {
|
|
2563
|
+
* @param {string|number} key
|
|
2564
|
+
* @param {number} [device]
|
|
2565
|
+
* @return {boolean}
|
|
2564
2566
|
* @memberof Input */
|
|
2565
2567
|
function keyWasPressed(key, device=0)
|
|
2566
2568
|
{
|
|
@@ -2569,9 +2571,9 @@ function keyWasPressed(key, device=0)
|
|
|
2569
2571
|
}
|
|
2570
2572
|
|
|
2571
2573
|
/** Returns true if device key was released this frame
|
|
2572
|
-
* @param {
|
|
2573
|
-
* @param {
|
|
2574
|
-
* @return {
|
|
2574
|
+
* @param {string|number} key
|
|
2575
|
+
* @param {number} [device]
|
|
2576
|
+
* @return {boolean}
|
|
2575
2577
|
* @memberof Input */
|
|
2576
2578
|
function keyWasReleased(key, device=0)
|
|
2577
2579
|
{
|
|
@@ -2594,22 +2596,22 @@ function clearInput() { inputData = [[]]; touchGamepadButtons = []; }
|
|
|
2594
2596
|
|
|
2595
2597
|
/** Returns true if mouse button is down
|
|
2596
2598
|
* @function
|
|
2597
|
-
* @param {
|
|
2598
|
-
* @return {
|
|
2599
|
+
* @param {number} button
|
|
2600
|
+
* @return {boolean}
|
|
2599
2601
|
* @memberof Input */
|
|
2600
2602
|
const mouseIsDown = keyIsDown;
|
|
2601
2603
|
|
|
2602
2604
|
/** Returns true if mouse button was pressed
|
|
2603
2605
|
* @function
|
|
2604
|
-
* @param {
|
|
2605
|
-
* @return {
|
|
2606
|
+
* @param {number} button
|
|
2607
|
+
* @return {boolean}
|
|
2606
2608
|
* @memberof Input */
|
|
2607
2609
|
const mouseWasPressed = keyWasPressed;
|
|
2608
2610
|
|
|
2609
2611
|
/** Returns true if mouse button was released
|
|
2610
2612
|
* @function
|
|
2611
|
-
* @param {
|
|
2612
|
-
* @return {
|
|
2613
|
+
* @param {number} button
|
|
2614
|
+
* @return {boolean}
|
|
2613
2615
|
* @memberof Input */
|
|
2614
2616
|
const mouseWasReleased = keyWasReleased;
|
|
2615
2617
|
|
|
@@ -2624,47 +2626,53 @@ let mousePos = vec2();
|
|
|
2624
2626
|
let mousePosScreen = vec2();
|
|
2625
2627
|
|
|
2626
2628
|
/** Mouse wheel delta this frame
|
|
2627
|
-
* @type {
|
|
2629
|
+
* @type {number}
|
|
2628
2630
|
* @memberof Input */
|
|
2629
2631
|
let mouseWheel = 0;
|
|
2630
2632
|
|
|
2631
2633
|
/** Returns true if user is using gamepad (has more recently pressed a gamepad button)
|
|
2632
|
-
* @type {
|
|
2634
|
+
* @type {boolean}
|
|
2633
2635
|
* @memberof Input */
|
|
2634
2636
|
let isUsingGamepad = false;
|
|
2635
2637
|
|
|
2636
|
-
/** Prevents input continuing to the default browser handling (
|
|
2637
|
-
* @type {
|
|
2638
|
+
/** Prevents input continuing to the default browser handling (true by default)
|
|
2639
|
+
* @type {boolean}
|
|
2638
2640
|
* @memberof Input */
|
|
2639
|
-
let
|
|
2641
|
+
let inputPreventDefault = true;
|
|
2642
|
+
|
|
2643
|
+
/** Prevents input continuing to the default browser handling
|
|
2644
|
+
* This is useful to disable for html menus so the browser can handle input normally
|
|
2645
|
+
* @param {boolean} preventDefault
|
|
2646
|
+
* @memberof Input */
|
|
2647
|
+
function setInputPreventDefault(preventDefault) { inputPreventDefault = preventDefault; }
|
|
2640
2648
|
|
|
2641
2649
|
/** Returns true if gamepad button is down
|
|
2642
|
-
* @param {
|
|
2643
|
-
* @param {
|
|
2644
|
-
* @return {
|
|
2650
|
+
* @param {number} button
|
|
2651
|
+
* @param {number} [gamepad]
|
|
2652
|
+
* @return {boolean}
|
|
2645
2653
|
* @memberof Input */
|
|
2646
2654
|
function gamepadIsDown(button, gamepad=0)
|
|
2647
2655
|
{ return keyIsDown(button, gamepad+1); }
|
|
2648
2656
|
|
|
2649
2657
|
/** Returns true if gamepad button was pressed
|
|
2650
|
-
* @param {
|
|
2651
|
-
* @param {
|
|
2652
|
-
* @return {
|
|
2658
|
+
* @param {number} button
|
|
2659
|
+
* @param {number} [gamepad]
|
|
2660
|
+
* @return {boolean}
|
|
2653
2661
|
* @memberof Input */
|
|
2654
2662
|
function gamepadWasPressed(button, gamepad=0)
|
|
2655
2663
|
{ return keyWasPressed(button, gamepad+1); }
|
|
2656
2664
|
|
|
2657
2665
|
/** Returns true if gamepad button was released
|
|
2658
|
-
* @param {
|
|
2659
|
-
* @param {
|
|
2660
|
-
* @return {
|
|
2666
|
+
* @param {number} button
|
|
2667
|
+
* @param {number} [gamepad]
|
|
2668
|
+
* @return {boolean}
|
|
2661
2669
|
* @memberof Input */
|
|
2662
2670
|
function gamepadWasReleased(button, gamepad=0)
|
|
2663
2671
|
{ return keyWasReleased(button, gamepad+1); }
|
|
2664
2672
|
|
|
2665
2673
|
/** Returns gamepad stick value
|
|
2666
|
-
* @param {
|
|
2667
|
-
* @param {
|
|
2674
|
+
* @param {number} stick
|
|
2675
|
+
* @param {number} [gamepad]
|
|
2668
2676
|
* @return {Vector2}
|
|
2669
2677
|
* @memberof Input */
|
|
2670
2678
|
function gamepadStick(stick, gamepad=0)
|
|
@@ -2716,7 +2724,6 @@ function inputInit()
|
|
|
2716
2724
|
if (inputWASDEmulateDirection)
|
|
2717
2725
|
inputData[0][remapKey(e.code)] = 3;
|
|
2718
2726
|
}
|
|
2719
|
-
preventDefaultInput && e.preventDefault();
|
|
2720
2727
|
}
|
|
2721
2728
|
|
|
2722
2729
|
onkeyup = (e)=>
|
|
@@ -2746,7 +2753,7 @@ function inputInit()
|
|
|
2746
2753
|
isUsingGamepad = false;
|
|
2747
2754
|
inputData[0][e.button] = 3;
|
|
2748
2755
|
mousePosScreen = mouseEventToScreen(e);
|
|
2749
|
-
e.button && e.preventDefault();
|
|
2756
|
+
inputPreventDefault && e.button && e.preventDefault();
|
|
2750
2757
|
}
|
|
2751
2758
|
onmouseup = (e)=> inputData[0][e.button] = inputData[0][e.button] & 2 | 4;
|
|
2752
2759
|
onmousemove = (e)=> mousePosScreen = mouseEventToScreen(e);
|
|
@@ -2867,7 +2874,7 @@ function gamepadsUpdate()
|
|
|
2867
2874
|
///////////////////////////////////////////////////////////////////////////////
|
|
2868
2875
|
|
|
2869
2876
|
/** Pulse the vibration hardware if it exists
|
|
2870
|
-
* @param {
|
|
2877
|
+
* @param {number|Array} [pattern] - single value in ms or vibration interval array
|
|
2871
2878
|
* @memberof Input */
|
|
2872
2879
|
function vibrate(pattern=100)
|
|
2873
2880
|
{ vibrateEnable && !headlessMode && navigator && navigator.vibrate && navigator.vibrate(pattern); }
|
|
@@ -2930,7 +2937,7 @@ function touchInputInit()
|
|
|
2930
2937
|
wasTouching = touching;
|
|
2931
2938
|
|
|
2932
2939
|
// prevent default handling like copy and magnifier lens
|
|
2933
|
-
if (document.hasFocus()) // allow document to get focus
|
|
2940
|
+
if (inputPreventDefault && document.hasFocus()) // allow document to get focus
|
|
2934
2941
|
e.preventDefault();
|
|
2935
2942
|
|
|
2936
2943
|
// must return true so the document will get focus
|
|
@@ -3102,20 +3109,20 @@ class Sound
|
|
|
3102
3109
|
{
|
|
3103
3110
|
/** Create a sound object and cache the zzfx samples for later use
|
|
3104
3111
|
* @param {Array} zzfxSound - Array of zzfx parameters, ex. [.5,.5]
|
|
3105
|
-
* @param {
|
|
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
|
|
@@ -4506,8 +4513,9 @@ class Medal
|
|
|
4506
4513
|
{
|
|
4507
4514
|
const context = overlayContext;
|
|
4508
4515
|
const width = min(medalDisplaySize.x, mainCanvas.width);
|
|
4516
|
+
const height = medalDisplaySize.y;
|
|
4509
4517
|
const x = overlayCanvas.width - width;
|
|
4510
|
-
const y = -
|
|
4518
|
+
const y = -height*hidePercent;
|
|
4511
4519
|
|
|
4512
4520
|
// draw containing rect and clip to that region
|
|
4513
4521
|
context.save();
|
|
@@ -4515,25 +4523,34 @@ class Medal
|
|
|
4515
4523
|
context.fillStyle = new Color(.9,.9,.9).toString();
|
|
4516
4524
|
context.strokeStyle = new Color(0,0,0).toString();
|
|
4517
4525
|
context.lineWidth = 3;
|
|
4518
|
-
context.rect(x, y, width,
|
|
4526
|
+
context.rect(x, y, width, height);
|
|
4519
4527
|
context.fill();
|
|
4520
4528
|
context.stroke();
|
|
4521
4529
|
context.clip();
|
|
4522
4530
|
|
|
4523
|
-
// draw the icon
|
|
4524
|
-
|
|
4525
|
-
const
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4531
|
+
// draw the icon
|
|
4532
|
+
const gap = vec2(.1, .05).scale(height);
|
|
4533
|
+
const medalDisplayIconSize = height - 2*gap.x;
|
|
4534
|
+
this.renderIcon(vec2(x + gap.x + medalDisplayIconSize/2, y + height/2), medalDisplayIconSize);
|
|
4535
|
+
|
|
4536
|
+
// draw the name
|
|
4537
|
+
const nameSize = height*.5;
|
|
4538
|
+
const descriptionSize = height*.3;
|
|
4539
|
+
const pos = vec2(x + medalDisplayIconSize + 2*gap.x, y + gap.y*2 + nameSize/2);
|
|
4540
|
+
const textWidth = width - medalDisplayIconSize - 3*gap.x;
|
|
4541
|
+
drawTextScreen(this.name, pos, nameSize, new Color(0,0,0), 0, undefined, 'left', undefined, textWidth);
|
|
4542
|
+
|
|
4543
|
+
// draw the description
|
|
4544
|
+
pos.y = y + height - gap.y*2 - descriptionSize/2;
|
|
4545
|
+
drawTextScreen(this.description, pos, descriptionSize, new Color(0,0,0), 0, undefined, 'left', undefined, textWidth);
|
|
4529
4546
|
context.restore();
|
|
4530
4547
|
}
|
|
4531
4548
|
|
|
4532
4549
|
/** Render the icon for a medal
|
|
4533
4550
|
* @param {Vector2} pos - Screen space position
|
|
4534
|
-
* @param {Number}
|
|
4551
|
+
* @param {Number} size - Screen space size
|
|
4535
4552
|
*/
|
|
4536
|
-
renderIcon(pos, size
|
|
4553
|
+
renderIcon(pos, size)
|
|
4537
4554
|
{
|
|
4538
4555
|
// draw the image or icon
|
|
4539
4556
|
if (this.image)
|
|
@@ -4570,7 +4587,7 @@ let glCanvas;
|
|
|
4570
4587
|
let glContext;
|
|
4571
4588
|
|
|
4572
4589
|
/** Should webgl be setup with anti-aliasing? must be set before calling engineInit
|
|
4573
|
-
* @type {
|
|
4590
|
+
* @type {boolean}
|
|
4574
4591
|
* @memberof WebGL */
|
|
4575
4592
|
let glAntialias = true;
|
|
4576
4593
|
|
|
@@ -4793,7 +4810,7 @@ function glFlush()
|
|
|
4793
4810
|
|
|
4794
4811
|
/** Draw any sprites still in the buffer and copy to main canvas
|
|
4795
4812
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} context
|
|
4796
|
-
* @param {
|
|
4813
|
+
* @param {boolean} [forceDraw]
|
|
4797
4814
|
* @memberof WebGL */
|
|
4798
4815
|
function glCopyToContext(context, forceDraw=false)
|
|
4799
4816
|
{
|
|
@@ -4807,7 +4824,7 @@ function glCopyToContext(context, forceDraw=false)
|
|
|
4807
4824
|
}
|
|
4808
4825
|
|
|
4809
4826
|
/** Set anti-aliasing for webgl canvas
|
|
4810
|
-
* @param {
|
|
4827
|
+
* @param {boolean} [antialias]
|
|
4811
4828
|
* @memberof WebGL */
|
|
4812
4829
|
function glSetAntialias(antialias=true)
|
|
4813
4830
|
{
|
|
@@ -4872,61 +4889,62 @@ function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba, rgbaAdd
|
|
|
4872
4889
|
|
|
4873
4890
|
|
|
4874
4891
|
/** Name of engine
|
|
4875
|
-
* @type {
|
|
4892
|
+
* @type {string}
|
|
4876
4893
|
* @default
|
|
4877
4894
|
* @memberof Engine */
|
|
4878
4895
|
const engineName = 'LittleJS';
|
|
4879
4896
|
|
|
4880
4897
|
/** Version of engine
|
|
4881
|
-
* @type {
|
|
4898
|
+
* @type {string}
|
|
4882
4899
|
* @default
|
|
4883
4900
|
* @memberof Engine */
|
|
4884
|
-
const engineVersion = '1.11.
|
|
4901
|
+
const engineVersion = '1.11.13';
|
|
4885
4902
|
|
|
4886
4903
|
/** Frames per second to update
|
|
4887
|
-
* @type {
|
|
4904
|
+
* @type {number}
|
|
4888
4905
|
* @default
|
|
4889
4906
|
* @memberof Engine */
|
|
4890
4907
|
const frameRate = 60;
|
|
4891
4908
|
|
|
4892
4909
|
/** How many seconds each frame lasts, engine uses a fixed time step
|
|
4893
|
-
* @type {
|
|
4910
|
+
* @type {number}
|
|
4894
4911
|
* @default 1/60
|
|
4895
4912
|
* @memberof Engine */
|
|
4896
4913
|
const timeDelta = 1/frameRate;
|
|
4897
4914
|
|
|
4898
4915
|
/** Array containing all engine objects
|
|
4899
|
-
* @type {Array}
|
|
4916
|
+
* @type {Array<EngineObject>}
|
|
4900
4917
|
* @memberof Engine */
|
|
4901
4918
|
let engineObjects = [];
|
|
4902
4919
|
|
|
4903
4920
|
/** Array with only objects set to collide with other objects this frame (for optimization)
|
|
4904
|
-
* @type {Array}
|
|
4921
|
+
* @type {Array<EngineObject>}
|
|
4905
4922
|
* @memberof Engine */
|
|
4906
4923
|
let engineObjectsCollide = [];
|
|
4907
4924
|
|
|
4908
4925
|
/** Current update frame, used to calculate time
|
|
4909
|
-
* @type {
|
|
4926
|
+
* @type {number}
|
|
4910
4927
|
* @memberof Engine */
|
|
4911
4928
|
let frame = 0;
|
|
4912
4929
|
|
|
4913
4930
|
/** Current engine time since start in seconds
|
|
4914
|
-
* @type {
|
|
4931
|
+
* @type {number}
|
|
4915
4932
|
* @memberof Engine */
|
|
4916
4933
|
let time = 0;
|
|
4917
4934
|
|
|
4918
4935
|
/** Actual clock time since start in seconds (not affected by pause or frame rate clamping)
|
|
4919
|
-
* @type {
|
|
4936
|
+
* @type {number}
|
|
4920
4937
|
* @memberof Engine */
|
|
4921
4938
|
let timeReal = 0;
|
|
4922
4939
|
|
|
4923
4940
|
/** Is the game paused? Causes time and objects to not be updated
|
|
4924
|
-
* @type {
|
|
4941
|
+
* @type {boolean}
|
|
4925
4942
|
* @default false
|
|
4926
4943
|
* @memberof Engine */
|
|
4927
4944
|
let paused = false;
|
|
4945
|
+
|
|
4928
4946
|
/** Set if game is paused
|
|
4929
|
-
* @param {
|
|
4947
|
+
* @param {boolean} isPaused
|
|
4930
4948
|
* @memberof Engine */
|
|
4931
4949
|
function setPaused(isPaused) { paused = isPaused; }
|
|
4932
4950
|
|
|
@@ -4959,7 +4977,7 @@ function engineAddPlugin(updateFunction, renderFunction)
|
|
|
4959
4977
|
* @param {Function} gameUpdatePost - Called after physics and objects are updated, even when paused
|
|
4960
4978
|
* @param {Function} gameRender - Called before objects are rendered, for drawing the background
|
|
4961
4979
|
* @param {Function} gameRenderPost - Called after objects are rendered, useful for drawing UI
|
|
4962
|
-
* @param {Array} [imageSources=[]] - List of images to load
|
|
4980
|
+
* @param {Array<string>} [imageSources=[]] - List of images to load
|
|
4963
4981
|
* @param {HTMLElement} [rootElement] - Root element to attach to, the document body by default
|
|
4964
4982
|
* @memberof Engine */
|
|
4965
4983
|
function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, imageSources=[], rootElement=document.body)
|
|
@@ -5255,9 +5273,9 @@ function engineObjectsDestroy()
|
|
|
5255
5273
|
|
|
5256
5274
|
/** Collects all object within a given area
|
|
5257
5275
|
* @param {Vector2} [pos] - Center of test area, or undefined for all objects
|
|
5258
|
-
* @param {
|
|
5259
|
-
* @param {Array} [objects=engineObjects] - List of objects to check
|
|
5260
|
-
* @return {Array} - List of collected objects
|
|
5276
|
+
* @param {Vector2|number} [size] - Radius of circle if float, rectangle size if Vector2
|
|
5277
|
+
* @param {Array<EngineObject>} [objects=engineObjects] - List of objects to check
|
|
5278
|
+
* @return {Array<EngineObject>} - List of collected objects
|
|
5261
5279
|
* @memberof Engine */
|
|
5262
5280
|
function engineObjectsCollect(pos, size, objects=engineObjects)
|
|
5263
5281
|
{
|
|
@@ -5283,9 +5301,9 @@ function engineObjectsCollect(pos, size, objects=engineObjects)
|
|
|
5283
5301
|
|
|
5284
5302
|
/** Triggers a callback for each object within a given area
|
|
5285
5303
|
* @param {Vector2} [pos] - Center of test area, or undefined for all objects
|
|
5286
|
-
* @param {
|
|
5304
|
+
* @param {Vector2|number} [size] - Radius of circle if float, rectangle size if Vector2
|
|
5287
5305
|
* @param {Function} [callbackFunction] - Calls this function on every object that passes the test
|
|
5288
|
-
* @param {Array} [objects=engineObjects] - List of objects to check
|
|
5306
|
+
* @param {Array<EngineObject>} [objects=engineObjects] - List of objects to check
|
|
5289
5307
|
* @memberof Engine */
|
|
5290
5308
|
function engineObjectsCallback(pos, size, callbackFunction, objects=engineObjects)
|
|
5291
5309
|
{ engineObjectsCollect(pos, size, objects).forEach(o => callbackFunction(o)); }
|
|
@@ -5293,8 +5311,8 @@ function engineObjectsCallback(pos, size, callbackFunction, objects=engineObject
|
|
|
5293
5311
|
/** Return a list of objects intersecting a ray
|
|
5294
5312
|
* @param {Vector2} start
|
|
5295
5313
|
* @param {Vector2} end
|
|
5296
|
-
* @param {Array} [objects=engineObjects] - List of objects to check
|
|
5297
|
-
* @return {Array} - List of objects hit
|
|
5314
|
+
* @param {Array<EngineObject>} [objects=engineObjects] - List of objects to check
|
|
5315
|
+
* @return {Array<EngineObject>} - List of objects hit
|
|
5298
5316
|
* @memberof Engine */
|
|
5299
5317
|
function engineObjectsRaycast(start, end, objects=engineObjects)
|
|
5300
5318
|
{
|