littlejsengine 1.2.3 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/build.bat +6 -6
- package/buildSetup.bat +7 -0
- package/docs/Audio.html +2268 -0
- package/docs/Color.html +3376 -0
- package/docs/Debug.html +2933 -0
- package/docs/Draw.html +4480 -0
- package/docs/EngineObject.html +4734 -0
- package/docs/FontImage.html +1055 -0
- package/docs/Input.html +2806 -0
- package/docs/Medal.html +1007 -0
- package/docs/Medals.html +628 -0
- package/docs/Music.html +584 -0
- package/docs/Newgrounds.html +1399 -0
- package/docs/Particle.html +4825 -0
- package/docs/ParticleEmitter.html +8099 -0
- package/docs/Random.html +1774 -0
- package/docs/Settings.html +3140 -0
- package/docs/Sound.html +1249 -0
- package/docs/TileCollision.html +1409 -0
- package/docs/TileLayer.html +7310 -0
- package/docs/TileLayerData.html +1052 -0
- package/docs/Timer.html +1295 -0
- package/docs/Utilities.html +3278 -0
- package/docs/Vector2.html +4266 -0
- package/docs/WebGL.html +2307 -0
- package/docs/engine.js.html +443 -0
- package/docs/engineAudio.js.html +627 -0
- package/docs/engineDebug.js.html +554 -0
- package/docs/engineDraw.js.html +539 -0
- package/docs/engineInput.js.html +571 -0
- package/docs/engineMedals.js.html +460 -0
- package/docs/engineObject.js.html +533 -0
- package/docs/engineParticles.js.html +443 -0
- package/docs/engineSettings.js.html +381 -0
- package/docs/engineTileLayer.js.html +503 -0
- package/docs/engineUtilities.js.html +700 -0
- package/docs/engineWebGL.js.html +511 -0
- package/docs/fonts/MavenPro-Regular.ttf +0 -0
- package/docs/fonts/Montserrat-Regular.ttf +0 -0
- package/docs/fonts/Muli-Black.ttf +0 -0
- package/docs/fonts/OFL-hind.txt +93 -0
- package/docs/fonts/OFL-montserrat.txt +93 -0
- package/docs/global.html +1771 -0
- package/docs/index.css +6 -0
- package/docs/index.html +267 -0
- package/docs/scripts/fix-code-block.js +53 -0
- package/docs/scripts/fix-navbar.js +25 -0
- package/docs/scripts/linenumber.js +25 -0
- package/docs/scripts/misc.js +217 -0
- package/docs/scripts/resize.js +85 -0
- package/docs/scripts/search.js +83 -0
- package/docs/scripts/third-party/Apache-License-2.0.txt +202 -0
- package/docs/scripts/third-party/fuse.js +9 -0
- package/docs/scripts/third-party/lang-css.js +2 -0
- package/docs/scripts/third-party/prettify.js +28 -0
- package/docs/static/favicon.png +0 -0
- package/docs/static/index.css +4 -0
- package/docs/styles/clean-jsdoc-theme-base.css +393 -0
- package/docs/styles/clean-jsdoc-theme-dark.css +324 -0
- package/docs/styles/clean-jsdoc-theme-light.css +319 -0
- package/docs/styles/reset.css +346 -0
- package/docs/styles/third-party/ionicons.min.css +11 -0
- package/docs/styles/third-party/prettify-jsdoc.css +111 -0
- package/docs/styles/third-party/prettify-tomorrow.css +5 -0
- package/engine/engine.all.js +171 -67
- package/engine/engine.all.min.js +1 -1
- package/engine/engine.all.release.js +162 -53
- package/engine/engine.js +3 -3
- package/engine/engineAudio.js +5 -7
- package/engine/engineBuild.bat +3 -4
- package/engine/engineDebug.js +9 -14
- package/engine/engineDraw.js +32 -13
- package/engine/engineInput.js +5 -1
- package/engine/engineMedals.js +5 -2
- package/engine/engineObject.js +24 -5
- package/engine/engineParticles.js +2 -2
- package/engine/engineSettings.js +5 -0
- package/engine/engineTileLayer.js +11 -10
- package/engine/engineUtilities.js +67 -7
- package/engine/engineWebGL.js +3 -3
- package/engine/index.d.ts +57 -18
- package/examples/breakout/index.html +3 -3
- package/examples/particles/index.html +366 -0
- package/examples/particles/tiles.png +0 -0
- package/examples/platformer/gameEffects.js +6 -6
- package/examples/platformer/index.html +6 -6
- package/examples/puzzle/game.js +4 -2
- package/examples/puzzle/index.html +2 -2
- package/examples/stress/index.html +1 -1
- package/game.js +3 -14
- package/index.html +13 -13
- package/package.json +1 -1
- package/engine/engineBuildSetup.bat +0 -7
|
@@ -333,7 +333,7 @@ class Vector2
|
|
|
333
333
|
|
|
334
334
|
/** Returns the area this vector covers as a rectangle
|
|
335
335
|
* @return {Number} */
|
|
336
|
-
area() { return this.x * this.y; }
|
|
336
|
+
area() { return abs(this.x * this.y); }
|
|
337
337
|
|
|
338
338
|
/** Returns a new vector that is p percent between this and the vector passed in
|
|
339
339
|
* @param {Vector2} vector
|
|
@@ -344,7 +344,13 @@ class Vector2
|
|
|
344
344
|
/** Returns true if this vector is within the bounds of an array size passed in
|
|
345
345
|
* @param {Vector2} arraySize
|
|
346
346
|
* @return {Boolean} */
|
|
347
|
-
arrayCheck(arraySize) { return this.x >= 0 && this.y >= 0 && this.x < arraySize.x && this.y < arraySize.y; }
|
|
347
|
+
arrayCheck(arraySize) { return this.x >= 0 && this.y >= 0 && this.x < arraySize.x && this.y < arraySize.y; }
|
|
348
|
+
|
|
349
|
+
/** Returns this vector expressed as a string
|
|
350
|
+
* @param {float} digits - precision to display
|
|
351
|
+
* @return {String} */
|
|
352
|
+
toString(digits=3)
|
|
353
|
+
{ return `(${(this.x<0?'':' ') + this.x.toFixed(digits)},${(this.y<0?'':' ') + this.y.toFixed(digits)} )`; }
|
|
348
354
|
}
|
|
349
355
|
|
|
350
356
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -415,7 +421,7 @@ class Color
|
|
|
415
421
|
* @return {Color} */
|
|
416
422
|
lerp(c, p) { return this.add(c.subtract(this).scale(clamp(p))); }
|
|
417
423
|
|
|
418
|
-
/** Sets this color given a hue, saturation, lightness
|
|
424
|
+
/** Sets this color given a hue, saturation, lightness, and alpha
|
|
419
425
|
* @param {Number} [hue=0]
|
|
420
426
|
* @param {Number} [saturation=0]
|
|
421
427
|
* @param {Number} [lightness=1]
|
|
@@ -451,21 +457,71 @@ class Color
|
|
|
451
457
|
).clamp();
|
|
452
458
|
}
|
|
453
459
|
|
|
454
|
-
/** Returns this color expressed as an
|
|
460
|
+
/** Returns this color expressed as an CSS color value
|
|
455
461
|
* @return {String} */
|
|
456
|
-
|
|
462
|
+
toString()
|
|
457
463
|
{
|
|
458
464
|
ASSERT(this.r>=0 && this.r<=1 && this.g>=0 && this.g<=1 && this.b>=0 && this.b<=1 && this.a>=0 && this.a<=1);
|
|
459
465
|
return `rgb(${this.r*255|0},${this.g*255|0},${this.b*255|0},${this.a})`;
|
|
460
466
|
}
|
|
461
467
|
|
|
462
|
-
/** Returns this color expressed as 32 bit integer value
|
|
468
|
+
/** Returns this color expressed as 32 bit integer RGBA value
|
|
463
469
|
* @return {Number} */
|
|
464
470
|
rgbaInt()
|
|
465
471
|
{
|
|
466
472
|
ASSERT(this.r>=0 && this.r<=1 && this.g>=0 && this.g<=1 && this.b>=0 && this.b<=1 && this.a>=0 && this.a<=1);
|
|
467
473
|
return (this.r*255|0) + (this.g*255<<8) + (this.b*255<<16) + (this.a*255<<24);
|
|
468
474
|
}
|
|
475
|
+
|
|
476
|
+
/** Returns this color expressed as a hex code
|
|
477
|
+
* @return {String} */
|
|
478
|
+
hex()
|
|
479
|
+
{
|
|
480
|
+
const toHex = (c)=> ((c=c*255|0)<16 ? '0' : '') + c.toString(16);
|
|
481
|
+
return '#' + toHex(this.r) + toHex(this.g) + toHex(this.b);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/** Returns this color expressed in hsla format
|
|
485
|
+
* @return {Array} */
|
|
486
|
+
getHSLA()
|
|
487
|
+
{
|
|
488
|
+
const r = this.r;
|
|
489
|
+
const g = this.g;
|
|
490
|
+
const b = this.b;
|
|
491
|
+
const a = this.a;
|
|
492
|
+
const max = Math.max(r, g, b);
|
|
493
|
+
const min = Math.min(r, g, b);
|
|
494
|
+
const l = (max + min) / 2;
|
|
495
|
+
|
|
496
|
+
let h = 0, s = 0;
|
|
497
|
+
if (max != min)
|
|
498
|
+
{
|
|
499
|
+
let d = max - min;
|
|
500
|
+
s = l > .5 ? d / (2 - max - min) : d / (max + min);
|
|
501
|
+
if (r == max)
|
|
502
|
+
h = (g - b) / d + (g < b ? 6 : 0);
|
|
503
|
+
else if (g == max)
|
|
504
|
+
h = (b - r) / d + 2;
|
|
505
|
+
else if (b == max)
|
|
506
|
+
h = (r - g) / d + 4;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
return [h / 6, s, l, a];
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/** Set this color from a hex code
|
|
513
|
+
* @param {String} hex - html hex code
|
|
514
|
+
* @return {Color} */
|
|
515
|
+
setHex(hex)
|
|
516
|
+
{
|
|
517
|
+
const fromHex = (a)=> parseInt(hex.slice(a,a+2), 16)/255;
|
|
518
|
+
this.r = fromHex(1);
|
|
519
|
+
this.g = fromHex(3),
|
|
520
|
+
this.b = fromHex(5);
|
|
521
|
+
this.a = 1;
|
|
522
|
+
ASSERT(this.r>=0 && this.r<=1 && this.g>=0 && this.g<=1 && this.b>=0 && this.b<=1);
|
|
523
|
+
return this;
|
|
524
|
+
}
|
|
469
525
|
}
|
|
470
526
|
|
|
471
527
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -502,7 +558,7 @@ class Timer
|
|
|
502
558
|
|
|
503
559
|
/** Returns true if set and elapsed
|
|
504
560
|
* @return {Boolean} */
|
|
505
|
-
elapsed() { return time >
|
|
561
|
+
elapsed() { return time > this.time; }
|
|
506
562
|
|
|
507
563
|
/** Get how long since elapsed, returns 0 if not set (returns negative if currently active)
|
|
508
564
|
* @return {Number} */
|
|
@@ -511,6 +567,10 @@ class Timer
|
|
|
511
567
|
/** Get percentage elapsed based on time it was set to, returns 0 if not set
|
|
512
568
|
* @return {Number} */
|
|
513
569
|
getPercent() { return this.isSet()? percent(this.time - time, this.setTime, 0) : 0; }
|
|
570
|
+
|
|
571
|
+
/** Returns this timer expressed as a string
|
|
572
|
+
* @return {String} */
|
|
573
|
+
toString() { if (debug) { return this.unset() ? 'unset' : Math.abs(this.get()) + ' seconds ' + (this.get()<0 ? 'before' : 'after' ); } }
|
|
514
574
|
}
|
|
515
575
|
/**
|
|
516
576
|
* LittleJS Engine Settings
|
|
@@ -567,6 +627,11 @@ let tileFixBleedScale = .3;
|
|
|
567
627
|
* @memberof Settings */
|
|
568
628
|
let objectDefaultSize = vec2(1);
|
|
569
629
|
|
|
630
|
+
/** Enable physics solver for collisions between objects
|
|
631
|
+
* @default
|
|
632
|
+
* @memberof Settings */
|
|
633
|
+
let enablePhysicsSolver = 1;
|
|
634
|
+
|
|
570
635
|
/** Default object mass for collison calcuations (how heavy objects are)
|
|
571
636
|
* @default
|
|
572
637
|
* @memberof Settings */
|
|
@@ -753,7 +818,7 @@ let medalDisplayIconSize = 50;
|
|
|
753
818
|
const engineName = 'LittleJS';
|
|
754
819
|
|
|
755
820
|
/** Version of engine */
|
|
756
|
-
const engineVersion = '1.
|
|
821
|
+
const engineVersion = '1.3.3';
|
|
757
822
|
|
|
758
823
|
/** Frames per second to update objects
|
|
759
824
|
* @default */
|
|
@@ -834,8 +899,6 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
834
899
|
// main update loop
|
|
835
900
|
const engineUpdate = (frameTimeMS=0)=>
|
|
836
901
|
{
|
|
837
|
-
requestAnimationFrame(engineUpdate);
|
|
838
|
-
|
|
839
902
|
// update time keeping
|
|
840
903
|
let frameTimeDeltaMS = frameTimeMS - frameTimeLastMS;
|
|
841
904
|
frameTimeLastMS = frameTimeMS;
|
|
@@ -934,6 +997,8 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
934
997
|
overlayContext.fillText(text, mainCanvas.width-2, 2);
|
|
935
998
|
drawCount = 0;
|
|
936
999
|
}
|
|
1000
|
+
|
|
1001
|
+
requestAnimationFrame(engineUpdate);
|
|
937
1002
|
}
|
|
938
1003
|
|
|
939
1004
|
// set tile image source to load the image and start the engine
|
|
@@ -1049,9 +1114,9 @@ class EngineObject
|
|
|
1049
1114
|
/** Create an engine object and adds it to the list of objects
|
|
1050
1115
|
* @param {Vector2} [position=new Vector2()] - World space position of the object
|
|
1051
1116
|
* @param {Vector2} [size=objectDefaultSize] - World space size of the object
|
|
1052
|
-
* @param {Number} [tileIndex=-1] - Tile to use to render object
|
|
1117
|
+
* @param {Number} [tileIndex=-1] - Tile to use to render object (-1 is untextured)
|
|
1053
1118
|
* @param {Vector2} [tileSize=tileSizeDefault] - Size of tile in source pixels
|
|
1054
|
-
* @param {Number} [angle=0] - Angle
|
|
1119
|
+
* @param {Number} [angle=0] - Angle the object is rotated by
|
|
1055
1120
|
* @param {Color} [color] - Color to apply to tile when rendered
|
|
1056
1121
|
* @param {Number} [renderOrder=0] - Objects sorted by renderOrder before being rendered
|
|
1057
1122
|
*/
|
|
@@ -1066,7 +1131,7 @@ class EngineObject
|
|
|
1066
1131
|
this.size = size;
|
|
1067
1132
|
/** @property {Vector2} - Size of object used for drawing, uses size if not set */
|
|
1068
1133
|
this.drawSize;
|
|
1069
|
-
/** @property {Number} - Tile to use to render object
|
|
1134
|
+
/** @property {Number} - Tile to use to render object (-1 is untextured) */
|
|
1070
1135
|
this.tileIndex = tileIndex;
|
|
1071
1136
|
/** @property {Vector2} - Size of tile in source pixels */
|
|
1072
1137
|
this.tileSize = tileSize;
|
|
@@ -1078,7 +1143,7 @@ class EngineObject
|
|
|
1078
1143
|
this.additiveColor;
|
|
1079
1144
|
|
|
1080
1145
|
// set object defaults
|
|
1081
|
-
/** @property {Number} [mass=objectDefaultMass] - How heavy the object is */
|
|
1146
|
+
/** @property {Number} [mass=objectDefaultMass] - How heavy the object is, static if 0 */
|
|
1082
1147
|
this.mass = objectDefaultMass;
|
|
1083
1148
|
/** @property {Number} [damping=objectDefaultDamping] - How much to slow down velocity each frame (0-1) */
|
|
1084
1149
|
this.damping = objectDefaultDamping;
|
|
@@ -1132,7 +1197,7 @@ class EngineObject
|
|
|
1132
1197
|
ASSERT(this.angleDamping >= 0 && this.angleDamping <= 1);
|
|
1133
1198
|
ASSERT(this.damping >= 0 && this.damping <= 1);
|
|
1134
1199
|
|
|
1135
|
-
if (!this.mass) // do not update collision for fixed objects
|
|
1200
|
+
if (!enablePhysicsSolver || !this.mass) // do not update collision for fixed objects
|
|
1136
1201
|
return;
|
|
1137
1202
|
|
|
1138
1203
|
const wasMovingDown = this.velocity.y < 0;
|
|
@@ -1367,6 +1432,25 @@ class EngineObject
|
|
|
1367
1432
|
this.isSolid = isSolid;
|
|
1368
1433
|
this.collideTiles = collideTiles;
|
|
1369
1434
|
}
|
|
1435
|
+
|
|
1436
|
+
toString()
|
|
1437
|
+
{
|
|
1438
|
+
if (debug)
|
|
1439
|
+
{
|
|
1440
|
+
let text = 'type = ' + this.constructor.name;
|
|
1441
|
+
if (this.pos.x || this.pos.y)
|
|
1442
|
+
text += '\npos = ' + this.pos;
|
|
1443
|
+
if (this.velocity.x || this.velocity.y)
|
|
1444
|
+
text += '\nvelocity = ' + this.velocity;
|
|
1445
|
+
if (this.size.x || this.size.y)
|
|
1446
|
+
text += '\nsize = ' + this.size;
|
|
1447
|
+
if (this.angle)
|
|
1448
|
+
text += '\nangle = ' + this.angle.toFixed(3);
|
|
1449
|
+
if (this.color)
|
|
1450
|
+
text += '\ncolor = ' + this.color;
|
|
1451
|
+
return text;
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1370
1454
|
}
|
|
1371
1455
|
/**
|
|
1372
1456
|
* LittleJS Drawing System
|
|
@@ -1480,7 +1564,7 @@ function drawTile(pos, size=vec2(1), tileIndex=-1, tileSize=tileSizeDefault, col
|
|
|
1480
1564
|
if (tileIndex < 0)
|
|
1481
1565
|
{
|
|
1482
1566
|
// if negative tile index, force untextured
|
|
1483
|
-
context.fillStyle = color
|
|
1567
|
+
context.fillStyle = color;
|
|
1484
1568
|
context.fillRect(-.5, -.5, 1, 1);
|
|
1485
1569
|
}
|
|
1486
1570
|
else
|
|
@@ -1535,7 +1619,7 @@ function drawTileScreenSpace(pos, size=vec2(1), tileIndex, tileSize, color, angl
|
|
|
1535
1619
|
* @memberof Draw */
|
|
1536
1620
|
function drawRectScreenSpace(pos, size, color, angle, useWebGL)
|
|
1537
1621
|
{
|
|
1538
|
-
|
|
1622
|
+
drawTileScreenSpace(pos, size, -1, tileSizeDefault, color, angle, 0, 0, useWebGL);
|
|
1539
1623
|
}
|
|
1540
1624
|
|
|
1541
1625
|
/** Draw colored line between two points
|
|
@@ -1585,7 +1669,8 @@ function setBlendMode(additive, useWebGL=glEnable)
|
|
|
1585
1669
|
mainContext.globalCompositeOperation = additive ? 'lighter' : 'source-over';
|
|
1586
1670
|
}
|
|
1587
1671
|
|
|
1588
|
-
/** Draw text on overlay canvas in
|
|
1672
|
+
/** Draw text on overlay canvas in screen space
|
|
1673
|
+
* Automatically splits new lines into rows
|
|
1589
1674
|
* @param {String} text
|
|
1590
1675
|
* @param {Vector2} pos
|
|
1591
1676
|
* @param {Number} [size=1]
|
|
@@ -1594,20 +1679,38 @@ function setBlendMode(additive, useWebGL=glEnable)
|
|
|
1594
1679
|
* @param {Color} [lineColor=new Color(0,0,0)]
|
|
1595
1680
|
* @param {String} [textAlign='center']
|
|
1596
1681
|
* @memberof Draw */
|
|
1597
|
-
function
|
|
1682
|
+
function drawTextScreen(text, pos, size=1, color=new Color, lineWidth=0, lineColor=new Color(0,0,0), textAlign='center', font=fontDefault)
|
|
1598
1683
|
{
|
|
1599
|
-
|
|
1600
|
-
overlayContext.
|
|
1684
|
+
overlayContext.fillStyle = color;
|
|
1685
|
+
overlayContext.lineWidth = lineWidth;
|
|
1686
|
+
overlayContext.strokeStyle = lineColor;
|
|
1601
1687
|
overlayContext.textAlign = textAlign;
|
|
1688
|
+
overlayContext.font = size + 'px '+ font;
|
|
1602
1689
|
overlayContext.textBaseline = 'middle';
|
|
1603
|
-
|
|
1690
|
+
overlayContext.lineJoin = 'round';
|
|
1691
|
+
|
|
1692
|
+
pos = pos.copy();
|
|
1693
|
+
text.split('\n').forEach(line=>
|
|
1604
1694
|
{
|
|
1605
|
-
overlayContext.
|
|
1606
|
-
overlayContext.
|
|
1607
|
-
|
|
1608
|
-
}
|
|
1609
|
-
|
|
1610
|
-
|
|
1695
|
+
lineWidth && overlayContext.strokeText(line, pos.x, pos.y);
|
|
1696
|
+
overlayContext.fillText(line, pos.x, pos.y);
|
|
1697
|
+
pos.y += size;
|
|
1698
|
+
});
|
|
1699
|
+
}
|
|
1700
|
+
|
|
1701
|
+
/** Draw text on overlay canvas in world space
|
|
1702
|
+
* Automatically splits new lines into rows
|
|
1703
|
+
* @param {String} text
|
|
1704
|
+
* @param {Vector2} pos
|
|
1705
|
+
* @param {Number} [size=1]
|
|
1706
|
+
* @param {Color} [color=new Color(1,1,1)]
|
|
1707
|
+
* @param {Number} [lineWidth=0]
|
|
1708
|
+
* @param {Color} [lineColor=new Color(0,0,0)]
|
|
1709
|
+
* @param {String} [textAlign='center']
|
|
1710
|
+
* @memberof Draw */
|
|
1711
|
+
function drawText(text, pos, size=1, color, lineWidth, lineColor, textAlign, font)
|
|
1712
|
+
{
|
|
1713
|
+
drawTextScreen(text, worldToScreen(pos), size*cameraScale, color, lineWidth*cameraScale, lineColor, textAlign, font);
|
|
1611
1714
|
}
|
|
1612
1715
|
|
|
1613
1716
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -1801,6 +1904,10 @@ let mouseWheel = 0;
|
|
|
1801
1904
|
* @memberof Input */
|
|
1802
1905
|
let isUsingGamepad = 0;
|
|
1803
1906
|
|
|
1907
|
+
/** Prevents input continuing to the default browser handling (false by default)
|
|
1908
|
+
* @memberof Input */
|
|
1909
|
+
let preventDefaultInput = 0;
|
|
1910
|
+
|
|
1804
1911
|
/** Returns true if gamepad button is down
|
|
1805
1912
|
* @param {Number} button
|
|
1806
1913
|
* @param {Number} [gamepad=0]
|
|
@@ -1864,7 +1971,7 @@ onkeydown = (e)=>
|
|
|
1864
1971
|
{
|
|
1865
1972
|
if (debug && e.target != document.body) return;
|
|
1866
1973
|
e.repeat || (inputData[isUsingGamepad = 0][remapKeyCode(e.keyCode)] = 3);
|
|
1867
|
-
|
|
1974
|
+
preventDefaultInput && e.preventDefault();
|
|
1868
1975
|
}
|
|
1869
1976
|
onkeyup = (e)=>
|
|
1870
1977
|
{
|
|
@@ -2428,8 +2535,7 @@ function zzfxG
|
|
|
2428
2535
|
)
|
|
2429
2536
|
{
|
|
2430
2537
|
// init parameters
|
|
2431
|
-
let PI2 = PI*2,
|
|
2432
|
-
startSlide = slide *= 500 * PI2 / zzfxR / zzfxR, b=[],
|
|
2538
|
+
let PI2 = PI*2, startSlide = slide *= 500 * PI2 / zzfxR / zzfxR, b=[],
|
|
2433
2539
|
startFrequency = frequency *= (1 + randomness*rand(-1,1)) * PI2 / zzfxR,
|
|
2434
2540
|
t=0, tm=0, i=0, j=1, r=0, c=0, s=0, f, length;
|
|
2435
2541
|
|
|
@@ -2453,15 +2559,15 @@ function zzfxG
|
|
|
2453
2559
|
{
|
|
2454
2560
|
s = shape? shape>1? shape>2? shape>3? // wave shape
|
|
2455
2561
|
Math.sin((t%PI2)**3) : // 4 noise
|
|
2456
|
-
|
|
2562
|
+
max(min(Math.tan(t),1),-1): // 3 tan
|
|
2457
2563
|
1-(2*t/PI2%2+2)%2: // 2 saw
|
|
2458
|
-
1-4*abs(Math.round(t/PI2)-t/PI2):
|
|
2564
|
+
1-4*abs(Math.round(t/PI2)-t/PI2): // 1 triangle
|
|
2459
2565
|
Math.sin(t); // 0 sin
|
|
2460
2566
|
|
|
2461
2567
|
s = (repeatTime ?
|
|
2462
2568
|
1 - tremolo + tremolo*Math.sin(PI2*i/repeatTime) // tremolo
|
|
2463
2569
|
: 1) *
|
|
2464
|
-
sign(s)*(abs(s)**shapeCurve) *
|
|
2570
|
+
sign(s)*(abs(s)**shapeCurve) * // curve 0=square, 2=pointy
|
|
2465
2571
|
volume * soundVolume * ( // envelope
|
|
2466
2572
|
i < attack ? i/attack : // attack
|
|
2467
2573
|
i < attack + decay ? // decay
|
|
@@ -2522,7 +2628,6 @@ function zzfxM(instruments, patterns, sequence, BPM = 125)
|
|
|
2522
2628
|
let notFirstBeat;
|
|
2523
2629
|
let stop;
|
|
2524
2630
|
let instrument;
|
|
2525
|
-
let pitch;
|
|
2526
2631
|
let attenuation;
|
|
2527
2632
|
let outSampleOffset;
|
|
2528
2633
|
let isSequenceEnd;
|
|
@@ -2541,7 +2646,7 @@ function zzfxM(instruments, patterns, sequence, BPM = 125)
|
|
|
2541
2646
|
for (; hasMore; channelIndex++) {
|
|
2542
2647
|
|
|
2543
2648
|
// reset current values
|
|
2544
|
-
sampleBuffer = [hasMore = notFirstBeat =
|
|
2649
|
+
sampleBuffer = [hasMore = notFirstBeat = outSampleOffset = 0];
|
|
2545
2650
|
|
|
2546
2651
|
// for each pattern in sequence
|
|
2547
2652
|
sequence.forEach((patternIndex, sequenceIndex) => {
|
|
@@ -2762,14 +2867,14 @@ class TileLayerData
|
|
|
2762
2867
|
*/
|
|
2763
2868
|
class TileLayer extends EngineObject
|
|
2764
2869
|
{
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2870
|
+
/** Create a tile layer object
|
|
2871
|
+
* @param {Vector2} [position=new Vector2()] - World space position
|
|
2872
|
+
* @param {Vector2} [size=tileCollisionSize] - World space size
|
|
2873
|
+
* @param {Vector2} [tileSize=tileSizeDefault] - Size of tiles in source pixels
|
|
2874
|
+
* @param {Vector2} [scale=new Vector2(1,1)] - How much to scale this layer when rendered
|
|
2875
|
+
* @param {Number} [renderOrder=0] - Objects sorted by renderOrder before being rendered
|
|
2876
|
+
*/
|
|
2877
|
+
constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1), renderOrder=0)
|
|
2773
2878
|
{
|
|
2774
2879
|
super(pos, size, -1, tileSize, 0, undefined, renderOrder);
|
|
2775
2880
|
|
|
@@ -2929,7 +3034,7 @@ class TileLayer extends EngineObject
|
|
|
2929
3034
|
if (tileIndex < 0)
|
|
2930
3035
|
{
|
|
2931
3036
|
// untextured
|
|
2932
|
-
context.fillStyle = color
|
|
3037
|
+
context.fillStyle = color;
|
|
2933
3038
|
context.fillRect(-.5, -.5, 1, 1);
|
|
2934
3039
|
}
|
|
2935
3040
|
else
|
|
@@ -2948,7 +3053,8 @@ class TileLayer extends EngineObject
|
|
|
2948
3053
|
* @param {Vector2} [size=new Vector2(1,1)]
|
|
2949
3054
|
* @param {Color} [color=new Color(1,1,1)]
|
|
2950
3055
|
* @param {Number} [angle=0] */
|
|
2951
|
-
drawRect(pos, size, color, angle)
|
|
3056
|
+
drawRect(pos, size, color, angle)
|
|
3057
|
+
{ this.drawTile(pos, size, -1, 0, color, angle); }
|
|
2952
3058
|
}
|
|
2953
3059
|
/*
|
|
2954
3060
|
LittleJS Particle System
|
|
@@ -2980,7 +3086,7 @@ class ParticleEmitter extends EngineObject
|
|
|
2980
3086
|
{
|
|
2981
3087
|
/** Create a particle system with the given settings
|
|
2982
3088
|
* @param {Vector2} position - World space position of the emitter
|
|
2983
|
-
* @param {Number} [angle=0] - Angle to
|
|
3089
|
+
* @param {Number} [angle=0] - Angle to emit the particles
|
|
2984
3090
|
* @param {Number} [emitSize=0] - World space size of the emitter (float for circle diameter, vec2 for rect)
|
|
2985
3091
|
* @param {Number} [emitTime=0] - How long to stay alive (0 is forever)
|
|
2986
3092
|
* @param {Number} [emitRate=100] - How many particles per second to spawn, does not emit if 0
|
|
@@ -3065,7 +3171,7 @@ class ParticleEmitter extends EngineObject
|
|
|
3065
3171
|
// particle settings
|
|
3066
3172
|
/** @property {Number} - How long particles live */
|
|
3067
3173
|
this.particleTime = particleTime;
|
|
3068
|
-
/** @property {Number} -
|
|
3174
|
+
/** @property {Number} - How big are particles at start */
|
|
3069
3175
|
this.sizeStart = sizeStart;
|
|
3070
3176
|
/** @property {Number} - How big are particles at end */
|
|
3071
3177
|
this.sizeEnd = sizeEnd;
|
|
@@ -3271,7 +3377,7 @@ function medalsInit(saveName)
|
|
|
3271
3377
|
{
|
|
3272
3378
|
// check if medals are unlocked
|
|
3273
3379
|
medalsSaveName = saveName;
|
|
3274
|
-
debugMedals || medals.forEach(medal=>
|
|
3380
|
+
debugMedals || medals.forEach(medal=> localStorage[medal.storageKey()]);
|
|
3275
3381
|
}
|
|
3276
3382
|
|
|
3277
3383
|
/**
|
|
@@ -3428,7 +3534,7 @@ class Newgrounds
|
|
|
3428
3534
|
cipher && (this.cryptoJS = CryptoJS());
|
|
3429
3535
|
|
|
3430
3536
|
// get session id from url search params
|
|
3431
|
-
const url = new URL(
|
|
3537
|
+
const url = new URL(location.href);
|
|
3432
3538
|
this.session_id = url.searchParams.get('ngio_session_id') || 0;
|
|
3433
3539
|
|
|
3434
3540
|
if (this.session_id == 0)
|
|
@@ -3460,6 +3566,9 @@ class Newgrounds
|
|
|
3460
3566
|
const scoreboardResult = this.call('ScoreBoard.getBoards');
|
|
3461
3567
|
this.scoreboards = scoreboardResult ? scoreboardResult.result.data.scoreboards : [];
|
|
3462
3568
|
debugMedals && console.log(this.scoreboards);
|
|
3569
|
+
|
|
3570
|
+
const keepAliveMS = 5 * 60 * 1e3;
|
|
3571
|
+
setInterval(()=>this.call('Gateway.ping', 0, 1), keepAliveMS);
|
|
3463
3572
|
}
|
|
3464
3573
|
|
|
3465
3574
|
/** Send message to unlock a medal by id
|
|
@@ -3581,7 +3690,7 @@ function glInit()
|
|
|
3581
3690
|
|
|
3582
3691
|
// setup vertex and fragment shaders
|
|
3583
3692
|
glShader = glCreateProgram(
|
|
3584
|
-
'precision highp float;'+ // use highp for better accuracy
|
|
3693
|
+
'precision highp float;'+ // use highp for better accuracy
|
|
3585
3694
|
'uniform mat4 m;'+ // transform matrix
|
|
3586
3695
|
'attribute vec2 p,t;'+ // position, uv
|
|
3587
3696
|
'attribute vec4 c,a;'+ // color, additiveColor
|
|
@@ -3592,7 +3701,7 @@ function glInit()
|
|
|
3592
3701
|
'v=t;d=c;e=a;'+ // pass stuff to fragment shader
|
|
3593
3702
|
'}' // end of shader
|
|
3594
3703
|
,
|
|
3595
|
-
'precision highp float;'+ // use highp for better accuracy
|
|
3704
|
+
'precision highp float;'+ // use highp for better accuracy
|
|
3596
3705
|
'varying vec2 v;'+ // uv
|
|
3597
3706
|
'varying vec4 d,e;'+ // color, additiveColor
|
|
3598
3707
|
'uniform sampler2D s;'+ // texture
|
|
@@ -3778,7 +3887,7 @@ function glFlush()
|
|
|
3778
3887
|
* @memberof WebGL */
|
|
3779
3888
|
function glCopyToContext(context, forceDraw)
|
|
3780
3889
|
{
|
|
3781
|
-
if (!glEnable || !glBatchCount) return;
|
|
3890
|
+
if ((!glEnable || !glBatchCount) && !forceDraw) return;
|
|
3782
3891
|
|
|
3783
3892
|
glFlush();
|
|
3784
3893
|
|
package/engine/engine.js
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
const engineName = 'LittleJS';
|
|
23
23
|
|
|
24
24
|
/** Version of engine */
|
|
25
|
-
const engineVersion = '1.
|
|
25
|
+
const engineVersion = '1.3.3';
|
|
26
26
|
|
|
27
27
|
/** Frames per second to update objects
|
|
28
28
|
* @default */
|
|
@@ -103,8 +103,6 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
103
103
|
// main update loop
|
|
104
104
|
const engineUpdate = (frameTimeMS=0)=>
|
|
105
105
|
{
|
|
106
|
-
requestAnimationFrame(engineUpdate);
|
|
107
|
-
|
|
108
106
|
// update time keeping
|
|
109
107
|
let frameTimeDeltaMS = frameTimeMS - frameTimeLastMS;
|
|
110
108
|
frameTimeLastMS = frameTimeMS;
|
|
@@ -203,6 +201,8 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
203
201
|
overlayContext.fillText(text, mainCanvas.width-2, 2);
|
|
204
202
|
drawCount = 0;
|
|
205
203
|
}
|
|
204
|
+
|
|
205
|
+
requestAnimationFrame(engineUpdate);
|
|
206
206
|
}
|
|
207
207
|
|
|
208
208
|
// set tile image source to load the image and start the engine
|
package/engine/engineAudio.js
CHANGED
|
@@ -289,8 +289,7 @@ function zzfxG
|
|
|
289
289
|
)
|
|
290
290
|
{
|
|
291
291
|
// init parameters
|
|
292
|
-
let PI2 = PI*2,
|
|
293
|
-
startSlide = slide *= 500 * PI2 / zzfxR / zzfxR, b=[],
|
|
292
|
+
let PI2 = PI*2, startSlide = slide *= 500 * PI2 / zzfxR / zzfxR, b=[],
|
|
294
293
|
startFrequency = frequency *= (1 + randomness*rand(-1,1)) * PI2 / zzfxR,
|
|
295
294
|
t=0, tm=0, i=0, j=1, r=0, c=0, s=0, f, length;
|
|
296
295
|
|
|
@@ -314,15 +313,15 @@ function zzfxG
|
|
|
314
313
|
{
|
|
315
314
|
s = shape? shape>1? shape>2? shape>3? // wave shape
|
|
316
315
|
Math.sin((t%PI2)**3) : // 4 noise
|
|
317
|
-
|
|
316
|
+
max(min(Math.tan(t),1),-1): // 3 tan
|
|
318
317
|
1-(2*t/PI2%2+2)%2: // 2 saw
|
|
319
|
-
1-4*abs(Math.round(t/PI2)-t/PI2):
|
|
318
|
+
1-4*abs(Math.round(t/PI2)-t/PI2): // 1 triangle
|
|
320
319
|
Math.sin(t); // 0 sin
|
|
321
320
|
|
|
322
321
|
s = (repeatTime ?
|
|
323
322
|
1 - tremolo + tremolo*Math.sin(PI2*i/repeatTime) // tremolo
|
|
324
323
|
: 1) *
|
|
325
|
-
sign(s)*(abs(s)**shapeCurve) *
|
|
324
|
+
sign(s)*(abs(s)**shapeCurve) * // curve 0=square, 2=pointy
|
|
326
325
|
volume * soundVolume * ( // envelope
|
|
327
326
|
i < attack ? i/attack : // attack
|
|
328
327
|
i < attack + decay ? // decay
|
|
@@ -383,7 +382,6 @@ function zzfxM(instruments, patterns, sequence, BPM = 125)
|
|
|
383
382
|
let notFirstBeat;
|
|
384
383
|
let stop;
|
|
385
384
|
let instrument;
|
|
386
|
-
let pitch;
|
|
387
385
|
let attenuation;
|
|
388
386
|
let outSampleOffset;
|
|
389
387
|
let isSequenceEnd;
|
|
@@ -402,7 +400,7 @@ function zzfxM(instruments, patterns, sequence, BPM = 125)
|
|
|
402
400
|
for (; hasMore; channelIndex++) {
|
|
403
401
|
|
|
404
402
|
// reset current values
|
|
405
|
-
sampleBuffer = [hasMore = notFirstBeat =
|
|
403
|
+
sampleBuffer = [hasMore = notFirstBeat = outSampleOffset = 0];
|
|
406
404
|
|
|
407
405
|
// for each pattern in sequence
|
|
408
406
|
sequence.forEach((patternIndex, sequenceIndex) => {
|
package/engine/engineBuild.bat
CHANGED
|
@@ -79,7 +79,7 @@ copy engine.all.release.js %OUTPUT_FILENAME%
|
|
|
79
79
|
|
|
80
80
|
rem check code with closure
|
|
81
81
|
move %OUTPUT_FILENAME% %OUTPUT_FILENAME%.temp
|
|
82
|
-
call google-closure-compiler --js
|
|
82
|
+
call npx google-closure-compiler --js=%OUTPUT_FILENAME%.temp --js_output_file=%OUTPUT_FILENAME% --language_out=ECMASCRIPT_2019 --warning_level=VERBOSE --jscomp_off=*
|
|
83
83
|
del %OUTPUT_FILENAME%.temp
|
|
84
84
|
if %ERRORLEVEL% NEQ 0 (
|
|
85
85
|
pause
|
|
@@ -87,15 +87,14 @@ if %ERRORLEVEL% NEQ 0 (
|
|
|
87
87
|
)
|
|
88
88
|
|
|
89
89
|
rem lightly minify with uglify
|
|
90
|
-
call uglifyjs -o %OUTPUT_FILENAME% -- %OUTPUT_FILENAME%
|
|
90
|
+
call npx uglifyjs -o %OUTPUT_FILENAME% -- %OUTPUT_FILENAME%
|
|
91
91
|
if %ERRORLEVEL% NEQ 0 (
|
|
92
92
|
pause
|
|
93
93
|
exit /b %ERRORLEVEL%
|
|
94
94
|
)
|
|
95
95
|
|
|
96
96
|
rem --- BUILD TYPESCRIPT DEFINITIONS ---
|
|
97
|
-
|
|
98
|
-
call tsc engine.all.js --declaration --allowJs --emitDeclarationOnly --outFile index.d.ts
|
|
97
|
+
call npx tsc engine.all.js --declaration --allowJs --emitDeclarationOnly --outFile index.d.ts
|
|
99
98
|
if %ERRORLEVEL% NEQ 0 (
|
|
100
99
|
pause
|
|
101
100
|
exit /b %ERRORLEVEL%
|
package/engine/engineDebug.js
CHANGED
|
@@ -273,17 +273,11 @@ const debugRender = ()=>
|
|
|
273
273
|
drawRect(mousePos.floor().add(vec2(.5)), vec2(1), new Color(0,0,1,.5));
|
|
274
274
|
drawLine(mousePos, bestObject.pos, .1, !raycastHitPos ? new Color(0,1,0,.5) : new Color(1,0,0,.5));
|
|
275
275
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
+ (bestObject.angle>0?' ':' ') + (bestObject.angle*180/PI).toFixed(1) + '°',
|
|
282
|
-
pos = pos.add(height), ...args);
|
|
283
|
-
drawText('vel = ' + printVec2(bestObject.velocity), pos = pos.add(height), ...args);
|
|
284
|
-
drawText('size = ' + printVec2(bestObject.size), pos = pos.add(height), ...args);
|
|
285
|
-
drawText('type = ' + ( bestObject.constructor.name), pos = mousePos.subtract(height), ...args);
|
|
286
|
-
drawText('collision = ' + getTileCollisionData(mousePos), pos = mousePos.subtract(height.scale(2)), ...args);
|
|
276
|
+
const debugText = 'mouse pos = ' + mousePos +
|
|
277
|
+
'\nmouse collision = ' + getTileCollisionData(mousePos) +
|
|
278
|
+
'\n\n--- object info ---\n' +
|
|
279
|
+
bestObject.toString();
|
|
280
|
+
drawTextScreen(debugText, mousePosScreen, 24, new Color, .05, undefined, undefined, 'monospace');
|
|
287
281
|
mainContext = saveContext;
|
|
288
282
|
}
|
|
289
283
|
|
|
@@ -292,11 +286,12 @@ const debugRender = ()=>
|
|
|
292
286
|
|
|
293
287
|
{
|
|
294
288
|
// draw debug primitives
|
|
295
|
-
overlayContext.save();
|
|
296
289
|
overlayContext.lineWidth = 2;
|
|
297
290
|
const pointSize = debugPointSize * cameraScale;
|
|
298
291
|
debugPrimitives.forEach(p=>
|
|
299
292
|
{
|
|
293
|
+
overlayContext.save();
|
|
294
|
+
|
|
300
295
|
// create canvas transform from world space to screen space
|
|
301
296
|
const pos = worldToScreen(p.pos);
|
|
302
297
|
|
|
@@ -332,12 +327,12 @@ const debugRender = ()=>
|
|
|
332
327
|
p.fill && overlayContext.fill();
|
|
333
328
|
overlayContext.stroke();
|
|
334
329
|
}
|
|
330
|
+
|
|
331
|
+
overlayContext.restore();
|
|
335
332
|
});
|
|
336
333
|
|
|
337
334
|
// remove expired pritives
|
|
338
335
|
debugPrimitives = debugPrimitives.filter(r=>r.time.get()<0);
|
|
339
|
-
|
|
340
|
-
overlayContext.restore();
|
|
341
336
|
}
|
|
342
337
|
|
|
343
338
|
{
|