littlejsengine 1.9.0 → 1.9.2
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 +7 -7
- package/{build → dist}/littlejs.d.ts +84 -77
- package/{build → dist}/littlejs.esm.js +245 -143
- package/dist/littlejs.esm.min.js +1 -0
- package/{build → dist}/littlejs.js +245 -143
- package/dist/littlejs.min.js +1 -0
- package/{build → dist}/littlejs.release.js +239 -141
- package/examples/breakout/game.js +2 -2
- package/examples/breakout/gameObjects.js +3 -3
- package/examples/breakout/index.html +3 -3
- package/examples/breakoutTutorial/index.html +2 -2
- package/examples/electron/build.js +1 -1
- package/examples/electron/game.js +49 -38
- package/examples/electron/index.html +2 -2
- package/examples/electron/tiles.png +0 -0
- package/examples/empty/index.html +1 -1
- package/examples/js13k/build.js +2 -2
- package/examples/js13k/game.js +10 -9
- package/examples/js13k/index.html +13 -13
- package/examples/js13k/tiles.png +0 -0
- package/examples/module/game.js +45 -41
- package/examples/module/index.html +1 -1
- package/examples/module/tiles.png +0 -0
- package/examples/particles/index.html +1 -1
- package/examples/platformer/data/gameTileData.tmx +143 -0
- package/examples/platformer/data/gameTileData.tsx +4 -0
- package/examples/platformer/game.js +0 -1
- package/examples/platformer/gameCharacter.js +1 -1
- package/examples/platformer/gameEffects.js +42 -110
- package/examples/platformer/gameLevel.js +149 -183
- package/examples/platformer/gameObjects.js +61 -16
- package/examples/platformer/gamePlayer.js +3 -2
- package/examples/platformer/gameTileData.js +181 -0
- package/examples/platformer/index.html +8 -7
- package/examples/platformer/tiles.png +0 -0
- package/examples/platformer/tilesLevel.png +0 -0
- package/examples/puzzle/game.js +12 -12
- package/examples/puzzle/index.html +2 -2
- package/examples/starter/build.js +2 -2
- package/examples/starter/game.js +6 -6
- package/examples/starter/index.html +13 -13
- package/examples/starter/tiles.png +0 -0
- package/examples/stress/index.html +2 -2
- package/examples/typescript/build.bat +4 -1
- package/examples/typescript/game.js +34 -31
- package/examples/typescript/game.ts +40 -36
- package/examples/typescript/index.html +1 -1
- package/examples/typescript/tiles.png +0 -0
- package/package.json +3 -3
- package/src/engine.js +1 -1
- package/src/engineAudio.js +4 -10
- package/src/engineBuild.js +9 -2
- package/src/engineDebug.js +6 -2
- package/src/engineDraw.js +27 -27
- package/src/engineInput.js +7 -7
- package/src/engineMedals.js +2 -2
- package/src/engineObject.js +7 -7
- package/src/engineParticles.js +9 -9
- package/src/engineTileLayer.js +38 -33
- package/src/engineUtilities.js +136 -35
- package/src/engineWebGL.js +8 -10
- package/build/littlejs.esm.min.js +0 -1
- package/build/littlejs.min.js +0 -1
|
@@ -156,13 +156,13 @@ function smoothStep(percent) { return percent * percent * (3 - 2 * percent); }
|
|
|
156
156
|
function nearestPowerOfTwo(value) { return 2**Math.ceil(Math.log2(value)); }
|
|
157
157
|
|
|
158
158
|
/** Returns true if two axis aligned bounding boxes are overlapping
|
|
159
|
-
* @param {Vector2} pointA
|
|
160
|
-
* @param {Vector2} sizeA
|
|
161
|
-
* @param {Vector2} pointB
|
|
162
|
-
* @param {Vector2} sizeB
|
|
163
|
-
* @return {Boolean}
|
|
159
|
+
* @param {Vector2} pointA - Center of box A
|
|
160
|
+
* @param {Vector2} sizeA - Size of box A
|
|
161
|
+
* @param {Vector2} pointB - Center of box B
|
|
162
|
+
* @param {Vector2} [sizeB=(0,0)] - Size of box B, a point if undefined
|
|
163
|
+
* @return {Boolean} - True if overlapping
|
|
164
164
|
* @memberof Utilities */
|
|
165
|
-
function isOverlapping(pointA, sizeA, pointB, sizeB)
|
|
165
|
+
function isOverlapping(pointA, sizeA, pointB, sizeB=vec2())
|
|
166
166
|
{
|
|
167
167
|
return abs(pointA.x - pointB.x)*2 < sizeA.x + sizeB.x
|
|
168
168
|
&& abs(pointA.y - pointB.y)*2 < sizeA.y + sizeB.y;
|
|
@@ -222,8 +222,8 @@ function randInCircle(radius=1, minRadius=0)
|
|
|
222
222
|
{ return radius > 0 ? randVector(radius * rand(minRadius / radius, 1)**.5) : new Vector2; }
|
|
223
223
|
|
|
224
224
|
/** Returns a random color between the two passed in colors, combine components if linear
|
|
225
|
-
* @param {Color} [colorA=
|
|
226
|
-
* @param {Color} [colorB=
|
|
225
|
+
* @param {Color} [colorA=(1,1,1,1)]
|
|
226
|
+
* @param {Color} [colorB=(0,0,0,1)]
|
|
227
227
|
* @param {Boolean} [linear]
|
|
228
228
|
* @return {Color}
|
|
229
229
|
* @memberof Random */
|
|
@@ -294,7 +294,11 @@ class RandomGenerator
|
|
|
294
294
|
* @memberof Utilities
|
|
295
295
|
*/
|
|
296
296
|
function vec2(x=0, y)
|
|
297
|
-
{
|
|
297
|
+
{
|
|
298
|
+
return typeof x === 'number' ?
|
|
299
|
+
new Vector2(x, y == undefined? x : y) :
|
|
300
|
+
new Vector2(x.x, x.y);
|
|
301
|
+
}
|
|
298
302
|
|
|
299
303
|
/**
|
|
300
304
|
* Check if object is a valid Vector2
|
|
@@ -302,7 +306,7 @@ function vec2(x=0, y)
|
|
|
302
306
|
* @return {Boolean}
|
|
303
307
|
* @memberof Utilities
|
|
304
308
|
*/
|
|
305
|
-
function isVector2(v) { return
|
|
309
|
+
function isVector2(v) { return v instanceof Vector2; }
|
|
306
310
|
|
|
307
311
|
/**
|
|
308
312
|
* 2D Vector object with vector math library
|
|
@@ -333,27 +337,47 @@ class Vector2
|
|
|
333
337
|
/** Returns a copy of this vector plus the vector passed in
|
|
334
338
|
* @param {Vector2} v - other vector
|
|
335
339
|
* @return {Vector2} */
|
|
336
|
-
add(v)
|
|
340
|
+
add(v)
|
|
341
|
+
{
|
|
342
|
+
ASSERT(isVector2(v));
|
|
343
|
+
return new Vector2(this.x + v.x, this.y + v.y);
|
|
344
|
+
}
|
|
337
345
|
|
|
338
346
|
/** Returns a copy of this vector minus the vector passed in
|
|
339
347
|
* @param {Vector2} v - other vector
|
|
340
348
|
* @return {Vector2} */
|
|
341
|
-
subtract(v)
|
|
349
|
+
subtract(v)
|
|
350
|
+
{
|
|
351
|
+
ASSERT(isVector2(v));
|
|
352
|
+
return new Vector2(this.x - v.x, this.y - v.y);
|
|
353
|
+
}
|
|
342
354
|
|
|
343
355
|
/** Returns a copy of this vector times the vector passed in
|
|
344
356
|
* @param {Vector2} v - other vector
|
|
345
357
|
* @return {Vector2} */
|
|
346
|
-
multiply(v)
|
|
358
|
+
multiply(v)
|
|
359
|
+
{
|
|
360
|
+
ASSERT(isVector2(v));
|
|
361
|
+
return new Vector2(this.x * v.x, this.y * v.y);
|
|
362
|
+
}
|
|
347
363
|
|
|
348
364
|
/** Returns a copy of this vector divided by the vector passed in
|
|
349
365
|
* @param {Vector2} v - other vector
|
|
350
366
|
* @return {Vector2} */
|
|
351
|
-
divide(v)
|
|
367
|
+
divide(v)
|
|
368
|
+
{
|
|
369
|
+
ASSERT(isVector2(v));
|
|
370
|
+
return new Vector2(this.x / v.x, this.y / v.y);
|
|
371
|
+
}
|
|
352
372
|
|
|
353
373
|
/** Returns a copy of this vector scaled by the vector passed in
|
|
354
374
|
* @param {Number} s - scale
|
|
355
375
|
* @return {Vector2} */
|
|
356
|
-
scale(s)
|
|
376
|
+
scale(s)
|
|
377
|
+
{
|
|
378
|
+
ASSERT(!isVector2(s));
|
|
379
|
+
return new Vector2(this.x * s, this.y * s);
|
|
380
|
+
}
|
|
357
381
|
|
|
358
382
|
/** Returns the length of this vector
|
|
359
383
|
* @return {Number} */
|
|
@@ -366,32 +390,56 @@ class Vector2
|
|
|
366
390
|
/** Returns the distance from this vector to vector passed in
|
|
367
391
|
* @param {Vector2} v - other vector
|
|
368
392
|
* @return {Number} */
|
|
369
|
-
distance(v)
|
|
393
|
+
distance(v)
|
|
394
|
+
{
|
|
395
|
+
ASSERT(isVector2(v));
|
|
396
|
+
return this.distanceSquared(v)**.5;
|
|
397
|
+
}
|
|
370
398
|
|
|
371
399
|
/** Returns the distance squared from this vector to vector passed in
|
|
372
400
|
* @param {Vector2} v - other vector
|
|
373
401
|
* @return {Number} */
|
|
374
|
-
distanceSquared(v)
|
|
402
|
+
distanceSquared(v)
|
|
403
|
+
{
|
|
404
|
+
ASSERT(isVector2(v));
|
|
405
|
+
return (this.x - v.x)**2 + (this.y - v.y)**2;
|
|
406
|
+
}
|
|
375
407
|
|
|
376
408
|
/** Returns a new vector in same direction as this one with the length passed in
|
|
377
409
|
* @param {Number} [length]
|
|
378
410
|
* @return {Vector2} */
|
|
379
|
-
normalize(length=1)
|
|
411
|
+
normalize(length=1)
|
|
412
|
+
{
|
|
413
|
+
const l = this.length();
|
|
414
|
+
return l ? this.scale(length/l) : new Vector2(0, length);
|
|
415
|
+
}
|
|
380
416
|
|
|
381
417
|
/** Returns a new vector clamped to length passed in
|
|
382
418
|
* @param {Number} [length]
|
|
383
419
|
* @return {Vector2} */
|
|
384
|
-
clampLength(length=1)
|
|
420
|
+
clampLength(length=1)
|
|
421
|
+
{
|
|
422
|
+
const l = this.length();
|
|
423
|
+
return l > length ? this.scale(length/l) : this;
|
|
424
|
+
}
|
|
385
425
|
|
|
386
426
|
/** Returns the dot product of this and the vector passed in
|
|
387
427
|
* @param {Vector2} v - other vector
|
|
388
428
|
* @return {Number} */
|
|
389
|
-
dot(v)
|
|
429
|
+
dot(v)
|
|
430
|
+
{
|
|
431
|
+
ASSERT(isVector2(v));
|
|
432
|
+
return this.x*v.x + this.y*v.y;
|
|
433
|
+
}
|
|
390
434
|
|
|
391
435
|
/** Returns the cross product of this and the vector passed in
|
|
392
436
|
* @param {Vector2} v - other vector
|
|
393
437
|
* @return {Number} */
|
|
394
|
-
cross(v)
|
|
438
|
+
cross(v)
|
|
439
|
+
{
|
|
440
|
+
ASSERT(isVector2(v));
|
|
441
|
+
return this.x*v.y - this.y*v.x;
|
|
442
|
+
}
|
|
395
443
|
|
|
396
444
|
/** Returns the angle of this vector, up is angle 0
|
|
397
445
|
* @return {Number} */
|
|
@@ -402,7 +450,11 @@ class Vector2
|
|
|
402
450
|
* @param {Number} [length]
|
|
403
451
|
* @return {Vector2} */
|
|
404
452
|
setAngle(angle=0, length=1)
|
|
405
|
-
{
|
|
453
|
+
{
|
|
454
|
+
this.x = length*Math.sin(angle);
|
|
455
|
+
this.y = length*Math.cos(angle);
|
|
456
|
+
return this;
|
|
457
|
+
}
|
|
406
458
|
|
|
407
459
|
/** Returns copy of this vector rotated by the angle passed in
|
|
408
460
|
* @param {Number} angle
|
|
@@ -413,9 +465,20 @@ class Vector2
|
|
|
413
465
|
return new Vector2(this.x*c - this.y*s, this.x*s + this.y*c);
|
|
414
466
|
}
|
|
415
467
|
|
|
468
|
+
/** Set the integer direction of this vector, corrosponding to multiples of 90 degree rotation (0-3)
|
|
469
|
+
* @param {Number} [direction]
|
|
470
|
+
* @param {Number} [length] */
|
|
471
|
+
setDirection(direction, length=1)
|
|
472
|
+
{
|
|
473
|
+
ASSERT(direction==0 || direction==1 || direction==2 || direction==3);
|
|
474
|
+
return vec2(direction%2 ? direction-1 ? -length : length : 0,
|
|
475
|
+
direction%2 ? 0 : direction ? -length : length);
|
|
476
|
+
}
|
|
477
|
+
|
|
416
478
|
/** Returns the integer direction of this vector, corrosponding to multiples of 90 degree rotation (0-3)
|
|
417
479
|
* @return {Number} */
|
|
418
|
-
direction()
|
|
480
|
+
direction()
|
|
481
|
+
{ return abs(this.x) > abs(this.y) ? this.x < 0 ? 3 : 1 : this.y < 0 ? 2 : 0; }
|
|
419
482
|
|
|
420
483
|
/** Returns a copy of this vector that has been inverted
|
|
421
484
|
* @return {Vector2} */
|
|
@@ -434,24 +497,34 @@ class Vector2
|
|
|
434
497
|
* @param {Number} percent
|
|
435
498
|
* @return {Vector2} */
|
|
436
499
|
lerp(v, percent)
|
|
437
|
-
{
|
|
500
|
+
{
|
|
501
|
+
ASSERT(isVector2(v));
|
|
502
|
+
return this.add(v.subtract(this).scale(clamp(percent)));
|
|
503
|
+
}
|
|
438
504
|
|
|
439
505
|
/** Returns true if this vector is within the bounds of an array size passed in
|
|
440
506
|
* @param {Vector2} arraySize
|
|
441
507
|
* @return {Boolean} */
|
|
442
|
-
arrayCheck(arraySize)
|
|
508
|
+
arrayCheck(arraySize)
|
|
509
|
+
{
|
|
510
|
+
ASSERT(isVector2(arraySize));
|
|
511
|
+
return this.x >= 0 && this.y >= 0 && this.x < arraySize.x && this.y < arraySize.y;
|
|
512
|
+
}
|
|
443
513
|
|
|
444
514
|
/** Returns this vector expressed as a string
|
|
445
515
|
* @param {Number} digits - precision to display
|
|
446
516
|
* @return {String} */
|
|
447
517
|
toString(digits=3)
|
|
448
|
-
{
|
|
518
|
+
{
|
|
519
|
+
if (debug)
|
|
520
|
+
return `(${(this.x<0?'':' ') + this.x.toFixed(digits)},${(this.y<0?'':' ') + this.y.toFixed(digits)} )`;
|
|
521
|
+
}
|
|
449
522
|
}
|
|
450
523
|
|
|
451
524
|
///////////////////////////////////////////////////////////////////////////////
|
|
452
525
|
|
|
453
526
|
/**
|
|
454
|
-
* Create a color object with RGBA values
|
|
527
|
+
* Create a color object with RGBA values, white by default
|
|
455
528
|
* @param {Number} [r=1] - red
|
|
456
529
|
* @param {Number} [g=1] - green
|
|
457
530
|
* @param {Number} [b=1] - blue
|
|
@@ -462,7 +535,7 @@ class Vector2
|
|
|
462
535
|
function rgb(r, g, b, a) { return new Color(r, g, b, a); }
|
|
463
536
|
|
|
464
537
|
/**
|
|
465
|
-
* Create a color object with HSLA values
|
|
538
|
+
* Create a color object with HSLA values, white by default
|
|
466
539
|
* @param {Number} [h=0] - hue
|
|
467
540
|
* @param {Number} [s=0] - saturation
|
|
468
541
|
* @param {Number} [l=1] - lightness
|
|
@@ -472,14 +545,22 @@ function rgb(r, g, b, a) { return new Color(r, g, b, a); }
|
|
|
472
545
|
*/
|
|
473
546
|
function hsl(h, s, l, a) { return new Color().setHSLA(h, s, l, a); }
|
|
474
547
|
|
|
548
|
+
/**
|
|
549
|
+
* Check if object is a valid Color
|
|
550
|
+
* @param {any} c
|
|
551
|
+
* @return {Boolean}
|
|
552
|
+
* @memberof Utilities
|
|
553
|
+
*/
|
|
554
|
+
function isColor(c) { return c instanceof Color; }
|
|
555
|
+
|
|
475
556
|
/**
|
|
476
557
|
* Color object (red, green, blue, alpha) with some helpful functions
|
|
477
558
|
* @example
|
|
478
559
|
* let a = new Color; // white
|
|
479
560
|
* let b = new Color(1, 0, 0); // red
|
|
480
561
|
* let c = new Color(0, 0, 0, 0); // transparent black
|
|
481
|
-
* let d =
|
|
482
|
-
* let e =
|
|
562
|
+
* let d = rgb(0, 0, 1); // blue using rgb color
|
|
563
|
+
* let e = hsl(.3, 1, .5); // green using hsl color
|
|
483
564
|
*/
|
|
484
565
|
class Color
|
|
485
566
|
{
|
|
@@ -507,22 +588,38 @@ class Color
|
|
|
507
588
|
/** Returns a copy of this color plus the color passed in
|
|
508
589
|
* @param {Color} c - other color
|
|
509
590
|
* @return {Color} */
|
|
510
|
-
add(c)
|
|
591
|
+
add(c)
|
|
592
|
+
{
|
|
593
|
+
ASSERT(isColor(c));
|
|
594
|
+
return new Color(this.r+c.r, this.g+c.g, this.b+c.b, this.a+c.a);
|
|
595
|
+
}
|
|
511
596
|
|
|
512
597
|
/** Returns a copy of this color minus the color passed in
|
|
513
598
|
* @param {Color} c - other color
|
|
514
599
|
* @return {Color} */
|
|
515
|
-
subtract(c)
|
|
600
|
+
subtract(c)
|
|
601
|
+
{
|
|
602
|
+
ASSERT(isColor(c));
|
|
603
|
+
return new Color(this.r-c.r, this.g-c.g, this.b-c.b, this.a-c.a);
|
|
604
|
+
}
|
|
516
605
|
|
|
517
606
|
/** Returns a copy of this color times the color passed in
|
|
518
607
|
* @param {Color} c - other color
|
|
519
608
|
* @return {Color} */
|
|
520
|
-
multiply(c)
|
|
609
|
+
multiply(c)
|
|
610
|
+
{
|
|
611
|
+
ASSERT(isColor(c));
|
|
612
|
+
return new Color(this.r*c.r, this.g*c.g, this.b*c.b, this.a*c.a);
|
|
613
|
+
}
|
|
521
614
|
|
|
522
615
|
/** Returns a copy of this color divided by the color passed in
|
|
523
616
|
* @param {Color} c - other color
|
|
524
617
|
* @return {Color} */
|
|
525
|
-
divide(c)
|
|
618
|
+
divide(c)
|
|
619
|
+
{
|
|
620
|
+
ASSERT(isColor(c));
|
|
621
|
+
return new Color(this.r/c.r, this.g/c.g, this.b/c.b, this.a/c.a);
|
|
622
|
+
}
|
|
526
623
|
|
|
527
624
|
/** Returns a copy of this color scaled by the value passed in, alpha can be scaled separately
|
|
528
625
|
* @param {Number} scale
|
|
@@ -539,7 +636,11 @@ class Color
|
|
|
539
636
|
* @param {Color} c - other color
|
|
540
637
|
* @param {Number} percent
|
|
541
638
|
* @return {Color} */
|
|
542
|
-
lerp(c, percent)
|
|
639
|
+
lerp(c, percent)
|
|
640
|
+
{
|
|
641
|
+
ASSERT(isColor(c));
|
|
642
|
+
return this.add(c.subtract(this).scale(clamp(percent)));
|
|
643
|
+
}
|
|
543
644
|
|
|
544
645
|
/** Sets this color given a hue, saturation, lightness, and alpha
|
|
545
646
|
* @param {Number} [h] - hue
|
|
@@ -1179,12 +1280,12 @@ function setDebugKey(key) { debugKey = key; }
|
|
|
1179
1280
|
class EngineObject
|
|
1180
1281
|
{
|
|
1181
1282
|
/** Create an engine object and adds it to the list of objects
|
|
1182
|
-
* @param {Vector2} [pos=
|
|
1183
|
-
* @param {Vector2} [size=
|
|
1184
|
-
* @param {TileInfo} [tileInfo]
|
|
1185
|
-
* @param {Number} [angle]
|
|
1186
|
-
* @param {Color} [color=
|
|
1187
|
-
* @param {Number} [renderOrder]
|
|
1283
|
+
* @param {Vector2} [pos=(0,0)] - World space position of the object
|
|
1284
|
+
* @param {Vector2} [size=(1,1)] - World space size of the object
|
|
1285
|
+
* @param {TileInfo} [tileInfo] - Tile info to render object (undefined is untextured)
|
|
1286
|
+
* @param {Number} [angle] - Angle the object is rotated by
|
|
1287
|
+
* @param {Color} [color=(1,1,1,1)] - Color to apply to tile when rendered
|
|
1288
|
+
* @param {Number} [renderOrder] - Objects sorted by renderOrder before being rendered
|
|
1188
1289
|
*/
|
|
1189
1290
|
constructor(pos=vec2(), size=vec2(1), tileInfo, angle=0, color, renderOrder=0)
|
|
1190
1291
|
{
|
|
@@ -1484,7 +1585,7 @@ class EngineObject
|
|
|
1484
1585
|
|
|
1485
1586
|
/** Attaches a child to this with a given local transform
|
|
1486
1587
|
* @param {EngineObject} child
|
|
1487
|
-
* @param {Vector2} [localPos=
|
|
1588
|
+
* @param {Vector2} [localPos=(0,0)]
|
|
1488
1589
|
* @param {Number} [localAngle] */
|
|
1489
1590
|
addChild(child, localPos=vec2(), localAngle=0)
|
|
1490
1591
|
{
|
|
@@ -1601,7 +1702,7 @@ let drawCount;
|
|
|
1601
1702
|
* Create a tile info object
|
|
1602
1703
|
* - This can take vecs or floats for easier use and conversion
|
|
1603
1704
|
* - If an index is passed in, the tile size and index will determine the position
|
|
1604
|
-
* @param {(Number|Vector2)} [pos=
|
|
1705
|
+
* @param {(Number|Vector2)} [pos=(0,0)] - Top left corner of tile in pixels or index
|
|
1605
1706
|
* @param {(Number|Vector2)} [size=tileSizeDefault] - Size of tile in pixels
|
|
1606
1707
|
* @param {Number} [textureIndex] - Texture index to use
|
|
1607
1708
|
* @return {TileInfo}
|
|
@@ -1644,7 +1745,7 @@ function tile(pos=vec2(), size=tileSizeDefault, textureIndex=0)
|
|
|
1644
1745
|
class TileInfo
|
|
1645
1746
|
{
|
|
1646
1747
|
/** Create a tile info object
|
|
1647
|
-
* @param {Vector2} [pos=
|
|
1748
|
+
* @param {Vector2} [pos=(0,0)] - Top left corner of tile in pixels
|
|
1648
1749
|
* @param {Vector2} [size=tileSizeDefault] - Size of tile in pixels
|
|
1649
1750
|
* @param {Number} [textureIndex] - Texture index to use
|
|
1650
1751
|
*/
|
|
@@ -1721,16 +1822,16 @@ function worldToScreen(worldPos)
|
|
|
1721
1822
|
}
|
|
1722
1823
|
|
|
1723
1824
|
/** Draw textured tile centered in world space, with color applied if using WebGL
|
|
1724
|
-
* @param {Vector2} pos
|
|
1725
|
-
* @param {Vector2} [size=
|
|
1726
|
-
* @param {TileInfo}[tileInfo]
|
|
1727
|
-
* @param {Color} [color=
|
|
1728
|
-
* @param {Number} [angle]
|
|
1729
|
-
* @param {Boolean} [mirror]
|
|
1730
|
-
* @param {Color} [additiveColor=
|
|
1731
|
-
* @param {Boolean} [useWebGL=glEnable]
|
|
1732
|
-
* @param {Boolean} [screenSpace]
|
|
1733
|
-
* @param {CanvasRenderingContext2D} [context]
|
|
1825
|
+
* @param {Vector2} pos - Center of the tile in world space
|
|
1826
|
+
* @param {Vector2} [size=(1,1)] - Size of the tile in world space
|
|
1827
|
+
* @param {TileInfo}[tileInfo] - Tile info to use, untextured if undefined
|
|
1828
|
+
* @param {Color} [color=(1,1,1,1)] - Color to modulate with
|
|
1829
|
+
* @param {Number} [angle] - Angle to rotate by
|
|
1830
|
+
* @param {Boolean} [mirror] - If true image is flipped along the Y axis
|
|
1831
|
+
* @param {Color} [additiveColor=(0,0,0,0)] - Additive color to be applied
|
|
1832
|
+
* @param {Boolean} [useWebGL=glEnable] - Use accelerated WebGL rendering
|
|
1833
|
+
* @param {Boolean} [screenSpace=false] - If true the pos and size are in screen space
|
|
1834
|
+
* @param {CanvasRenderingContext2D} [context] - Canvas 2D context to draw to
|
|
1734
1835
|
* @memberof Draw */
|
|
1735
1836
|
function drawTile(pos, size=vec2(1), tileInfo, color=new Color,
|
|
1736
1837
|
angle=0, mirror, additiveColor=new Color(0,0,0,0), useWebGL=glEnable, screenSpace, context)
|
|
@@ -1798,11 +1899,11 @@ function drawTile(pos, size=vec2(1), tileInfo, color=new Color,
|
|
|
1798
1899
|
|
|
1799
1900
|
/** Draw colored rect centered on pos
|
|
1800
1901
|
* @param {Vector2} pos
|
|
1801
|
-
* @param {Vector2} [size=
|
|
1802
|
-
* @param {Color} [color=
|
|
1902
|
+
* @param {Vector2} [size=(1,1)]
|
|
1903
|
+
* @param {Color} [color=(1,1,1,1)]
|
|
1803
1904
|
* @param {Number} [angle]
|
|
1804
1905
|
* @param {Boolean} [useWebGL=glEnable]
|
|
1805
|
-
* @param {Boolean} [screenSpace]
|
|
1906
|
+
* @param {Boolean} [screenSpace=false]
|
|
1806
1907
|
* @param {CanvasRenderingContext2D} [context]
|
|
1807
1908
|
* @memberof Draw */
|
|
1808
1909
|
function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
|
|
@@ -1812,8 +1913,8 @@ function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
|
|
|
1812
1913
|
|
|
1813
1914
|
/** Draw colored polygon using passed in points
|
|
1814
1915
|
* @param {Array} points - Array of Vector2 points
|
|
1815
|
-
* @param {Color} [color=
|
|
1816
|
-
* @param {Boolean} [screenSpace]
|
|
1916
|
+
* @param {Color} [color=(1,1,1,1)]
|
|
1917
|
+
* @param {Boolean} [screenSpace=false]
|
|
1817
1918
|
* @param {CanvasRenderingContext2D} [context=mainContext]
|
|
1818
1919
|
* @memberof Draw */
|
|
1819
1920
|
function drawPoly(points, color=new Color, screenSpace, context=mainContext)
|
|
@@ -1829,9 +1930,9 @@ function drawPoly(points, color=new Color, screenSpace, context=mainContext)
|
|
|
1829
1930
|
* @param {Vector2} posA
|
|
1830
1931
|
* @param {Vector2} posB
|
|
1831
1932
|
* @param {Number} [thickness]
|
|
1832
|
-
* @param {Color} [color=
|
|
1933
|
+
* @param {Color} [color=(1,1,1,1)]
|
|
1833
1934
|
* @param {Boolean} [useWebGL=glEnable]
|
|
1834
|
-
* @param {Boolean} [screenSpace]
|
|
1935
|
+
* @param {Boolean} [screenSpace=false]
|
|
1835
1936
|
* @param {CanvasRenderingContext2D} [context]
|
|
1836
1937
|
* @memberof Draw */
|
|
1837
1938
|
function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace, context)
|
|
@@ -1847,7 +1948,7 @@ function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace, contex
|
|
|
1847
1948
|
* @param {Number} angle
|
|
1848
1949
|
* @param {Boolean} mirror
|
|
1849
1950
|
* @param {Function} drawFunction
|
|
1850
|
-
* @param {Boolean} [screenSpace]
|
|
1951
|
+
* @param {Boolean} [screenSpace=false]
|
|
1851
1952
|
* @param {CanvasRenderingContext2D} [context=mainContext]
|
|
1852
1953
|
* @memberof Draw */
|
|
1853
1954
|
function drawCanvas2D(pos, size, angle, mirror, drawFunction, screenSpace, context=mainContext)
|
|
@@ -1889,9 +1990,9 @@ function setBlendMode(additive, useWebGL=glEnable, context)
|
|
|
1889
1990
|
* @param {String} text
|
|
1890
1991
|
* @param {Vector2} pos
|
|
1891
1992
|
* @param {Number} [size]
|
|
1892
|
-
* @param {Color} [color=
|
|
1993
|
+
* @param {Color} [color=(1,1,1,1)]
|
|
1893
1994
|
* @param {Number} [lineWidth]
|
|
1894
|
-
* @param {Color} [lineColor=
|
|
1995
|
+
* @param {Color} [lineColor=(0,0,0,1)]
|
|
1895
1996
|
* @param {CanvasTextAlign} [textAlign='center']
|
|
1896
1997
|
* @param {String} [font=fontDefault]
|
|
1897
1998
|
* @param {CanvasRenderingContext2D} [context=overlayContext]
|
|
@@ -1906,9 +2007,9 @@ function drawText(text, pos, size=1, color, lineWidth=0, lineColor, textAlign, f
|
|
|
1906
2007
|
* @param {String} text
|
|
1907
2008
|
* @param {Vector2} pos
|
|
1908
2009
|
* @param {Number} [size]
|
|
1909
|
-
* @param {Color} [color=
|
|
2010
|
+
* @param {Color} [color=(1,1,1,1)]
|
|
1910
2011
|
* @param {Number} [lineWidth]
|
|
1911
|
-
* @param {Color} [lineColor=
|
|
2012
|
+
* @param {Color} [lineColor=(0,0,0,1)]
|
|
1912
2013
|
* @param {CanvasTextAlign} [textAlign]
|
|
1913
2014
|
* @param {String} [font=fontDefault]
|
|
1914
2015
|
* @param {CanvasRenderingContext2D} [context=overlayContext]
|
|
@@ -1951,9 +2052,9 @@ let engineFontImage;
|
|
|
1951
2052
|
class FontImage
|
|
1952
2053
|
{
|
|
1953
2054
|
/** Create an image font
|
|
1954
|
-
* @param {HTMLImageElement} [image]
|
|
1955
|
-
* @param {Vector2} [tileSize=
|
|
1956
|
-
* @param {Vector2} [paddingSize=
|
|
2055
|
+
* @param {HTMLImageElement} [image] - Image for the font, if undefined default font is used
|
|
2056
|
+
* @param {Vector2} [tileSize=(8,8)] - Size of the font source tiles
|
|
2057
|
+
* @param {Vector2} [paddingSize=(0,1)] - How much extra space to add between characters
|
|
1957
2058
|
* @param {CanvasRenderingContext2D} [context=overlayContext] - context to draw to
|
|
1958
2059
|
*/
|
|
1959
2060
|
constructor(image, tileSize=vec2(8), paddingSize=vec2(0,1), context=overlayContext)
|
|
@@ -2231,10 +2332,10 @@ function inputUpdatePost()
|
|
|
2231
2332
|
///////////////////////////////////////////////////////////////////////////////
|
|
2232
2333
|
// Mouse event handlers
|
|
2233
2334
|
|
|
2234
|
-
onmousedown = (e)=> {isUsingGamepad = false; inputData[0][e.button] = 3;
|
|
2335
|
+
onmousedown = (e)=> {isUsingGamepad = false; inputData[0][e.button] = 3; mousePosScreen = mouseToScreen(e); e.button && e.preventDefault();}
|
|
2235
2336
|
onmouseup = (e)=> inputData[0][e.button] = inputData[0][e.button] & 2 | 4;
|
|
2236
2337
|
onmousemove = (e)=> mousePosScreen = mouseToScreen(e);
|
|
2237
|
-
onwheel = (e)=> e.ctrlKey
|
|
2338
|
+
onwheel = (e)=> mouseWheel = e.ctrlKey ? 0 : sign(e.deltaY);
|
|
2238
2339
|
oncontextmenu = (e)=> false; // prevent right click menu
|
|
2239
2340
|
|
|
2240
2341
|
// convert a mouse or touch event position to screen space
|
|
@@ -2328,7 +2429,7 @@ function gamepadsUpdate()
|
|
|
2328
2429
|
///////////////////////////////////////////////////////////////////////////////
|
|
2329
2430
|
|
|
2330
2431
|
/** Pulse the vibration hardware if it exists
|
|
2331
|
-
* @param {Number} [pattern] -
|
|
2432
|
+
* @param {Number|Array} [pattern] - single value in ms or vibration interval array
|
|
2332
2433
|
* @memberof Input */
|
|
2333
2434
|
function vibrate(pattern=100)
|
|
2334
2435
|
{ vibrateEnable && navigator && navigator.vibrate && navigator.vibrate(pattern); }
|
|
@@ -2354,9 +2455,9 @@ if (isTouchDevice)
|
|
|
2354
2455
|
// handle all touch events the same way
|
|
2355
2456
|
ontouchstart = ontouchmove = ontouchend = (e)=>
|
|
2356
2457
|
{
|
|
2357
|
-
// fix stalled audio
|
|
2358
|
-
if (soundEnable)
|
|
2359
|
-
|
|
2458
|
+
// fix stalled audio requiring user interaction
|
|
2459
|
+
if (soundEnable && audioContext && audioContext.state != 'running')
|
|
2460
|
+
zzfx(0);
|
|
2360
2461
|
|
|
2361
2462
|
// check if touching and pass to mouse events
|
|
2362
2463
|
const touching = e.touches.length;
|
|
@@ -2502,7 +2603,7 @@ function touchGamepadRender()
|
|
|
2502
2603
|
const rightCenter = vec2(mainCanvasSize.x-touchGamepadSize, mainCanvasSize.y-touchGamepadSize);
|
|
2503
2604
|
for (let i=4; i--;)
|
|
2504
2605
|
{
|
|
2505
|
-
const pos = rightCenter.add(vec2().
|
|
2606
|
+
const pos = rightCenter.add(vec2().setDirection(i, touchGamepadSize/2));
|
|
2506
2607
|
overlayContext.fillStyle = touchGamepadButtons[i] ? '#fff' : '#000';
|
|
2507
2608
|
overlayContext.beginPath();
|
|
2508
2609
|
overlayContext.arc(pos.x, pos.y, touchGamepadSize/4, 0,9);
|
|
@@ -2661,22 +2762,19 @@ class SoundWave extends Sound
|
|
|
2661
2762
|
this.randomness = randomness;
|
|
2662
2763
|
|
|
2663
2764
|
if (!soundEnable) return;
|
|
2664
|
-
if (!soundDecoderContext)
|
|
2665
|
-
soundDecoderContext = new AudioContext;
|
|
2666
2765
|
|
|
2667
2766
|
fetch(filename)
|
|
2668
2767
|
.then(response => response.arrayBuffer())
|
|
2669
|
-
.then(arrayBuffer =>
|
|
2768
|
+
.then(arrayBuffer => audioContext.decodeAudioData(arrayBuffer))
|
|
2670
2769
|
.then(audioBuffer =>
|
|
2671
2770
|
{
|
|
2672
2771
|
this.sampleChannels = [];
|
|
2673
2772
|
for (let i = audioBuffer.numberOfChannels; i--;)
|
|
2674
|
-
this.sampleChannels[i] = audioBuffer.getChannelData(i);
|
|
2773
|
+
this.sampleChannels[i] = Array.from(audioBuffer.getChannelData(i));
|
|
2675
2774
|
this.sampleRate = audioBuffer.sampleRate;
|
|
2676
2775
|
});
|
|
2677
2776
|
}
|
|
2678
2777
|
}
|
|
2679
|
-
let soundDecoderContext; // audio context used only to decode audio files
|
|
2680
2778
|
|
|
2681
2779
|
/**
|
|
2682
2780
|
* Music Object - Stores a zzfx music track for later use
|
|
@@ -2790,8 +2888,9 @@ function getNoteFrequency(semitoneOffset, rootFrequency=220)
|
|
|
2790
2888
|
///////////////////////////////////////////////////////////////////////////////
|
|
2791
2889
|
|
|
2792
2890
|
/** Audio context used by the engine
|
|
2891
|
+
* @type {AudioContext}
|
|
2793
2892
|
* @memberof Audio */
|
|
2794
|
-
let audioContext;
|
|
2893
|
+
let audioContext = new AudioContext;
|
|
2795
2894
|
|
|
2796
2895
|
/** Play cached audio samples with given settings
|
|
2797
2896
|
* @param {Array} sampleChannels - Array of arrays of samples to play (for stereo playback)
|
|
@@ -2806,10 +2905,6 @@ function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=false, sample
|
|
|
2806
2905
|
{
|
|
2807
2906
|
if (!soundEnable) return;
|
|
2808
2907
|
|
|
2809
|
-
// create audio context if needed
|
|
2810
|
-
if (!audioContext)
|
|
2811
|
-
audioContext = new AudioContext;
|
|
2812
|
-
|
|
2813
2908
|
// prevent sounds from building up if they can't be played
|
|
2814
2909
|
if (audioContext.state != 'running')
|
|
2815
2910
|
{
|
|
@@ -3135,7 +3230,7 @@ function getTileCollisionData(pos)
|
|
|
3135
3230
|
|
|
3136
3231
|
/** Check if collision with another object should occur
|
|
3137
3232
|
* @param {Vector2} pos
|
|
3138
|
-
* @param {Vector2} [size=
|
|
3233
|
+
* @param {Vector2} [size=(1,1)]
|
|
3139
3234
|
* @param {EngineObject} [object]
|
|
3140
3235
|
* @return {Boolean}
|
|
3141
3236
|
* @memberof TileCollision */
|
|
@@ -3220,7 +3315,7 @@ class TileLayerData
|
|
|
3220
3315
|
* @param {Number} [direction] - Integer direction of tile, in 90 degree increments
|
|
3221
3316
|
* @param {Boolean} [mirror] - If the tile should be mirrored along the x axis
|
|
3222
3317
|
* @param {Color} [color] - Color of the tile */
|
|
3223
|
-
constructor(tile, direction=0, mirror=false, color=new Color
|
|
3318
|
+
constructor(tile, direction=0, mirror=false, color=new Color)
|
|
3224
3319
|
{
|
|
3225
3320
|
/** @property {Number} - The tile to use, untextured if undefined */
|
|
3226
3321
|
this.tile = tile;
|
|
@@ -3251,11 +3346,11 @@ class TileLayerData
|
|
|
3251
3346
|
class TileLayer extends EngineObject
|
|
3252
3347
|
{
|
|
3253
3348
|
/** Create a tile layer object
|
|
3254
|
-
* @param {Vector2} [position=
|
|
3349
|
+
* @param {Vector2} [position=(0,0)] - World space position
|
|
3255
3350
|
* @param {Vector2} [size=tileCollisionSize] - World space size
|
|
3256
|
-
* @param {TileInfo} [tileInfo]
|
|
3257
|
-
* @param {Vector2} [scale=
|
|
3258
|
-
* @param {Number} [renderOrder]
|
|
3351
|
+
* @param {TileInfo} [tileInfo] - Tile info for layer
|
|
3352
|
+
* @param {Vector2} [scale=(1,1)] - How much to scale this layer when rendered
|
|
3353
|
+
* @param {Number} [renderOrder] - Objects are sorted by renderOrder
|
|
3259
3354
|
*/
|
|
3260
3355
|
constructor(position, size=tileCollisionSize, tileInfo=tile(), scale=vec2(1), renderOrder=0)
|
|
3261
3356
|
{
|
|
@@ -3316,16 +3411,18 @@ class TileLayer extends EngineObject
|
|
|
3316
3411
|
}
|
|
3317
3412
|
|
|
3318
3413
|
/** Draw all the tile data to an offscreen canvas
|
|
3319
|
-
* - This may be slow in some browsers
|
|
3320
|
-
*/
|
|
3414
|
+
* - This may be slow in some browsers but only needs to be done once */
|
|
3321
3415
|
redraw()
|
|
3322
3416
|
{
|
|
3323
3417
|
this.redrawStart(true);
|
|
3324
|
-
this.
|
|
3418
|
+
for (let x = this.size.x; x--;)
|
|
3419
|
+
for (let y = this.size.y; y--;)
|
|
3420
|
+
this.drawTileData(vec2(x,y), false);
|
|
3325
3421
|
this.redrawEnd();
|
|
3326
3422
|
}
|
|
3327
3423
|
|
|
3328
3424
|
/** Call to start the redraw process
|
|
3425
|
+
* - This can be used to manually update small parts of the level
|
|
3329
3426
|
* @param {Boolean} [clear] - Should it clear the canvas before drawing */
|
|
3330
3427
|
redrawStart(clear=false)
|
|
3331
3428
|
{
|
|
@@ -3333,17 +3430,19 @@ class TileLayer extends EngineObject
|
|
|
3333
3430
|
/** @type {[HTMLCanvasElement, CanvasRenderingContext2D, Vector2, Vector2, number]} */
|
|
3334
3431
|
this.savedRenderSettings = [mainCanvas, mainContext, mainCanvasSize, cameraPos, cameraScale];
|
|
3335
3432
|
|
|
3336
|
-
//
|
|
3433
|
+
// use webgl rendering system to render the tiles if enabled
|
|
3434
|
+
// this works by temporally taking control of the rendering system
|
|
3337
3435
|
mainCanvas = this.canvas;
|
|
3338
3436
|
mainContext = this.context;
|
|
3437
|
+
mainCanvasSize = this.size.multiply(this.tileInfo.size);
|
|
3339
3438
|
cameraPos = this.size.scale(.5);
|
|
3340
3439
|
cameraScale = this.tileInfo.size.x;
|
|
3341
3440
|
|
|
3342
3441
|
if (clear)
|
|
3343
3442
|
{
|
|
3344
3443
|
// clear and set size
|
|
3345
|
-
mainCanvas.width =
|
|
3346
|
-
mainCanvas.height =
|
|
3444
|
+
mainCanvas.width = mainCanvasSize.x;
|
|
3445
|
+
mainCanvas.height = mainCanvasSize.y;
|
|
3347
3446
|
}
|
|
3348
3447
|
|
|
3349
3448
|
// begin a new render for the tile canvas
|
|
@@ -3361,32 +3460,33 @@ class TileLayer extends EngineObject
|
|
|
3361
3460
|
[mainCanvas, mainContext, mainCanvasSize, cameraPos, cameraScale] = this.savedRenderSettings;
|
|
3362
3461
|
}
|
|
3363
3462
|
|
|
3364
|
-
/** Draw the tile at a given position
|
|
3365
|
-
*
|
|
3366
|
-
|
|
3463
|
+
/** Draw the tile at a given position in the tile grid
|
|
3464
|
+
* This can be used to clear out tiles when they are destroyed
|
|
3465
|
+
* Tiles can also be redrawn if isinde a redrawStart/End block
|
|
3466
|
+
* @param {Vector2} layerPos
|
|
3467
|
+
* @param {Boolean} [clear] - should the old tile be cleared out
|
|
3468
|
+
*/
|
|
3469
|
+
drawTileData(layerPos, clear=true)
|
|
3367
3470
|
{
|
|
3368
|
-
//
|
|
3369
|
-
const
|
|
3370
|
-
|
|
3471
|
+
// clear out where the tile was, for full opaque tiles this can be skipped
|
|
3472
|
+
const s = this.tileInfo.size;
|
|
3473
|
+
if (clear)
|
|
3474
|
+
{
|
|
3475
|
+
const pos = layerPos.multiply(s);
|
|
3476
|
+
this.context.clearRect(pos.x, this.canvas.height-pos.y, s.x, -s.y);
|
|
3477
|
+
}
|
|
3371
3478
|
|
|
3372
3479
|
// draw the tile if not undefined
|
|
3373
3480
|
const d = this.getData(layerPos);
|
|
3374
3481
|
if (d.tile != undefined)
|
|
3375
3482
|
{
|
|
3483
|
+
const pos = this.pos.add(layerPos).add(vec2(.5));
|
|
3376
3484
|
ASSERT(mainContext == this.context, 'must call redrawStart() before drawing tiles');
|
|
3377
|
-
const tileInfo = tile(d.tile,
|
|
3485
|
+
const tileInfo = tile(d.tile, s, this.tileInfo.textureIndex);
|
|
3378
3486
|
drawTile(pos, vec2(1), tileInfo, d.color, d.direction*PI/2, d.mirror);
|
|
3379
3487
|
}
|
|
3380
3488
|
}
|
|
3381
3489
|
|
|
3382
|
-
/** Draw all the tiles in this layer */
|
|
3383
|
-
drawAllTileData()
|
|
3384
|
-
{
|
|
3385
|
-
for (let x = this.size.x; x--;)
|
|
3386
|
-
for (let y = this.size.y; y--;)
|
|
3387
|
-
this.drawTileData(vec2(x,y));
|
|
3388
|
-
}
|
|
3389
|
-
|
|
3390
3490
|
/** Draw directly to the 2D canvas in world space (bipass webgl)
|
|
3391
3491
|
* @param {Vector2} pos
|
|
3392
3492
|
* @param {Vector2} size
|
|
@@ -3406,11 +3506,11 @@ class TileLayer extends EngineObject
|
|
|
3406
3506
|
context.restore();
|
|
3407
3507
|
}
|
|
3408
3508
|
|
|
3409
|
-
/** Draw a tile directly onto the layer canvas
|
|
3509
|
+
/** Draw a tile directly onto the layer canvas in world space
|
|
3410
3510
|
* @param {Vector2} pos
|
|
3411
|
-
* @param {Vector2} [size=
|
|
3511
|
+
* @param {Vector2} [size=(1,1)]
|
|
3412
3512
|
* @param {TileInfo} [tileInfo]
|
|
3413
|
-
* @param {Color} [color=
|
|
3513
|
+
* @param {Color} [color=(1,1,1,1)]
|
|
3414
3514
|
* @param {Number} [angle=0]
|
|
3415
3515
|
* @param {Boolean} [mirror=0] */
|
|
3416
3516
|
drawTile(pos, size=vec2(1), tileInfo, color=new Color, angle, mirror)
|
|
@@ -3435,10 +3535,10 @@ class TileLayer extends EngineObject
|
|
|
3435
3535
|
});
|
|
3436
3536
|
}
|
|
3437
3537
|
|
|
3438
|
-
/** Draw a rectangle directly onto the layer canvas
|
|
3538
|
+
/** Draw a rectangle directly onto the layer canvas in world space
|
|
3439
3539
|
* @param {Vector2} pos
|
|
3440
|
-
* @param {Vector2} [size=
|
|
3441
|
-
* @param {Color} [color=
|
|
3540
|
+
* @param {Vector2} [size=(1,1)]
|
|
3541
|
+
* @param {Color} [color=(1,1,1,1)]
|
|
3442
3542
|
* @param {Number} [angle=0] */
|
|
3443
3543
|
drawRect(pos, size, color, angle)
|
|
3444
3544
|
{ this.drawTile(pos, size, undefined, color, angle); }
|
|
@@ -3455,12 +3555,12 @@ class TileLayer extends EngineObject
|
|
|
3455
3555
|
* @example
|
|
3456
3556
|
* // create a particle emitter
|
|
3457
3557
|
* let pos = vec2(2,3);
|
|
3458
|
-
* let
|
|
3558
|
+
* let particleEmitter = new ParticleEmitter
|
|
3459
3559
|
* (
|
|
3460
|
-
* pos, 0, 1, 0, 500, PI,
|
|
3461
|
-
* tile(0, 16),
|
|
3462
|
-
*
|
|
3463
|
-
*
|
|
3560
|
+
* pos, 0, 1, 0, 500, PI, // pos, angle, emitSize, emitTime, emitRate, emiteCone
|
|
3561
|
+
* tile(0, 16), // tileInfo
|
|
3562
|
+
* rgb(1,1,1), rgb(0,0,0), // colorStartA, colorStartB
|
|
3563
|
+
* rgb(1,1,1,0), rgb(0,0,0,0), // colorEndA, colorEndB
|
|
3464
3564
|
* 2, .2, .2, .1, .05, // particleTime, sizeStart, sizeEnd, particleSpeed, particleAngleSpeed
|
|
3465
3565
|
* .99, 1, 1, PI, .05, // damping, angleDamping, gravityScale, particleCone, fadeRate,
|
|
3466
3566
|
* .5, 1 // randomness, collide, additive, randomColorLinear, renderOrder
|
|
@@ -3476,10 +3576,10 @@ class ParticleEmitter extends EngineObject
|
|
|
3476
3576
|
* @param {Number} [emitRate] - How many particles per second to spawn, does not emit if 0
|
|
3477
3577
|
* @param {Number} [emitConeAngle=PI] - Local angle to apply velocity to particles from emitter
|
|
3478
3578
|
* @param {TileInfo} [tileInfo] - Tile info to render particles (undefined is untextured)
|
|
3479
|
-
* @param {Color} [colorStartA=
|
|
3480
|
-
* @param {Color} [colorStartB=
|
|
3481
|
-
* @param {Color} [colorEndA=
|
|
3482
|
-
* @param {Color} [colorEndB=
|
|
3579
|
+
* @param {Color} [colorStartA=(1,1,1,1)] - Color at start of life 1, randomized between start colors
|
|
3580
|
+
* @param {Color} [colorStartB=(1,1,1,1)] - Color at start of life 2, randomized between start colors
|
|
3581
|
+
* @param {Color} [colorEndA=(1,1,1,0)] - Color at end of life 1, randomized between end colors
|
|
3582
|
+
* @param {Color} [colorEndB=(1,1,1,0)] - Color at end of life 2, randomized between end colors
|
|
3483
3583
|
* @param {Number} [particleTime] - How long particles live
|
|
3484
3584
|
* @param {Number} [sizeStart] - How big are particles at start
|
|
3485
3585
|
* @param {Number} [sizeEnd] - How big are particles at end
|
|
@@ -3867,8 +3967,8 @@ class Medal
|
|
|
3867
3967
|
// draw containing rect and clip to that region
|
|
3868
3968
|
context.save();
|
|
3869
3969
|
context.beginPath();
|
|
3870
|
-
context.fillStyle =
|
|
3871
|
-
context.strokeStyle =
|
|
3970
|
+
context.fillStyle = new Color(.9,.9,.9).toString();
|
|
3971
|
+
context.strokeStyle = new Color(0,0,0).toString();
|
|
3872
3972
|
context.lineWidth = 3;
|
|
3873
3973
|
context.rect(x, y, width, medalDisplaySize.y);
|
|
3874
3974
|
context.fill();
|
|
@@ -4317,8 +4417,10 @@ function glCopyToContext(context, forceDraw=false)
|
|
|
4317
4417
|
* @memberof WebGL */
|
|
4318
4418
|
function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba, rgbaAdditive=0)
|
|
4319
4419
|
{
|
|
4420
|
+
ASSERT(typeof rgba == 'number' && typeof rgbaAdditive == 'number', 'invalid color');
|
|
4421
|
+
|
|
4320
4422
|
// flush if there is not enough room or if different blend mode
|
|
4321
|
-
if (glInstanceCount >= gl_MAX_INSTANCES
|
|
4423
|
+
if (glInstanceCount >= gl_MAX_INSTANCES || glBatchAdditive != glAdditive)
|
|
4322
4424
|
glFlush();
|
|
4323
4425
|
|
|
4324
4426
|
let offset = glInstanceCount * gl_INDICIES_PER_INSTANCE;
|
|
@@ -4345,7 +4447,7 @@ let glPostShader, glPostArrayBuffer, glPostTexture, glPostIncludeOverlay;
|
|
|
4345
4447
|
* @param {String} shaderCode
|
|
4346
4448
|
* @param {Boolean} includeOverlay
|
|
4347
4449
|
* @memberof WebGL */
|
|
4348
|
-
function glInitPostProcess(shaderCode, includeOverlay)
|
|
4450
|
+
function glInitPostProcess(shaderCode, includeOverlay=false)
|
|
4349
4451
|
{
|
|
4350
4452
|
ASSERT(!glPostShader, 'can only have 1 post effects shader');
|
|
4351
4453
|
|
|
@@ -4381,6 +4483,8 @@ function glInitPostProcess(shaderCode, includeOverlay)
|
|
|
4381
4483
|
|
|
4382
4484
|
// hide the original 2d canvas
|
|
4383
4485
|
mainCanvas.style.visibility = 'hidden';
|
|
4486
|
+
if (glPostIncludeOverlay)
|
|
4487
|
+
overlayCanvas.style.visibility = 'hidden';
|
|
4384
4488
|
}
|
|
4385
4489
|
|
|
4386
4490
|
// Render the post processing shader, called automatically by the engine
|
|
@@ -4401,14 +4505,8 @@ function glRenderPostProcess()
|
|
|
4401
4505
|
glContext.viewport(0, 0, glCanvas.width = mainCanvas.width, glCanvas.height = mainCanvas.height);
|
|
4402
4506
|
}
|
|
4403
4507
|
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
// copy overlay canvas so it will be included in post processing
|
|
4407
|
-
mainContext.drawImage(overlayCanvas, 0, 0);
|
|
4408
|
-
|
|
4409
|
-
// clear overlay canvas
|
|
4410
|
-
overlayCanvas.width = mainCanvas.width;
|
|
4411
|
-
}
|
|
4508
|
+
// copy overlay canvas so it will be included in post processing
|
|
4509
|
+
glPostIncludeOverlay && mainContext.drawImage(overlayCanvas, 0, 0);
|
|
4412
4510
|
|
|
4413
4511
|
// setup shader program to draw one triangle
|
|
4414
4512
|
glContext.useProgram(glPostShader);
|
|
@@ -4502,7 +4600,7 @@ const engineName = 'LittleJS';
|
|
|
4502
4600
|
* @type {String}
|
|
4503
4601
|
* @default
|
|
4504
4602
|
* @memberof Engine */
|
|
4505
|
-
const engineVersion = '1.9.
|
|
4603
|
+
const engineVersion = '1.9.2';
|
|
4506
4604
|
|
|
4507
4605
|
/** Frames per second to update objects
|
|
4508
4606
|
* @type {Number}
|