littlejsengine 1.4.91 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +1 -0
  2. package/build.bat +4 -6
  3. package/engine/engine.all.js +202 -105
  4. package/engine/engine.all.min.js +1 -1
  5. package/engine/engine.all.module.js +385 -181
  6. package/engine/engine.all.module.min.js +1 -1
  7. package/engine/engine.all.release.js +192 -100
  8. package/engine/engine.js +47 -16
  9. package/engine/engineAudio.js +14 -1
  10. package/engine/engineBuild.bat +8 -8
  11. package/engine/engineDebug.js +10 -5
  12. package/engine/engineDraw.js +25 -27
  13. package/engine/engineExport.js +183 -76
  14. package/engine/engineInput.js +6 -1
  15. package/engine/engineMedals.js +1 -0
  16. package/engine/engineObject.js +11 -9
  17. package/engine/engineParticles.js +5 -5
  18. package/engine/engineSettings.js +46 -20
  19. package/engine/engineTileLayer.js +13 -12
  20. package/engine/engineUtilities.js +13 -7
  21. package/engine/engineWebGL.js +11 -2
  22. package/engine/index.d.ts +1788 -1700
  23. package/examples/breakout/game.js +3 -1
  24. package/examples/breakout/index.html +4 -4
  25. package/examples/empty/index.html +1 -4
  26. package/examples/module/game.js +1 -4
  27. package/examples/module/index.html +2 -2
  28. package/examples/particles/index.html +2 -2
  29. package/examples/platformer/game.js +2 -0
  30. package/examples/platformer/gameObjects.js +3 -3
  31. package/examples/platformer/index.html +7 -7
  32. package/examples/puzzle/index.html +3 -3
  33. package/examples/stress/index.html +5 -5
  34. package/examples/typescript/build.bat +14 -0
  35. package/examples/typescript/game.js +89 -0
  36. package/examples/typescript/game.ts +117 -0
  37. package/examples/typescript/index.html +9 -0
  38. package/examples/typescript/tiles.png +0 -0
  39. package/examples/typescript/tsconfig.json +8 -0
  40. package/index.html +14 -14
  41. package/package.json +6 -6
@@ -43,7 +43,8 @@ const debugSaveCanvas = ()=> {}
43
43
  'use strict';
44
44
 
45
45
  /** A shortcut to get Math.PI
46
- * @const
46
+ * @type {Number}
47
+ * @default Math.PI
47
48
  * @memberof Utilities */
48
49
  const PI = Math.PI;
49
50
 
@@ -177,8 +178,8 @@ const randInCircle = (radius=1, minRadius=0)=> radius > 0 ? randVector(radius *
177
178
  const randVector = (length=1)=> new Vector2().setAngle(rand(2*PI), length);
178
179
 
179
180
  /** Returns a random color between the two passed in colors, combine components if linear
180
- * @param {Color} [colorA=new Color(1,1,1,1)]
181
- * @param {Color} [colorB=new Color(0,0,0,1)]
181
+ * @param {Color} [colorA=Color()]
182
+ * @param {Color} [colorB=Color(0,0,0,1)]
182
183
  * @param {Boolean} [linear]
183
184
  * @return {Color}
184
185
  * @memberof Random */
@@ -186,6 +187,8 @@ const randColor = (cA = new Color, cB = new Color(0,0,0,1), linear)=>
186
187
  linear ? cA.lerp(cB, rand()) : new Color(rand(cA.r,cB.r),rand(cA.g,cB.g),rand(cA.b,cB.b),rand(cA.a,cB.a));
187
188
 
188
189
  /** Seed used by the randSeeded function
190
+ * @type {Number}
191
+ * @default
189
192
  * @memberof Random */
190
193
  let randSeed = 1;
191
194
 
@@ -324,7 +327,8 @@ class Vector2
324
327
 
325
328
  /** Sets this vector with angle and length passed in
326
329
  * @param {Number} [angle=0]
327
- * @param {Number} [length=1] */
330
+ * @param {Number} [length=1]
331
+ * @return {Vector2} */
328
332
  setAngle(a=0, length=1) { this.x = length*Math.sin(a); this.y = length*Math.cos(a); return this; }
329
333
 
330
334
  /** Returns copy of this vector rotated by the angle passed in
@@ -393,9 +397,11 @@ const colorHSLA = (h, s, l, a)=> new Color().setHSLA(h, s, l, a);
393
397
  /**
394
398
  * Color object (red, green, blue, alpha) with some helpful functions
395
399
  * @example
396
- * let a = new Color; // white
397
- * let b = new Color(1, 0, 0); // red
398
- * let c = new Color(0, 0, 0, 0); // transparent black
400
+ * let a = new Color; // white
401
+ * let b = new Color(1, 0, 0); // red
402
+ * let c = new Color(0, 0, 0, 0); // transparent black
403
+ * let d = colorRGBA(0, 0, 1); // blue using rgb color
404
+ * let e = colorHSLA(.3, 1, .5); // green using hsl color
399
405
  */
400
406
  class Color
401
407
  {
@@ -619,11 +625,12 @@ class Timer
619
625
 
620
626
  /** Position of camera in world space
621
627
  * @type {Vector2}
622
- * @default
628
+ * @default Vector2()
623
629
  * @memberof Settings */
624
630
  let cameraPos = vec2();
625
631
 
626
632
  /** Scale of camera in world space
633
+ * @type {Number}
627
634
  * @default
628
635
  * @memberof Settings */
629
636
  let cameraScale = 32;
@@ -632,24 +639,26 @@ let cameraScale = 32;
632
639
  // Display settings
633
640
 
634
641
  /** The max size of the canvas, centered if window is larger
635
- * @type {Vector2}
636
- * @default
642
+ * @type {Vector2}
643
+ * @default Vector2(1920,1200)
637
644
  * @memberof Settings */
638
645
  let canvasMaxSize = vec2(1920, 1200);
639
646
 
640
647
  /** Fixed size of the canvas, if enabled canvas size never changes
641
648
  * - you may also need to set mainCanvasSize if using screen space coords in startup
642
- * @type {Vector2}
643
- * @default
649
+ * @type {Vector2}
650
+ * @default Vector2()
644
651
  * @memberof Settings */
645
652
  let canvasFixedSize = vec2();
646
653
 
647
654
  /** Disables anti aliasing for pixel art if true
655
+ * @type {Boolean}
648
656
  * @default
649
657
  * @memberof Settings */
650
658
  let cavasPixelated = 1;
651
659
 
652
660
  /** Default font used for text rendering
661
+ * @type {String}
653
662
  * @default
654
663
  * @memberof Settings */
655
664
  let fontDefault = 'arial';
@@ -658,11 +667,13 @@ let fontDefault = 'arial';
658
667
  // WebGL settings
659
668
 
660
669
  /** Enable webgl rendering, webgl can be disabled and removed from build (with some features disabled)
670
+ * @type {Boolean}
661
671
  * @default
662
672
  * @memberof Settings */
663
673
  let glEnable = 1;
664
674
 
665
675
  /** Fixes slow rendering in some browsers by not compositing the WebGL canvas
676
+ * @type {Boolean}
666
677
  * @default
667
678
  * @memberof Settings */
668
679
  let glOverlay = 1;
@@ -671,12 +682,13 @@ let glOverlay = 1;
671
682
  // Tile sheet settings
672
683
 
673
684
  /** Default size of tiles in pixels
674
- * @type {Vector2}
675
- * @default
685
+ * @type {Vector2}
686
+ * @default Vector2(16,16)
676
687
  * @memberof Settings */
677
688
  let tileSizeDefault = vec2(16);
678
689
 
679
690
  /** Prevent tile bleeding from neighbors in pixels
691
+ * @type {Number}
680
692
  * @default
681
693
  * @memberof Settings */
682
694
  let tileFixBleedScale = .3;
@@ -684,53 +696,56 @@ let tileFixBleedScale = .3;
684
696
  ///////////////////////////////////////////////////////////////////////////////
685
697
  // Object settings
686
698
 
687
- /** Default size of objects
688
- * @type {Vector2}
689
- * @default
690
- * @memberof Settings */
691
- let objectDefaultSize = vec2(1);
692
-
693
699
  /** Enable physics solver for collisions between objects
700
+ * @type {Boolean}
694
701
  * @default
695
702
  * @memberof Settings */
696
703
  let enablePhysicsSolver = 1;
697
704
 
698
705
  /** Default object mass for collison calcuations (how heavy objects are)
706
+ * @type {Number}
699
707
  * @default
700
708
  * @memberof Settings */
701
709
  let objectDefaultMass = 1;
702
710
 
703
711
  /** How much to slow velocity by each frame (0-1)
712
+ * @type {Number}
704
713
  * @default
705
714
  * @memberof Settings */
706
- let objectDefaultDamping = .99;
715
+ let objectDefaultDamping = 1;
707
716
 
708
717
  /** How much to slow angular velocity each frame (0-1)
718
+ * @type {Number}
709
719
  * @default
710
720
  * @memberof Settings */
711
- let objectDefaultAngleDamping = .99;
721
+ let objectDefaultAngleDamping = 1;
712
722
 
713
723
  /** How much to bounce when a collision occurs (0-1)
714
- * @default
724
+ * @type {Number}
725
+ * @default 0
715
726
  * @memberof Settings */
716
727
  let objectDefaultElasticity = 0;
717
728
 
718
729
  /** How much to slow when touching (0-1)
730
+ * @type {Number}
719
731
  * @default
720
732
  * @memberof Settings */
721
733
  let objectDefaultFriction = .8;
722
734
 
723
735
  /** Clamp max speed to avoid fast objects missing collisions
736
+ * @type {Number}
724
737
  * @default
725
738
  * @memberof Settings */
726
739
  let objectMaxSpeed = 1;
727
740
 
728
741
  /** How much gravity to apply to objects along the Y axis, negative is down
729
- * @default
742
+ * @type {Number}
743
+ * @default 0
730
744
  * @memberof Settings */
731
745
  let gravity = 0;
732
746
 
733
747
  /** Scales emit rate of particles, useful for low graphics mode (0 disables particle emitters)
748
+ * @type {Number}
734
749
  * @default
735
750
  * @memberof Settings */
736
751
  let particleEmitRateScale = 1;
@@ -739,16 +754,19 @@ let particleEmitRateScale = 1;
739
754
  // Input settings
740
755
 
741
756
  /** Should gamepads be allowed
757
+ * @type {Boolean}
742
758
  * @default
743
759
  * @memberof Settings */
744
760
  let gamepadsEnable = 1;
745
761
 
746
762
  /** If true, the dpad input is also routed to the left analog stick (for better accessability)
763
+ * @type {Boolean}
747
764
  * @default
748
765
  * @memberof Settings */
749
766
  let gamepadDirectionEmulateStick = 1;
750
767
 
751
768
  /** If true the WASD keys are also routed to the direction keys (for better accessability)
769
+ * @type {Boolean}
752
770
  * @default
753
771
  * @memberof Settings */
754
772
  let inputWASDEmulateDirection = 1;
@@ -756,26 +774,31 @@ let inputWASDEmulateDirection = 1;
756
774
  /** True if touch gamepad should appear on mobile devices
757
775
  * <br> - Supports left analog stick, 4 face buttons and start button (button 9)
758
776
  * <br> - Must be set by end of gameInit to be activated
759
- * @default
777
+ * @type {Boolean}
778
+ * @default 0
760
779
  * @memberof Settings */
761
780
  let touchGamepadEnable = 0;
762
781
 
763
782
  /** True if touch gamepad should be analog stick or false to use if 8 way dpad
783
+ * @type {Boolean}
764
784
  * @default
765
785
  * @memberof Settings */
766
786
  let touchGamepadAnalog = 1;
767
787
 
768
788
  /** Size of virutal gamepad for touch devices in pixels
789
+ * @type {Number}
769
790
  * @default
770
791
  * @memberof Settings */
771
792
  let touchGamepadSize = 99;
772
793
 
773
794
  /** Transparency of touch gamepad overlay
795
+ * @type {Number}
774
796
  * @default
775
797
  * @memberof Settings */
776
798
  let touchGamepadAlpha = .3;
777
799
 
778
800
  /** Allow vibration hardware if it exists
801
+ * @type {Boolean}
779
802
  * @default
780
803
  * @memberof Settings */
781
804
  let vibrateEnable = 1;
@@ -784,21 +807,25 @@ let vibrateEnable = 1;
784
807
  // Audio settings
785
808
 
786
809
  /** All audio code can be disabled and removed from build
810
+ * @type {Boolean}
787
811
  * @default
788
812
  * @memberof Settings */
789
813
  let soundEnable = 1;
790
814
 
791
815
  /** Volume scale to apply to all sound, music and speech
816
+ * @type {Number}
792
817
  * @default
793
818
  * @memberof Settings */
794
819
  let soundVolume = .5;
795
820
 
796
821
  /** Default range where sound no longer plays
822
+ * @type {Number}
797
823
  * @default
798
824
  * @memberof Settings */
799
825
  let soundDefaultRange = 40;
800
826
 
801
827
  /** Default range percent to start tapering off sound (0-1)
828
+ * @type {Number}
802
829
  * @default
803
830
  * @memberof Settings */
804
831
  let soundDefaultTaper = .7;
@@ -807,27 +834,32 @@ let soundDefaultTaper = .7;
807
834
  // Medals settings
808
835
 
809
836
  /** How long to show medals for in seconds
837
+ * @type {Number}
810
838
  * @default
811
839
  * @memberof Settings */
812
840
  let medalDisplayTime = 5;
813
841
 
814
842
  /** How quickly to slide on/off medals in seconds
843
+ * @type {Number}
815
844
  * @default
816
845
  * @memberof Settings */
817
846
  let medalDisplaySlideTime = .5;
818
847
 
819
848
  /** Size of medal display
820
- * @default
849
+ * @type {Vector2}
850
+ * @default Vector2(640,80)
821
851
  * @memberof Settings */
822
852
  let medalDisplaySize = vec2(640, 80);
823
853
 
824
854
  /** Size of icon in medal display
855
+ * @type {Number}
825
856
  * @default
826
857
  * @memberof Settings */
827
858
  let medalDisplayIconSize = 50;
828
859
 
829
860
  /** Set to stop medals from being unlockable (like if cheats are enabled)
830
- * @default
861
+ * @type {Boolean}
862
+ * @default 0
831
863
  * @memberof Settings */
832
864
  let medalsPreventUnlock;
833
865
  /*
@@ -849,43 +881,71 @@ let medalsPreventUnlock;
849
881
  - Call engineInit() to start it up!
850
882
  */
851
883
 
884
+ /**
885
+ * LittleJS Engine Globals
886
+ * @namespace Engine
887
+ */
888
+
852
889
  'use strict';
853
890
 
854
- /** Name of engine */
891
+ /** Name of engine
892
+ * @type {String}
893
+ * @default
894
+ * @memberof Engine */
855
895
  const engineName = 'LittleJS';
856
896
 
857
- /** Version of engine */
858
- const engineVersion = '1.4.9';
897
+ /** Version of engine
898
+ * @type {String}
899
+ * @default
900
+ * @memberof Engine */
901
+ const engineVersion = '1.5.1';
859
902
 
860
903
  /** Frames per second to update objects
861
- * @default */
904
+ * @type {Number}
905
+ * @default
906
+ * @memberof Engine */
862
907
  const frameRate = 60;
863
908
 
864
909
  /** How many seconds each frame lasts, engine uses a fixed time step
865
- * @default 1/60 */
910
+ * @type {Number}
911
+ * @default 1/60
912
+ * @memberof Engine */
866
913
  const timeDelta = 1/frameRate;
867
914
 
868
- /** Array containing all engine objects */
915
+ /** Array containing all engine objects
916
+ * @type {Array}
917
+ * @memberof Engine */
869
918
  let engineObjects = [];
870
919
 
871
- /** Array containing only objects that are set to collide with other objects this frame (for optimization) */
920
+ /** Array containing only objects that are set to collide with other objects this frame (for optimization)
921
+ * @type {Array}
922
+ * @memberof Engine */
872
923
  let engineObjectsCollide = [];
873
924
 
874
- /** Current update frame, used to calculate time */
925
+ /** Current update frame, used to calculate time
926
+ * @type {Number}
927
+ * @memberof Engine */
875
928
  let frame = 0;
876
929
 
877
- /** Current engine time since start in seconds, derived from frame */
930
+ /** Current engine time since start in seconds, derived from frame
931
+ * @type {Number}
932
+ * @memberof Engine */
878
933
  let time = 0;
879
934
 
880
- /** Actual clock time since start in seconds (not affected by pause or frame rate clamping) */
935
+ /** Actual clock time since start in seconds (not affected by pause or frame rate clamping)
936
+ * @type {Number}
937
+ * @memberof Engine */
881
938
  let timeReal = 0;
882
939
 
883
- /** Is the game paused? Causes time and objects to not be updated */
940
+ /** Is the game paused? Causes time and objects to not be updated
941
+ * @type {Boolean}
942
+ * @default 0
943
+ * @memberof Engine */
884
944
  let paused = 0;
885
945
 
886
946
  /** Set if game is paused
887
947
  * @param {Boolean} paused
888
- */
948
+ * @memberof Engine */
889
949
  function setPaused(_paused) { paused = _paused; }
890
950
 
891
951
  ///////////////////////////////////////////////////////////////////////////////
@@ -897,7 +957,7 @@ function setPaused(_paused) { paused = _paused; }
897
957
  * @param {Function} gameRender - Called before objects are rendered, draw any background effects that appear behind objects
898
958
  * @param {Function} gameRenderPost - Called after objects are rendered, draw effects or hud that appear above all objects
899
959
  * @param {String} [tileImageSource] - Tile image to use, everything starts when the image is finished loading
900
- */
960
+ * @memberof Engine */
901
961
  function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, tileImageSource)
902
962
  {
903
963
  // init engine when tiles load or fail to load
@@ -1061,7 +1121,8 @@ function enginePreRender()
1061
1121
  glEnable && glPreRender();
1062
1122
  }
1063
1123
 
1064
- /** Update each engine object, remove destroyed objects, and update time */
1124
+ /** Update each engine object, remove destroyed objects, and update time
1125
+ * @memberof Engine */
1065
1126
  function engineObjectsUpdate()
1066
1127
  {
1067
1128
  // get list of solid objects for physics optimzation
@@ -1087,7 +1148,8 @@ function engineObjectsUpdate()
1087
1148
  time = ++frame / frameRate;
1088
1149
  }
1089
1150
 
1090
- /** Destroy and remove all objects */
1151
+ /** Destroy and remove all objects
1152
+ * @memberof Engine */
1091
1153
  function engineObjectsDestroy()
1092
1154
  {
1093
1155
  for (const o of engineObjects)
@@ -1099,7 +1161,8 @@ function engineObjectsDestroy()
1099
1161
  * @param {Vector2} [pos] - Center of test area
1100
1162
  * @param {Number} [size] - Radius of circle if float, rectangle size if Vector2
1101
1163
  * @param {Function} [callbackFunction] - Calls this function on every object that passes the test
1102
- * @param {Array} [objects=engineObjects] - List of objects to check */
1164
+ * @param {Array} [objects=engineObjects] - List of objects to check
1165
+ * @memberof Engine */
1103
1166
  function engineObjectsCallback(pos, size, callbackFunction, objects=engineObjects)
1104
1167
  {
1105
1168
  if (!pos) // all objects
@@ -1153,15 +1216,15 @@ function engineObjectsCallback(pos, size, callbackFunction, objects=engineObject
1153
1216
  class EngineObject
1154
1217
  {
1155
1218
  /** Create an engine object and adds it to the list of objects
1156
- * @param {Vector2} [position=new Vector2()] - World space position of the object
1157
- * @param {Vector2} [size=objectDefaultSize] - World space size of the object
1219
+ * @param {Vector2} [position=Vector2()] - World space position of the object
1220
+ * @param {Vector2} [size=Vector2(1,1)] - World space size of the object
1158
1221
  * @param {Number} [tileIndex=-1] - Tile to use to render object (-1 is untextured)
1159
1222
  * @param {Vector2} [tileSize=tileSizeDefault] - Size of tile in source pixels
1160
1223
  * @param {Number} [angle=0] - Angle the object is rotated by
1161
- * @param {Color} [color] - Color to apply to tile when rendered
1224
+ * @param {Color} [color=Color()] - Color to apply to tile when rendered
1162
1225
  * @param {Number} [renderOrder=0] - Objects sorted by renderOrder before being rendered
1163
1226
  */
1164
- constructor(pos=vec2(), size=objectDefaultSize, tileIndex=-1, tileSize=tileSizeDefault, angle=0, color, renderOrder=0)
1227
+ constructor(pos=vec2(), size=vec2(1), tileIndex=-1, tileSize=tileSizeDefault, angle=0, color, renderOrder=0)
1165
1228
  {
1166
1229
  // set passed in params
1167
1230
  ASSERT(isVector2(pos) && isVector2(size)); // ensure pos and size are vec2s
@@ -1198,7 +1261,7 @@ class EngineObject
1198
1261
  this.gravityScale = 1;
1199
1262
  /** @property {Number} [renderOrder=0] - Objects are sorted by render order */
1200
1263
  this.renderOrder = renderOrder;
1201
- /** @property {Vector2} [velocity=new Vector2()] - Velocity of the object */
1264
+ /** @property {Vector2} [velocity=Vector2()] - Velocity of the object */
1202
1265
  this.velocity = new Vector2();
1203
1266
  /** @property {Number} [angleVelocity=0] - Angular velocity of the object */
1204
1267
  this.angleVelocity = 0;
@@ -1441,7 +1504,7 @@ class EngineObject
1441
1504
 
1442
1505
  /** Attaches a child to this with a given local transform
1443
1506
  * @param {EngineObject} child
1444
- * @param {Vector2} [localPos=new Vector2]
1507
+ * @param {Vector2} [localPos=Vector2()]
1445
1508
  * @param {Number} [localAngle=0] */
1446
1509
  addChild(child, localPos=vec2(), localAngle=0)
1447
1510
  {
@@ -1462,9 +1525,9 @@ class EngineObject
1462
1525
  }
1463
1526
 
1464
1527
  /** Set how this object collides
1465
- * @param {boolean} [collideSolidObjects=1] - Does it collide with solid objects
1466
- * @param {boolean} [isSolid=1] - Does it collide with and block other objects (expensive in large numbers)
1467
- * @param {boolean} [collideTiles=1] - Does it collide with the tile collision */
1528
+ * @param {Boolean} [collideSolidObjects=1] - Does it collide with solid objects
1529
+ * @param {Boolean} [isSolid=1] - Does it collide with and block other objects (expensive in large numbers)
1530
+ * @param {Boolean} [collideTiles=1] - Does it collide with the tile collision */
1468
1531
  setCollision(collideSolidObjects=1, isSolid=1, collideTiles=1)
1469
1532
  {
1470
1533
  ASSERT(collideSolidObjects || !isSolid); // solid objects must be set to collide
@@ -1474,6 +1537,8 @@ class EngineObject
1474
1537
  this.collideTiles = collideTiles;
1475
1538
  }
1476
1539
 
1540
+ /** Returns string containg info about this object for debugging
1541
+ * @return {String} */
1477
1542
  toString()
1478
1543
  {
1479
1544
  if (debug)
@@ -1543,7 +1608,7 @@ let overlayContext;
1543
1608
  let mainCanvasSize = vec2();
1544
1609
 
1545
1610
  /** Tile sheet for batch rendering system
1546
- * @type {Image}
1611
+ * @type {CanvasImageSource}
1547
1612
  * @memberof Draw */
1548
1613
  const tileImage = new Image;
1549
1614
 
@@ -1573,15 +1638,15 @@ const worldToScreen = (worldPos)=>
1573
1638
  }
1574
1639
 
1575
1640
  /** Draw textured tile centered in world space, with color applied if using WebGL
1576
- * @param {Vector2} pos - Center of the tile in world space
1577
- * @param {Vector2} [size=new Vector2(1,1)] - Size of the tile in world space
1578
- * @param {Number} [tileIndex=-1] - Tile index to use, negative is untextured
1579
- * @param {Vector2} [tileSize=tileSizeDefault] - Tile size in source pixels
1580
- * @param {Color} [color=new Color(1,1,1)] - Color to modulate with
1581
- * @param {Number} [angle=0] - Angle to rotate by
1582
- * @param {Boolean} [mirror=0] - If true image is flipped along the Y axis
1583
- * @param {Color} [additiveColor=new Color(0,0,0,0)] - Additive color to be applied
1584
- * @param {Boolean} [useWebGL=glEnable] - Use accelerated WebGL rendering
1641
+ * @param {Vector2} pos - Center of the tile in world space
1642
+ * @param {Vector2} [size=Vector2(1,1)] - Size of the tile in world space
1643
+ * @param {Number} [tileIndex=-1] - Tile index to use, negative is untextured
1644
+ * @param {Vector2} [tileSize=tileSizeDefault] - Tile size in source pixels
1645
+ * @param {Color} [color=Color()] - Color to modulate with
1646
+ * @param {Number} [angle=0] - Angle to rotate by
1647
+ * @param {Boolean} [mirror=0] - If true image is flipped along the Y axis
1648
+ * @param {Color} [additiveColor=Color(0,0,0,0)] - Additive color to be applied
1649
+ * @param {Boolean} [useWebGL=glEnable] - Use accelerated WebGL rendering
1585
1650
  * @memberof Draw */
1586
1651
  function drawTile(pos, size=vec2(1), tileIndex=-1, tileSize=tileSizeDefault, color=new Color, angle=0, mirror,
1587
1652
  additiveColor=new Color(0,0,0,0), useWebGL=glEnable)
@@ -1636,8 +1701,8 @@ function drawTile(pos, size=vec2(1), tileIndex=-1, tileSize=tileSizeDefault, col
1636
1701
 
1637
1702
  /** Draw colored rect centered on pos
1638
1703
  * @param {Vector2} pos
1639
- * @param {Vector2} [size=new Vector2(1,1)]
1640
- * @param {Color} [color=new Color(1,1,1)]
1704
+ * @param {Vector2} [size=Vector2(1,1)]
1705
+ * @param {Color} [color=Color()]
1641
1706
  * @param {Number} [angle=0]
1642
1707
  * @param {Boolean} [useWebGL=glEnable]
1643
1708
  * @memberof Draw */
@@ -1648,13 +1713,13 @@ function drawRect(pos, size, color, angle, useWebGL)
1648
1713
 
1649
1714
  /** Draw textured tile centered on pos in screen space
1650
1715
  * @param {Vector2} pos - Center of the tile
1651
- * @param {Vector2} [size=new Vector2(1,1)] - Size of the tile
1716
+ * @param {Vector2} [size=Vector2(1,1)] - Size of the tile
1652
1717
  * @param {Number} [tileIndex=-1] - Tile index to use, negative is untextured
1653
1718
  * @param {Vector2} [tileSize=tileSizeDefault] - Tile size in source pixels
1654
- * @param {Color} [color=new Color]
1719
+ * @param {Color} [color=Color()]
1655
1720
  * @param {Number} [angle=0]
1656
1721
  * @param {Boolean} [mirror=0]
1657
- * @param {Color} [additiveColor=new Color(0,0,0,0)]
1722
+ * @param {Color} [additiveColor=Color(0,0,0,0)]
1658
1723
  * @param {Boolean} [useWebGL=glEnable]
1659
1724
  * @memberof Draw */
1660
1725
  function drawTileScreenSpace(pos, size=vec2(1), tileIndex, tileSize, color, angle, mirror, additiveColor, useWebGL)
@@ -1664,8 +1729,8 @@ function drawTileScreenSpace(pos, size=vec2(1), tileIndex, tileSize, color, angl
1664
1729
 
1665
1730
  /** Draw colored rectangle in screen space
1666
1731
  * @param {Vector2} pos
1667
- * @param {Vector2} [size=new Vector2(1,1)]
1668
- * @param {Color} [color=new Color(1,1,1)]
1732
+ * @param {Vector2} [size=Vector2(1,1)]
1733
+ * @param {Color} [color=Color()]
1669
1734
  * @param {Number} [angle=0]
1670
1735
  * @param {Boolean} [useWebGL=glEnable]
1671
1736
  * @memberof Draw */
@@ -1678,7 +1743,7 @@ function drawRectScreenSpace(pos, size, color, angle, useWebGL)
1678
1743
  * @param {Vector2} posA
1679
1744
  * @param {Vector2} posB
1680
1745
  * @param {Number} [thickness=.1]
1681
- * @param {Color} [color=new Color(1,1,1)]
1746
+ * @param {Color} [color=Color()]
1682
1747
  * @param {Boolean} [useWebGL=glEnable]
1683
1748
  * @memberof Draw */
1684
1749
  function drawLine(posA, posB, thickness=.1, color, useWebGL)
@@ -1726,9 +1791,9 @@ function setBlendMode(additive, useWebGL=glEnable)
1726
1791
  * @param {String} text
1727
1792
  * @param {Vector2} pos
1728
1793
  * @param {Number} [size=1]
1729
- * @param {Color} [color=new Color(1,1,1)]
1794
+ * @param {Color} [color=Color()]
1730
1795
  * @param {Number} [lineWidth=0]
1731
- * @param {Color} [lineColor=new Color(0,0,0)]
1796
+ * @param {Color} [lineColor=Color(0,0,0)]
1732
1797
  * @param {String} [textAlign='center']
1733
1798
  * @memberof Draw */
1734
1799
  function drawTextScreen(text, pos, size=1, color=new Color, lineWidth=0, lineColor=new Color(0,0,0), textAlign='center', font=fontDefault, context=overlayContext)
@@ -1755,18 +1820,20 @@ function drawTextScreen(text, pos, size=1, color=new Color, lineWidth=0, lineCol
1755
1820
  * @param {String} text
1756
1821
  * @param {Vector2} pos
1757
1822
  * @param {Number} [size=1]
1758
- * @param {Color} [color=new Color(1,1,1)]
1823
+ * @param {Color} [color=Color()]
1759
1824
  * @param {Number} [lineWidth=0]
1760
- * @param {Color} [lineColor=new Color(0,0,0)]
1825
+ * @param {Color} [lineColor=Color(0,0,0)]
1761
1826
  * @param {String} [textAlign='center']
1762
1827
  * @memberof Draw */
1763
- function drawText(text, pos, size=1, color, lineWidth, lineColor, textAlign, font)
1828
+ function drawText(text, pos, size=1, color, lineWidth=0, lineColor, textAlign, font)
1764
1829
  {
1765
1830
  drawTextScreen(text, worldToScreen(pos), size*cameraScale, color, lineWidth*cameraScale, lineColor, textAlign, font, mainContext);
1766
1831
  }
1767
1832
 
1768
1833
  ///////////////////////////////////////////////////////////////////////////////
1769
1834
 
1835
+ let engineFontImage;
1836
+
1770
1837
  /**
1771
1838
  * Font Image Object - Draw text on a 2D canvas by using characters in an image
1772
1839
  * <br> - 96 characters (from space to tilde) are stored in an image
@@ -1779,10 +1846,6 @@ function drawText(text, pos, size=1, color, lineWidth, lineColor, textAlign, fon
1779
1846
  * // draw text
1780
1847
  * font.drawTextScreen("LittleJS\nHello World!", vec2(200, 50));
1781
1848
  */
1782
-
1783
- // default font image created by engine
1784
- let engineFontImage;
1785
-
1786
1849
  class FontImage
1787
1850
  {
1788
1851
  /** Create an image font
@@ -1913,18 +1976,21 @@ const keyWasReleased = (key, device=0)=> inputData[device] && inputData[device][
1913
1976
  const clearInput = ()=> inputData = [[]];
1914
1977
 
1915
1978
  /** Returns true if mouse button is down
1979
+ * @function
1916
1980
  * @param {Number} button
1917
1981
  * @return {Boolean}
1918
1982
  * @memberof Input */
1919
1983
  const mouseIsDown = keyIsDown;
1920
1984
 
1921
1985
  /** Returns true if mouse button was pressed
1986
+ * @function
1922
1987
  * @param {Number} button
1923
1988
  * @return {Boolean}
1924
1989
  * @memberof Input */
1925
1990
  const mouseWasPressed = keyWasPressed;
1926
1991
 
1927
1992
  /** Returns true if mouse button was released
1993
+ * @function
1928
1994
  * @param {Number} button
1929
1995
  * @return {Boolean}
1930
1996
  * @memberof Input */
@@ -1941,14 +2007,17 @@ let mousePos = vec2();
1941
2007
  let mousePosScreen = vec2();
1942
2008
 
1943
2009
  /** Mouse wheel delta this frame
2010
+ * @type {Number}
1944
2011
  * @memberof Input */
1945
2012
  let mouseWheel = 0;
1946
2013
 
1947
2014
  /** Returns true if user is using gamepad (has more recently pressed a gamepad button)
2015
+ * @type {Boolean}
1948
2016
  * @memberof Input */
1949
2017
  let isUsingGamepad = 0;
1950
2018
 
1951
2019
  /** Prevents input continuing to the default browser handling (false by default)
2020
+ * @type {Boolean}
1952
2021
  * @memberof Input */
1953
2022
  let preventDefaultInput = 0;
1954
2023
 
@@ -2124,7 +2193,6 @@ const vibrateStop = ()=> vibrate(0);
2124
2193
  // Touch input
2125
2194
 
2126
2195
  /** True if a touch device has been detected
2127
- * @const {boolean}
2128
2196
  * @memberof Input */
2129
2197
  const isTouchDevice = window.ontouchstart !== undefined;
2130
2198
 
@@ -2454,8 +2522,21 @@ class Music
2454
2522
  {
2455
2523
  if (!soundEnable) return;
2456
2524
 
2457
- return playSamples(this.cachedSamples, volume, 1, 0, loop);
2525
+ return this.source = playSamples(this.cachedSamples, volume, 1, 0, loop);
2526
+ }
2527
+
2528
+ /** Stop the music */
2529
+ stop()
2530
+ {
2531
+ if (this.source)
2532
+ this.source.stop();
2533
+ this.source = 0;
2458
2534
  }
2535
+
2536
+ /** Check if music is playing
2537
+ * @return {Boolean}
2538
+ */
2539
+ isPlaying() { return this.source; }
2459
2540
  }
2460
2541
 
2461
2542
  /** Play an mp3 or wav audio from a local file or url
@@ -2782,6 +2863,7 @@ function zzfxM(instruments, patterns, sequence, BPM = 125)
2782
2863
  'use strict';
2783
2864
 
2784
2865
  /** The tile collision layer array, use setTileCollisionData and getTileCollisionData to access
2866
+ * @type {Array}
2785
2867
  * @memberof TileCollision */
2786
2868
  let tileCollision = [];
2787
2869
 
@@ -2817,7 +2899,7 @@ const getTileCollisionData = (pos)=>
2817
2899
 
2818
2900
  /** Check if collision with another object should occur
2819
2901
  * @param {Vector2} pos
2820
- * @param {Vector2} [size=new Vector2(1,1)]
2902
+ * @param {Vector2} [size=Vector2(1,1)]
2821
2903
  * @param {EngineObject} [object]
2822
2904
  * @return {Boolean}
2823
2905
  * @memberof TileCollision */
@@ -2885,11 +2967,11 @@ function tileCollisionRaycast(posStart, posEnd, object)
2885
2967
  class TileLayerData
2886
2968
  {
2887
2969
  /** Create a tile layer data object, one for each tile in a TileLayer
2888
- * @param {Number} [tile] - The tile to use, untextured if undefined
2889
- * @param {Number} [direction=0] - Integer direction of tile, in 90 degree increments
2890
- * @param {Boolean} [mirror=0] - If the tile should be mirrored along the x axis
2891
- * @param {Color} [color=new Color(1,1,1)] - Color of the tile */
2892
- constructor(tile, direction=0, mirror=0, color=new Color)
2970
+ * @param {Number} [tile] - The tile to use, untextured if undefined
2971
+ * @param {Number} [direction=0] - Integer direction of tile, in 90 degree increments
2972
+ * @param {Boolean} [mirror=0] - If the tile should be mirrored along the x axis
2973
+ * @param {Color} [color=Color()] - Color of the tile */
2974
+ constructor(tile, direction=0, mirror=0, color=new Color())
2893
2975
  {
2894
2976
  /** @property {Number} - The tile to use, untextured if undefined */
2895
2977
  this.tile = tile;
@@ -2920,10 +3002,10 @@ class TileLayerData
2920
3002
  class TileLayer extends EngineObject
2921
3003
  {
2922
3004
  /** Create a tile layer object
2923
- * @param {Vector2} [position=new Vector2()] - World space position
3005
+ * @param {Vector2} [position=Vector2()] - World space position
2924
3006
  * @param {Vector2} [size=tileCollisionSize] - World space size
2925
3007
  * @param {Vector2} [tileSize=tileSizeDefault] - Size of tiles in source pixels
2926
- * @param {Vector2} [scale=new Vector2(1,1)] - How much to scale this layer when rendered
3008
+ * @param {Vector2} [scale=Vector2(1,1)] - How much to scale this layer when rendered
2927
3009
  * @param {Number} [renderOrder=0] - Objects sorted by renderOrder before being rendered
2928
3010
  */
2929
3011
  constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1), renderOrder=0)
@@ -3075,10 +3157,10 @@ constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1)
3075
3157
 
3076
3158
  /** Draw a tile directly onto the layer canvas
3077
3159
  * @param {Vector2} pos
3078
- * @param {Vector2} [size=new Vector2(1,1)]
3160
+ * @param {Vector2} [size=Vector2(1,1)]
3079
3161
  * @param {Number} [tileIndex=-1]
3080
3162
  * @param {Vector2} [tileSize=tileSizeDefault]
3081
- * @param {Color} [color=new Color(1,1,1)]
3163
+ * @param {Color} [color=Color()]
3082
3164
  * @param {Number} [angle=0]
3083
3165
  * @param {Boolean} [mirror=0] */
3084
3166
  drawTile(pos, size=vec2(1), tileIndex=-1, tileSize=tileSizeDefault, color=new Color, angle, mirror)
@@ -3104,8 +3186,8 @@ constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1)
3104
3186
 
3105
3187
  /** Draw a rectangle directly onto the layer canvas
3106
3188
  * @param {Vector2} pos
3107
- * @param {Vector2} [size=new Vector2(1,1)]
3108
- * @param {Color} [color=new Color(1,1,1)]
3189
+ * @param {Vector2} [size=Vector2(1,1)]
3190
+ * @param {Color} [color=Color()]
3109
3191
  * @param {Number} [angle=0] */
3110
3192
  drawRect(pos, size, color, angle)
3111
3193
  { this.drawTile(pos, size, -1, 0, color, angle); }
@@ -3146,11 +3228,11 @@ class ParticleEmitter extends EngineObject
3146
3228
  * @param {Number} [emitRate=100] - How many particles per second to spawn, does not emit if 0
3147
3229
  * @param {Number} [emitConeAngle=PI] - Local angle to apply velocity to particles from emitter
3148
3230
  * @param {Number} [tileIndex=-1] - Index into tile sheet, if <0 no texture is applied
3149
- * @param {Number} [tileSize=tileSizeDefault] - Tile size for particles
3150
- * @param {Color} [colorStartA=new Color(1,1,1)] - Color at start of life 1, randomized between start colors
3151
- * @param {Color} [colorStartB=new Color(1,1,1)] - Color at start of life 2, randomized between start colors
3152
- * @param {Color} [colorEndA=new Color(1,1,1,0)] - Color at end of life 1, randomized between end colors
3153
- * @param {Color} [colorEndB=new Color(1,1,1,0)] - Color at end of life 2, randomized between end colors
3231
+ * @param {Vector2} [tileSize=tileSizeDefault] - Tile size for particles
3232
+ * @param {Color} [colorStartA=Color()] - Color at start of life 1, randomized between start colors
3233
+ * @param {Color} [colorStartB=Color()] - Color at start of life 2, randomized between start colors
3234
+ * @param {Color} [colorEndA=Color(1,1,1,0)] - Color at end of life 1, randomized between end colors
3235
+ * @param {Color} [colorEndB=Color(1,1,1,0)] - Color at end of life 2, randomized between end colors
3154
3236
  * @param {Number} [particleTime=.5] - How long particles live
3155
3237
  * @param {Number} [sizeStart=.1] - How big are particles at start
3156
3238
  * @param {Number} [sizeEnd=1] - How big are particles at end
@@ -3430,6 +3512,7 @@ class Particle extends EngineObject
3430
3512
  'use strict';
3431
3513
 
3432
3514
  /** List of all medals
3515
+ * @type {Array}
3433
3516
  * @memberof Medals */
3434
3517
  const medals = [];
3435
3518
 
@@ -3981,12 +4064,13 @@ function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba, rgbaAdd
3981
4064
  ///////////////////////////////////////////////////////////////////////////////
3982
4065
  // post processing - can be enabled to pass other canvases through a final shader
3983
4066
 
3984
- let glPostShader, glPostArrayBuffer, glPostTexture;
4067
+ let glPostShader, glPostArrayBuffer, glPostTexture, glPostIncludeOverlay;
3985
4068
 
3986
4069
  /** Set up a post processing shader
3987
4070
  * @param {String} shaderCode
4071
+ * @param {Boolean} includeOverlay
3988
4072
  * @memberof WebGL */
3989
- function glInitPostProcess(shaderCode)
4073
+ function glInitPostProcess(shaderCode, includeOverlay)
3990
4074
  {
3991
4075
  ASSERT(!glPostShader); // can only have 1 post effects shader
3992
4076
 
@@ -4015,6 +4099,7 @@ function glInitPostProcess(shaderCode)
4015
4099
  // create buffer and texture
4016
4100
  glPostArrayBuffer = glContext.createBuffer();
4017
4101
  glPostTexture = glCreateTexture();
4102
+ glPostIncludeOverlay = includeOverlay;
4018
4103
 
4019
4104
  // hide the original 2d canvas
4020
4105
  mainCanvas.style.visibility = 'hidden';
@@ -4035,6 +4120,13 @@ function glRenderPostProcess()
4035
4120
  else // set viewport
4036
4121
  glContext.viewport(0, 0, glCanvas.width = mainCanvas.width, glCanvas.height = mainCanvas.height);
4037
4122
 
4123
+ if (glPostIncludeOverlay)
4124
+ {
4125
+ // copy overlay canvas so it will be included in post processing
4126
+ mainContext.drawImage(overlayCanvas, 0, 0);
4127
+ overlayCanvas.width |= 0;
4128
+ }
4129
+
4038
4130
  // setup shader program to draw one triangle
4039
4131
  glContext.useProgram(glPostShader);
4040
4132
  glContext.disable(gl_BLEND);