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
@@ -16,26 +16,31 @@
16
16
  'use strict';
17
17
 
18
18
  /** True if debug is enabled
19
+ * @type {Boolean}
19
20
  * @default
20
21
  * @memberof Debug */
21
22
  const debug = 1;
22
23
 
23
24
  /** True if asserts are enaled
25
+ * @type {Boolean}
24
26
  * @default
25
27
  * @memberof Debug */
26
28
  const enableAsserts = 1;
27
29
 
28
30
  /** Size to render debug points by default
31
+ * @type {Number}
29
32
  * @default
30
33
  * @memberof Debug */
31
34
  const debugPointSize = .5;
32
35
 
33
36
  /** True if watermark with FPS should be down, false in release builds
37
+ * @type {Boolean}
34
38
  * @default
35
39
  * @memberof Debug */
36
40
  let showWatermark = 1;
37
41
 
38
42
  /** True if god mode is enabled, handle this however you want
43
+ * @type {Boolean}
39
44
  * @default
40
45
  * @memberof Debug */
41
46
  let godMode = 0;
@@ -55,13 +60,13 @@ const ASSERT = enableAsserts ? (...assert)=> console.assert(...assert) : ()=>{};
55
60
 
56
61
  /** Draw a debug rectangle in world space
57
62
  * @param {Vector2} pos
58
- * @param {Vector2} [size=new Vector2()]
63
+ * @param {Vector2} [size=Vector2()]
59
64
  * @param {String} [color='#fff']
60
65
  * @param {Number} [time=0]
61
66
  * @param {Number} [angle=0]
62
- * @param {Boolean} [fill=0]
67
+ * @param {Boolean} [fill=false]
63
68
  * @memberof Debug */
64
- const debugRect = (pos, size=vec2(), color='#fff', time=0, angle=0, fill=0)=>
69
+ const debugRect = (pos, size=vec2(), color='#fff', time=0, angle=0, fill=false)=>
65
70
  {
66
71
  ASSERT(typeof color == 'string'); // pass in regular html strings as colors
67
72
  debugPrimitives.push({pos, size:vec2(size), color, time:new Timer(time), angle, fill});
@@ -72,9 +77,9 @@ const debugRect = (pos, size=vec2(), color='#fff', time=0, angle=0, fill=0)=>
72
77
  * @param {Number} [radius=0]
73
78
  * @param {String} [color='#fff']
74
79
  * @param {Number} [time=0]
75
- * @param {Boolean} [fill=0]
80
+ * @param {Boolean} [fill=false]
76
81
  * @memberof Debug */
77
- const debugCircle = (pos, radius=0, color='#fff', time=0, fill=0)=>
82
+ const debugCircle = (pos, radius=0, color='#fff', time=0, fill=false)=>
78
83
  {
79
84
  ASSERT(typeof color == 'string'); // pass in regular html strings as colors
80
85
  debugPrimitives.push({pos, size:radius, color, time:new Timer(time), angle:0, fill});
@@ -398,7 +403,8 @@ const debugRender = ()=>
398
403
  'use strict';
399
404
 
400
405
  /** A shortcut to get Math.PI
401
- * @const
406
+ * @type {Number}
407
+ * @default Math.PI
402
408
  * @memberof Utilities */
403
409
  const PI = Math.PI;
404
410
 
@@ -532,8 +538,8 @@ const randInCircle = (radius=1, minRadius=0)=> radius > 0 ? randVector(radius *
532
538
  const randVector = (length=1)=> new Vector2().setAngle(rand(2*PI), length);
533
539
 
534
540
  /** Returns a random color between the two passed in colors, combine components if linear
535
- * @param {Color} [colorA=new Color(1,1,1,1)]
536
- * @param {Color} [colorB=new Color(0,0,0,1)]
541
+ * @param {Color} [colorA=Color()]
542
+ * @param {Color} [colorB=Color(0,0,0,1)]
537
543
  * @param {Boolean} [linear]
538
544
  * @return {Color}
539
545
  * @memberof Random */
@@ -541,6 +547,8 @@ const randColor = (cA = new Color, cB = new Color(0,0,0,1), linear)=>
541
547
  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));
542
548
 
543
549
  /** Seed used by the randSeeded function
550
+ * @type {Number}
551
+ * @default
544
552
  * @memberof Random */
545
553
  let randSeed = 1;
546
554
 
@@ -679,7 +687,8 @@ class Vector2
679
687
 
680
688
  /** Sets this vector with angle and length passed in
681
689
  * @param {Number} [angle=0]
682
- * @param {Number} [length=1] */
690
+ * @param {Number} [length=1]
691
+ * @return {Vector2} */
683
692
  setAngle(a=0, length=1) { this.x = length*Math.sin(a); this.y = length*Math.cos(a); return this; }
684
693
 
685
694
  /** Returns copy of this vector rotated by the angle passed in
@@ -748,9 +757,11 @@ const colorHSLA = (h, s, l, a)=> new Color().setHSLA(h, s, l, a);
748
757
  /**
749
758
  * Color object (red, green, blue, alpha) with some helpful functions
750
759
  * @example
751
- * let a = new Color; // white
752
- * let b = new Color(1, 0, 0); // red
753
- * let c = new Color(0, 0, 0, 0); // transparent black
760
+ * let a = new Color; // white
761
+ * let b = new Color(1, 0, 0); // red
762
+ * let c = new Color(0, 0, 0, 0); // transparent black
763
+ * let d = colorRGBA(0, 0, 1); // blue using rgb color
764
+ * let e = colorHSLA(.3, 1, .5); // green using hsl color
754
765
  */
755
766
  class Color
756
767
  {
@@ -974,11 +985,12 @@ class Timer
974
985
 
975
986
  /** Position of camera in world space
976
987
  * @type {Vector2}
977
- * @default
988
+ * @default Vector2()
978
989
  * @memberof Settings */
979
990
  let cameraPos = vec2();
980
991
 
981
992
  /** Scale of camera in world space
993
+ * @type {Number}
982
994
  * @default
983
995
  * @memberof Settings */
984
996
  let cameraScale = 32;
@@ -987,24 +999,26 @@ let cameraScale = 32;
987
999
  // Display settings
988
1000
 
989
1001
  /** The max size of the canvas, centered if window is larger
990
- * @type {Vector2}
991
- * @default
1002
+ * @type {Vector2}
1003
+ * @default Vector2(1920,1200)
992
1004
  * @memberof Settings */
993
1005
  let canvasMaxSize = vec2(1920, 1200);
994
1006
 
995
1007
  /** Fixed size of the canvas, if enabled canvas size never changes
996
1008
  * - you may also need to set mainCanvasSize if using screen space coords in startup
997
- * @type {Vector2}
998
- * @default
1009
+ * @type {Vector2}
1010
+ * @default Vector2()
999
1011
  * @memberof Settings */
1000
1012
  let canvasFixedSize = vec2();
1001
1013
 
1002
1014
  /** Disables anti aliasing for pixel art if true
1015
+ * @type {Boolean}
1003
1016
  * @default
1004
1017
  * @memberof Settings */
1005
1018
  let cavasPixelated = 1;
1006
1019
 
1007
1020
  /** Default font used for text rendering
1021
+ * @type {String}
1008
1022
  * @default
1009
1023
  * @memberof Settings */
1010
1024
  let fontDefault = 'arial';
@@ -1013,11 +1027,13 @@ let fontDefault = 'arial';
1013
1027
  // WebGL settings
1014
1028
 
1015
1029
  /** Enable webgl rendering, webgl can be disabled and removed from build (with some features disabled)
1030
+ * @type {Boolean}
1016
1031
  * @default
1017
1032
  * @memberof Settings */
1018
1033
  let glEnable = 1;
1019
1034
 
1020
1035
  /** Fixes slow rendering in some browsers by not compositing the WebGL canvas
1036
+ * @type {Boolean}
1021
1037
  * @default
1022
1038
  * @memberof Settings */
1023
1039
  let glOverlay = 1;
@@ -1026,12 +1042,13 @@ let glOverlay = 1;
1026
1042
  // Tile sheet settings
1027
1043
 
1028
1044
  /** Default size of tiles in pixels
1029
- * @type {Vector2}
1030
- * @default
1045
+ * @type {Vector2}
1046
+ * @default Vector2(16,16)
1031
1047
  * @memberof Settings */
1032
1048
  let tileSizeDefault = vec2(16);
1033
1049
 
1034
1050
  /** Prevent tile bleeding from neighbors in pixels
1051
+ * @type {Number}
1035
1052
  * @default
1036
1053
  * @memberof Settings */
1037
1054
  let tileFixBleedScale = .3;
@@ -1039,53 +1056,56 @@ let tileFixBleedScale = .3;
1039
1056
  ///////////////////////////////////////////////////////////////////////////////
1040
1057
  // Object settings
1041
1058
 
1042
- /** Default size of objects
1043
- * @type {Vector2}
1044
- * @default
1045
- * @memberof Settings */
1046
- let objectDefaultSize = vec2(1);
1047
-
1048
1059
  /** Enable physics solver for collisions between objects
1060
+ * @type {Boolean}
1049
1061
  * @default
1050
1062
  * @memberof Settings */
1051
1063
  let enablePhysicsSolver = 1;
1052
1064
 
1053
1065
  /** Default object mass for collison calcuations (how heavy objects are)
1066
+ * @type {Number}
1054
1067
  * @default
1055
1068
  * @memberof Settings */
1056
1069
  let objectDefaultMass = 1;
1057
1070
 
1058
1071
  /** How much to slow velocity by each frame (0-1)
1072
+ * @type {Number}
1059
1073
  * @default
1060
1074
  * @memberof Settings */
1061
- let objectDefaultDamping = .99;
1075
+ let objectDefaultDamping = 1;
1062
1076
 
1063
1077
  /** How much to slow angular velocity each frame (0-1)
1078
+ * @type {Number}
1064
1079
  * @default
1065
1080
  * @memberof Settings */
1066
- let objectDefaultAngleDamping = .99;
1081
+ let objectDefaultAngleDamping = 1;
1067
1082
 
1068
1083
  /** How much to bounce when a collision occurs (0-1)
1069
- * @default
1084
+ * @type {Number}
1085
+ * @default 0
1070
1086
  * @memberof Settings */
1071
1087
  let objectDefaultElasticity = 0;
1072
1088
 
1073
1089
  /** How much to slow when touching (0-1)
1090
+ * @type {Number}
1074
1091
  * @default
1075
1092
  * @memberof Settings */
1076
1093
  let objectDefaultFriction = .8;
1077
1094
 
1078
1095
  /** Clamp max speed to avoid fast objects missing collisions
1096
+ * @type {Number}
1079
1097
  * @default
1080
1098
  * @memberof Settings */
1081
1099
  let objectMaxSpeed = 1;
1082
1100
 
1083
1101
  /** How much gravity to apply to objects along the Y axis, negative is down
1084
- * @default
1102
+ * @type {Number}
1103
+ * @default 0
1085
1104
  * @memberof Settings */
1086
1105
  let gravity = 0;
1087
1106
 
1088
1107
  /** Scales emit rate of particles, useful for low graphics mode (0 disables particle emitters)
1108
+ * @type {Number}
1089
1109
  * @default
1090
1110
  * @memberof Settings */
1091
1111
  let particleEmitRateScale = 1;
@@ -1094,16 +1114,19 @@ let particleEmitRateScale = 1;
1094
1114
  // Input settings
1095
1115
 
1096
1116
  /** Should gamepads be allowed
1117
+ * @type {Boolean}
1097
1118
  * @default
1098
1119
  * @memberof Settings */
1099
1120
  let gamepadsEnable = 1;
1100
1121
 
1101
1122
  /** If true, the dpad input is also routed to the left analog stick (for better accessability)
1123
+ * @type {Boolean}
1102
1124
  * @default
1103
1125
  * @memberof Settings */
1104
1126
  let gamepadDirectionEmulateStick = 1;
1105
1127
 
1106
1128
  /** If true the WASD keys are also routed to the direction keys (for better accessability)
1129
+ * @type {Boolean}
1107
1130
  * @default
1108
1131
  * @memberof Settings */
1109
1132
  let inputWASDEmulateDirection = 1;
@@ -1111,26 +1134,31 @@ let inputWASDEmulateDirection = 1;
1111
1134
  /** True if touch gamepad should appear on mobile devices
1112
1135
  * <br> - Supports left analog stick, 4 face buttons and start button (button 9)
1113
1136
  * <br> - Must be set by end of gameInit to be activated
1114
- * @default
1137
+ * @type {Boolean}
1138
+ * @default 0
1115
1139
  * @memberof Settings */
1116
1140
  let touchGamepadEnable = 0;
1117
1141
 
1118
1142
  /** True if touch gamepad should be analog stick or false to use if 8 way dpad
1143
+ * @type {Boolean}
1119
1144
  * @default
1120
1145
  * @memberof Settings */
1121
1146
  let touchGamepadAnalog = 1;
1122
1147
 
1123
1148
  /** Size of virutal gamepad for touch devices in pixels
1149
+ * @type {Number}
1124
1150
  * @default
1125
1151
  * @memberof Settings */
1126
1152
  let touchGamepadSize = 99;
1127
1153
 
1128
1154
  /** Transparency of touch gamepad overlay
1155
+ * @type {Number}
1129
1156
  * @default
1130
1157
  * @memberof Settings */
1131
1158
  let touchGamepadAlpha = .3;
1132
1159
 
1133
1160
  /** Allow vibration hardware if it exists
1161
+ * @type {Boolean}
1134
1162
  * @default
1135
1163
  * @memberof Settings */
1136
1164
  let vibrateEnable = 1;
@@ -1139,21 +1167,25 @@ let vibrateEnable = 1;
1139
1167
  // Audio settings
1140
1168
 
1141
1169
  /** All audio code can be disabled and removed from build
1170
+ * @type {Boolean}
1142
1171
  * @default
1143
1172
  * @memberof Settings */
1144
1173
  let soundEnable = 1;
1145
1174
 
1146
1175
  /** Volume scale to apply to all sound, music and speech
1176
+ * @type {Number}
1147
1177
  * @default
1148
1178
  * @memberof Settings */
1149
1179
  let soundVolume = .5;
1150
1180
 
1151
1181
  /** Default range where sound no longer plays
1182
+ * @type {Number}
1152
1183
  * @default
1153
1184
  * @memberof Settings */
1154
1185
  let soundDefaultRange = 40;
1155
1186
 
1156
1187
  /** Default range percent to start tapering off sound (0-1)
1188
+ * @type {Number}
1157
1189
  * @default
1158
1190
  * @memberof Settings */
1159
1191
  let soundDefaultTaper = .7;
@@ -1162,27 +1194,32 @@ let soundDefaultTaper = .7;
1162
1194
  // Medals settings
1163
1195
 
1164
1196
  /** How long to show medals for in seconds
1197
+ * @type {Number}
1165
1198
  * @default
1166
1199
  * @memberof Settings */
1167
1200
  let medalDisplayTime = 5;
1168
1201
 
1169
1202
  /** How quickly to slide on/off medals in seconds
1203
+ * @type {Number}
1170
1204
  * @default
1171
1205
  * @memberof Settings */
1172
1206
  let medalDisplaySlideTime = .5;
1173
1207
 
1174
1208
  /** Size of medal display
1175
- * @default
1209
+ * @type {Vector2}
1210
+ * @default Vector2(640,80)
1176
1211
  * @memberof Settings */
1177
1212
  let medalDisplaySize = vec2(640, 80);
1178
1213
 
1179
1214
  /** Size of icon in medal display
1215
+ * @type {Number}
1180
1216
  * @default
1181
1217
  * @memberof Settings */
1182
1218
  let medalDisplayIconSize = 50;
1183
1219
 
1184
1220
  /** Set to stop medals from being unlockable (like if cheats are enabled)
1185
- * @default
1221
+ * @type {Boolean}
1222
+ * @default 0
1186
1223
  * @memberof Settings */
1187
1224
  let medalsPreventUnlock;
1188
1225
  /*
@@ -1219,15 +1256,15 @@ let medalsPreventUnlock;
1219
1256
  class EngineObject
1220
1257
  {
1221
1258
  /** Create an engine object and adds it to the list of objects
1222
- * @param {Vector2} [position=new Vector2()] - World space position of the object
1223
- * @param {Vector2} [size=objectDefaultSize] - World space size of the object
1259
+ * @param {Vector2} [position=Vector2()] - World space position of the object
1260
+ * @param {Vector2} [size=Vector2(1,1)] - World space size of the object
1224
1261
  * @param {Number} [tileIndex=-1] - Tile to use to render object (-1 is untextured)
1225
1262
  * @param {Vector2} [tileSize=tileSizeDefault] - Size of tile in source pixels
1226
1263
  * @param {Number} [angle=0] - Angle the object is rotated by
1227
- * @param {Color} [color] - Color to apply to tile when rendered
1264
+ * @param {Color} [color=Color()] - Color to apply to tile when rendered
1228
1265
  * @param {Number} [renderOrder=0] - Objects sorted by renderOrder before being rendered
1229
1266
  */
1230
- constructor(pos=vec2(), size=objectDefaultSize, tileIndex=-1, tileSize=tileSizeDefault, angle=0, color, renderOrder=0)
1267
+ constructor(pos=vec2(), size=vec2(1), tileIndex=-1, tileSize=tileSizeDefault, angle=0, color, renderOrder=0)
1231
1268
  {
1232
1269
  // set passed in params
1233
1270
  ASSERT(isVector2(pos) && isVector2(size)); // ensure pos and size are vec2s
@@ -1264,7 +1301,7 @@ class EngineObject
1264
1301
  this.gravityScale = 1;
1265
1302
  /** @property {Number} [renderOrder=0] - Objects are sorted by render order */
1266
1303
  this.renderOrder = renderOrder;
1267
- /** @property {Vector2} [velocity=new Vector2()] - Velocity of the object */
1304
+ /** @property {Vector2} [velocity=Vector2()] - Velocity of the object */
1268
1305
  this.velocity = new Vector2();
1269
1306
  /** @property {Number} [angleVelocity=0] - Angular velocity of the object */
1270
1307
  this.angleVelocity = 0;
@@ -1507,7 +1544,7 @@ class EngineObject
1507
1544
 
1508
1545
  /** Attaches a child to this with a given local transform
1509
1546
  * @param {EngineObject} child
1510
- * @param {Vector2} [localPos=new Vector2]
1547
+ * @param {Vector2} [localPos=Vector2()]
1511
1548
  * @param {Number} [localAngle=0] */
1512
1549
  addChild(child, localPos=vec2(), localAngle=0)
1513
1550
  {
@@ -1528,9 +1565,9 @@ class EngineObject
1528
1565
  }
1529
1566
 
1530
1567
  /** Set how this object collides
1531
- * @param {boolean} [collideSolidObjects=1] - Does it collide with solid objects
1532
- * @param {boolean} [isSolid=1] - Does it collide with and block other objects (expensive in large numbers)
1533
- * @param {boolean} [collideTiles=1] - Does it collide with the tile collision */
1568
+ * @param {Boolean} [collideSolidObjects=1] - Does it collide with solid objects
1569
+ * @param {Boolean} [isSolid=1] - Does it collide with and block other objects (expensive in large numbers)
1570
+ * @param {Boolean} [collideTiles=1] - Does it collide with the tile collision */
1534
1571
  setCollision(collideSolidObjects=1, isSolid=1, collideTiles=1)
1535
1572
  {
1536
1573
  ASSERT(collideSolidObjects || !isSolid); // solid objects must be set to collide
@@ -1540,6 +1577,8 @@ class EngineObject
1540
1577
  this.collideTiles = collideTiles;
1541
1578
  }
1542
1579
 
1580
+ /** Returns string containg info about this object for debugging
1581
+ * @return {String} */
1543
1582
  toString()
1544
1583
  {
1545
1584
  if (debug)
@@ -1609,7 +1648,7 @@ let overlayContext;
1609
1648
  let mainCanvasSize = vec2();
1610
1649
 
1611
1650
  /** Tile sheet for batch rendering system
1612
- * @type {Image}
1651
+ * @type {CanvasImageSource}
1613
1652
  * @memberof Draw */
1614
1653
  const tileImage = new Image;
1615
1654
 
@@ -1639,15 +1678,15 @@ const worldToScreen = (worldPos)=>
1639
1678
  }
1640
1679
 
1641
1680
  /** Draw textured tile centered in world space, with color applied if using WebGL
1642
- * @param {Vector2} pos - Center of the tile in world space
1643
- * @param {Vector2} [size=new Vector2(1,1)] - Size of the tile in world space
1644
- * @param {Number} [tileIndex=-1] - Tile index to use, negative is untextured
1645
- * @param {Vector2} [tileSize=tileSizeDefault] - Tile size in source pixels
1646
- * @param {Color} [color=new Color(1,1,1)] - Color to modulate with
1647
- * @param {Number} [angle=0] - Angle to rotate by
1648
- * @param {Boolean} [mirror=0] - If true image is flipped along the Y axis
1649
- * @param {Color} [additiveColor=new Color(0,0,0,0)] - Additive color to be applied
1650
- * @param {Boolean} [useWebGL=glEnable] - Use accelerated WebGL rendering
1681
+ * @param {Vector2} pos - Center of the tile in world space
1682
+ * @param {Vector2} [size=Vector2(1,1)] - Size of the tile in world space
1683
+ * @param {Number} [tileIndex=-1] - Tile index to use, negative is untextured
1684
+ * @param {Vector2} [tileSize=tileSizeDefault] - Tile size in source pixels
1685
+ * @param {Color} [color=Color()] - Color to modulate with
1686
+ * @param {Number} [angle=0] - Angle to rotate by
1687
+ * @param {Boolean} [mirror=0] - If true image is flipped along the Y axis
1688
+ * @param {Color} [additiveColor=Color(0,0,0,0)] - Additive color to be applied
1689
+ * @param {Boolean} [useWebGL=glEnable] - Use accelerated WebGL rendering
1651
1690
  * @memberof Draw */
1652
1691
  function drawTile(pos, size=vec2(1), tileIndex=-1, tileSize=tileSizeDefault, color=new Color, angle=0, mirror,
1653
1692
  additiveColor=new Color(0,0,0,0), useWebGL=glEnable)
@@ -1702,8 +1741,8 @@ function drawTile(pos, size=vec2(1), tileIndex=-1, tileSize=tileSizeDefault, col
1702
1741
 
1703
1742
  /** Draw colored rect centered on pos
1704
1743
  * @param {Vector2} pos
1705
- * @param {Vector2} [size=new Vector2(1,1)]
1706
- * @param {Color} [color=new Color(1,1,1)]
1744
+ * @param {Vector2} [size=Vector2(1,1)]
1745
+ * @param {Color} [color=Color()]
1707
1746
  * @param {Number} [angle=0]
1708
1747
  * @param {Boolean} [useWebGL=glEnable]
1709
1748
  * @memberof Draw */
@@ -1714,13 +1753,13 @@ function drawRect(pos, size, color, angle, useWebGL)
1714
1753
 
1715
1754
  /** Draw textured tile centered on pos in screen space
1716
1755
  * @param {Vector2} pos - Center of the tile
1717
- * @param {Vector2} [size=new Vector2(1,1)] - Size of the tile
1756
+ * @param {Vector2} [size=Vector2(1,1)] - Size of the tile
1718
1757
  * @param {Number} [tileIndex=-1] - Tile index to use, negative is untextured
1719
1758
  * @param {Vector2} [tileSize=tileSizeDefault] - Tile size in source pixels
1720
- * @param {Color} [color=new Color]
1759
+ * @param {Color} [color=Color()]
1721
1760
  * @param {Number} [angle=0]
1722
1761
  * @param {Boolean} [mirror=0]
1723
- * @param {Color} [additiveColor=new Color(0,0,0,0)]
1762
+ * @param {Color} [additiveColor=Color(0,0,0,0)]
1724
1763
  * @param {Boolean} [useWebGL=glEnable]
1725
1764
  * @memberof Draw */
1726
1765
  function drawTileScreenSpace(pos, size=vec2(1), tileIndex, tileSize, color, angle, mirror, additiveColor, useWebGL)
@@ -1730,8 +1769,8 @@ function drawTileScreenSpace(pos, size=vec2(1), tileIndex, tileSize, color, angl
1730
1769
 
1731
1770
  /** Draw colored rectangle in screen space
1732
1771
  * @param {Vector2} pos
1733
- * @param {Vector2} [size=new Vector2(1,1)]
1734
- * @param {Color} [color=new Color(1,1,1)]
1772
+ * @param {Vector2} [size=Vector2(1,1)]
1773
+ * @param {Color} [color=Color()]
1735
1774
  * @param {Number} [angle=0]
1736
1775
  * @param {Boolean} [useWebGL=glEnable]
1737
1776
  * @memberof Draw */
@@ -1744,7 +1783,7 @@ function drawRectScreenSpace(pos, size, color, angle, useWebGL)
1744
1783
  * @param {Vector2} posA
1745
1784
  * @param {Vector2} posB
1746
1785
  * @param {Number} [thickness=.1]
1747
- * @param {Color} [color=new Color(1,1,1)]
1786
+ * @param {Color} [color=Color()]
1748
1787
  * @param {Boolean} [useWebGL=glEnable]
1749
1788
  * @memberof Draw */
1750
1789
  function drawLine(posA, posB, thickness=.1, color, useWebGL)
@@ -1792,9 +1831,9 @@ function setBlendMode(additive, useWebGL=glEnable)
1792
1831
  * @param {String} text
1793
1832
  * @param {Vector2} pos
1794
1833
  * @param {Number} [size=1]
1795
- * @param {Color} [color=new Color(1,1,1)]
1834
+ * @param {Color} [color=Color()]
1796
1835
  * @param {Number} [lineWidth=0]
1797
- * @param {Color} [lineColor=new Color(0,0,0)]
1836
+ * @param {Color} [lineColor=Color(0,0,0)]
1798
1837
  * @param {String} [textAlign='center']
1799
1838
  * @memberof Draw */
1800
1839
  function drawTextScreen(text, pos, size=1, color=new Color, lineWidth=0, lineColor=new Color(0,0,0), textAlign='center', font=fontDefault, context=overlayContext)
@@ -1821,18 +1860,20 @@ function drawTextScreen(text, pos, size=1, color=new Color, lineWidth=0, lineCol
1821
1860
  * @param {String} text
1822
1861
  * @param {Vector2} pos
1823
1862
  * @param {Number} [size=1]
1824
- * @param {Color} [color=new Color(1,1,1)]
1863
+ * @param {Color} [color=Color()]
1825
1864
  * @param {Number} [lineWidth=0]
1826
- * @param {Color} [lineColor=new Color(0,0,0)]
1865
+ * @param {Color} [lineColor=Color(0,0,0)]
1827
1866
  * @param {String} [textAlign='center']
1828
1867
  * @memberof Draw */
1829
- function drawText(text, pos, size=1, color, lineWidth, lineColor, textAlign, font)
1868
+ function drawText(text, pos, size=1, color, lineWidth=0, lineColor, textAlign, font)
1830
1869
  {
1831
1870
  drawTextScreen(text, worldToScreen(pos), size*cameraScale, color, lineWidth*cameraScale, lineColor, textAlign, font, mainContext);
1832
1871
  }
1833
1872
 
1834
1873
  ///////////////////////////////////////////////////////////////////////////////
1835
1874
 
1875
+ let engineFontImage;
1876
+
1836
1877
  /**
1837
1878
  * Font Image Object - Draw text on a 2D canvas by using characters in an image
1838
1879
  * <br> - 96 characters (from space to tilde) are stored in an image
@@ -1845,10 +1886,6 @@ function drawText(text, pos, size=1, color, lineWidth, lineColor, textAlign, fon
1845
1886
  * // draw text
1846
1887
  * font.drawTextScreen("LittleJS\nHello World!", vec2(200, 50));
1847
1888
  */
1848
-
1849
- // default font image created by engine
1850
- let engineFontImage;
1851
-
1852
1889
  class FontImage
1853
1890
  {
1854
1891
  /** Create an image font
@@ -1979,18 +2016,21 @@ const keyWasReleased = (key, device=0)=> inputData[device] && inputData[device][
1979
2016
  const clearInput = ()=> inputData = [[]];
1980
2017
 
1981
2018
  /** Returns true if mouse button is down
2019
+ * @function
1982
2020
  * @param {Number} button
1983
2021
  * @return {Boolean}
1984
2022
  * @memberof Input */
1985
2023
  const mouseIsDown = keyIsDown;
1986
2024
 
1987
2025
  /** Returns true if mouse button was pressed
2026
+ * @function
1988
2027
  * @param {Number} button
1989
2028
  * @return {Boolean}
1990
2029
  * @memberof Input */
1991
2030
  const mouseWasPressed = keyWasPressed;
1992
2031
 
1993
2032
  /** Returns true if mouse button was released
2033
+ * @function
1994
2034
  * @param {Number} button
1995
2035
  * @return {Boolean}
1996
2036
  * @memberof Input */
@@ -2007,14 +2047,17 @@ let mousePos = vec2();
2007
2047
  let mousePosScreen = vec2();
2008
2048
 
2009
2049
  /** Mouse wheel delta this frame
2050
+ * @type {Number}
2010
2051
  * @memberof Input */
2011
2052
  let mouseWheel = 0;
2012
2053
 
2013
2054
  /** Returns true if user is using gamepad (has more recently pressed a gamepad button)
2055
+ * @type {Boolean}
2014
2056
  * @memberof Input */
2015
2057
  let isUsingGamepad = 0;
2016
2058
 
2017
2059
  /** Prevents input continuing to the default browser handling (false by default)
2060
+ * @type {Boolean}
2018
2061
  * @memberof Input */
2019
2062
  let preventDefaultInput = 0;
2020
2063
 
@@ -2190,7 +2233,6 @@ const vibrateStop = ()=> vibrate(0);
2190
2233
  // Touch input
2191
2234
 
2192
2235
  /** True if a touch device has been detected
2193
- * @const {boolean}
2194
2236
  * @memberof Input */
2195
2237
  const isTouchDevice = window.ontouchstart !== undefined;
2196
2238
 
@@ -2520,8 +2562,21 @@ class Music
2520
2562
  {
2521
2563
  if (!soundEnable) return;
2522
2564
 
2523
- return playSamples(this.cachedSamples, volume, 1, 0, loop);
2565
+ return this.source = playSamples(this.cachedSamples, volume, 1, 0, loop);
2566
+ }
2567
+
2568
+ /** Stop the music */
2569
+ stop()
2570
+ {
2571
+ if (this.source)
2572
+ this.source.stop();
2573
+ this.source = 0;
2524
2574
  }
2575
+
2576
+ /** Check if music is playing
2577
+ * @return {Boolean}
2578
+ */
2579
+ isPlaying() { return this.source; }
2525
2580
  }
2526
2581
 
2527
2582
  /** Play an mp3 or wav audio from a local file or url
@@ -2848,6 +2903,7 @@ function zzfxM(instruments, patterns, sequence, BPM = 125)
2848
2903
  'use strict';
2849
2904
 
2850
2905
  /** The tile collision layer array, use setTileCollisionData and getTileCollisionData to access
2906
+ * @type {Array}
2851
2907
  * @memberof TileCollision */
2852
2908
  let tileCollision = [];
2853
2909
 
@@ -2883,7 +2939,7 @@ const getTileCollisionData = (pos)=>
2883
2939
 
2884
2940
  /** Check if collision with another object should occur
2885
2941
  * @param {Vector2} pos
2886
- * @param {Vector2} [size=new Vector2(1,1)]
2942
+ * @param {Vector2} [size=Vector2(1,1)]
2887
2943
  * @param {EngineObject} [object]
2888
2944
  * @return {Boolean}
2889
2945
  * @memberof TileCollision */
@@ -2951,11 +3007,11 @@ function tileCollisionRaycast(posStart, posEnd, object)
2951
3007
  class TileLayerData
2952
3008
  {
2953
3009
  /** Create a tile layer data object, one for each tile in a TileLayer
2954
- * @param {Number} [tile] - The tile to use, untextured if undefined
2955
- * @param {Number} [direction=0] - Integer direction of tile, in 90 degree increments
2956
- * @param {Boolean} [mirror=0] - If the tile should be mirrored along the x axis
2957
- * @param {Color} [color=new Color(1,1,1)] - Color of the tile */
2958
- constructor(tile, direction=0, mirror=0, color=new Color)
3010
+ * @param {Number} [tile] - The tile to use, untextured if undefined
3011
+ * @param {Number} [direction=0] - Integer direction of tile, in 90 degree increments
3012
+ * @param {Boolean} [mirror=0] - If the tile should be mirrored along the x axis
3013
+ * @param {Color} [color=Color()] - Color of the tile */
3014
+ constructor(tile, direction=0, mirror=0, color=new Color())
2959
3015
  {
2960
3016
  /** @property {Number} - The tile to use, untextured if undefined */
2961
3017
  this.tile = tile;
@@ -2986,10 +3042,10 @@ class TileLayerData
2986
3042
  class TileLayer extends EngineObject
2987
3043
  {
2988
3044
  /** Create a tile layer object
2989
- * @param {Vector2} [position=new Vector2()] - World space position
3045
+ * @param {Vector2} [position=Vector2()] - World space position
2990
3046
  * @param {Vector2} [size=tileCollisionSize] - World space size
2991
3047
  * @param {Vector2} [tileSize=tileSizeDefault] - Size of tiles in source pixels
2992
- * @param {Vector2} [scale=new Vector2(1,1)] - How much to scale this layer when rendered
3048
+ * @param {Vector2} [scale=Vector2(1,1)] - How much to scale this layer when rendered
2993
3049
  * @param {Number} [renderOrder=0] - Objects sorted by renderOrder before being rendered
2994
3050
  */
2995
3051
  constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1), renderOrder=0)
@@ -3141,10 +3197,10 @@ constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1)
3141
3197
 
3142
3198
  /** Draw a tile directly onto the layer canvas
3143
3199
  * @param {Vector2} pos
3144
- * @param {Vector2} [size=new Vector2(1,1)]
3200
+ * @param {Vector2} [size=Vector2(1,1)]
3145
3201
  * @param {Number} [tileIndex=-1]
3146
3202
  * @param {Vector2} [tileSize=tileSizeDefault]
3147
- * @param {Color} [color=new Color(1,1,1)]
3203
+ * @param {Color} [color=Color()]
3148
3204
  * @param {Number} [angle=0]
3149
3205
  * @param {Boolean} [mirror=0] */
3150
3206
  drawTile(pos, size=vec2(1), tileIndex=-1, tileSize=tileSizeDefault, color=new Color, angle, mirror)
@@ -3170,8 +3226,8 @@ constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1)
3170
3226
 
3171
3227
  /** Draw a rectangle directly onto the layer canvas
3172
3228
  * @param {Vector2} pos
3173
- * @param {Vector2} [size=new Vector2(1,1)]
3174
- * @param {Color} [color=new Color(1,1,1)]
3229
+ * @param {Vector2} [size=Vector2(1,1)]
3230
+ * @param {Color} [color=Color()]
3175
3231
  * @param {Number} [angle=0] */
3176
3232
  drawRect(pos, size, color, angle)
3177
3233
  { this.drawTile(pos, size, -1, 0, color, angle); }
@@ -3212,11 +3268,11 @@ class ParticleEmitter extends EngineObject
3212
3268
  * @param {Number} [emitRate=100] - How many particles per second to spawn, does not emit if 0
3213
3269
  * @param {Number} [emitConeAngle=PI] - Local angle to apply velocity to particles from emitter
3214
3270
  * @param {Number} [tileIndex=-1] - Index into tile sheet, if <0 no texture is applied
3215
- * @param {Number} [tileSize=tileSizeDefault] - Tile size for particles
3216
- * @param {Color} [colorStartA=new Color(1,1,1)] - Color at start of life 1, randomized between start colors
3217
- * @param {Color} [colorStartB=new Color(1,1,1)] - Color at start of life 2, randomized between start colors
3218
- * @param {Color} [colorEndA=new Color(1,1,1,0)] - Color at end of life 1, randomized between end colors
3219
- * @param {Color} [colorEndB=new Color(1,1,1,0)] - Color at end of life 2, randomized between end colors
3271
+ * @param {Vector2} [tileSize=tileSizeDefault] - Tile size for particles
3272
+ * @param {Color} [colorStartA=Color()] - Color at start of life 1, randomized between start colors
3273
+ * @param {Color} [colorStartB=Color()] - Color at start of life 2, randomized between start colors
3274
+ * @param {Color} [colorEndA=Color(1,1,1,0)] - Color at end of life 1, randomized between end colors
3275
+ * @param {Color} [colorEndB=Color(1,1,1,0)] - Color at end of life 2, randomized between end colors
3220
3276
  * @param {Number} [particleTime=.5] - How long particles live
3221
3277
  * @param {Number} [sizeStart=.1] - How big are particles at start
3222
3278
  * @param {Number} [sizeEnd=1] - How big are particles at end
@@ -3496,6 +3552,7 @@ class Particle extends EngineObject
3496
3552
  'use strict';
3497
3553
 
3498
3554
  /** List of all medals
3555
+ * @type {Array}
3499
3556
  * @memberof Medals */
3500
3557
  const medals = [];
3501
3558
 
@@ -4047,12 +4104,13 @@ function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba, rgbaAdd
4047
4104
  ///////////////////////////////////////////////////////////////////////////////
4048
4105
  // post processing - can be enabled to pass other canvases through a final shader
4049
4106
 
4050
- let glPostShader, glPostArrayBuffer, glPostTexture;
4107
+ let glPostShader, glPostArrayBuffer, glPostTexture, glPostIncludeOverlay;
4051
4108
 
4052
4109
  /** Set up a post processing shader
4053
4110
  * @param {String} shaderCode
4111
+ * @param {Boolean} includeOverlay
4054
4112
  * @memberof WebGL */
4055
- function glInitPostProcess(shaderCode)
4113
+ function glInitPostProcess(shaderCode, includeOverlay)
4056
4114
  {
4057
4115
  ASSERT(!glPostShader); // can only have 1 post effects shader
4058
4116
 
@@ -4081,6 +4139,7 @@ function glInitPostProcess(shaderCode)
4081
4139
  // create buffer and texture
4082
4140
  glPostArrayBuffer = glContext.createBuffer();
4083
4141
  glPostTexture = glCreateTexture();
4142
+ glPostIncludeOverlay = includeOverlay;
4084
4143
 
4085
4144
  // hide the original 2d canvas
4086
4145
  mainCanvas.style.visibility = 'hidden';
@@ -4101,6 +4160,13 @@ function glRenderPostProcess()
4101
4160
  else // set viewport
4102
4161
  glContext.viewport(0, 0, glCanvas.width = mainCanvas.width, glCanvas.height = mainCanvas.height);
4103
4162
 
4163
+ if (glPostIncludeOverlay)
4164
+ {
4165
+ // copy overlay canvas so it will be included in post processing
4166
+ mainContext.drawImage(overlayCanvas, 0, 0);
4167
+ overlayCanvas.width |= 0;
4168
+ }
4169
+
4104
4170
  // setup shader program to draw one triangle
4105
4171
  glContext.useProgram(glPostShader);
4106
4172
  glContext.disable(gl_BLEND);
@@ -4184,43 +4250,71 @@ gl_VERTEX_BUFFER_SIZE = gl_MAX_BATCH * gl_VERTICES_PER_QUAD * gl_VERTEX_BYTE_STR
4184
4250
  - Call engineInit() to start it up!
4185
4251
  */
4186
4252
 
4253
+ /**
4254
+ * LittleJS Engine Globals
4255
+ * @namespace Engine
4256
+ */
4257
+
4187
4258
  'use strict';
4188
4259
 
4189
- /** Name of engine */
4260
+ /** Name of engine
4261
+ * @type {String}
4262
+ * @default
4263
+ * @memberof Engine */
4190
4264
  const engineName = 'LittleJS';
4191
4265
 
4192
- /** Version of engine */
4193
- const engineVersion = '1.4.9';
4266
+ /** Version of engine
4267
+ * @type {String}
4268
+ * @default
4269
+ * @memberof Engine */
4270
+ const engineVersion = '1.5.1';
4194
4271
 
4195
4272
  /** Frames per second to update objects
4196
- * @default */
4273
+ * @type {Number}
4274
+ * @default
4275
+ * @memberof Engine */
4197
4276
  const frameRate = 60;
4198
4277
 
4199
4278
  /** How many seconds each frame lasts, engine uses a fixed time step
4200
- * @default 1/60 */
4279
+ * @type {Number}
4280
+ * @default 1/60
4281
+ * @memberof Engine */
4201
4282
  const timeDelta = 1/frameRate;
4202
4283
 
4203
- /** Array containing all engine objects */
4284
+ /** Array containing all engine objects
4285
+ * @type {Array}
4286
+ * @memberof Engine */
4204
4287
  let engineObjects = [];
4205
4288
 
4206
- /** Array containing only objects that are set to collide with other objects this frame (for optimization) */
4289
+ /** Array containing only objects that are set to collide with other objects this frame (for optimization)
4290
+ * @type {Array}
4291
+ * @memberof Engine */
4207
4292
  let engineObjectsCollide = [];
4208
4293
 
4209
- /** Current update frame, used to calculate time */
4294
+ /** Current update frame, used to calculate time
4295
+ * @type {Number}
4296
+ * @memberof Engine */
4210
4297
  let frame = 0;
4211
4298
 
4212
- /** Current engine time since start in seconds, derived from frame */
4299
+ /** Current engine time since start in seconds, derived from frame
4300
+ * @type {Number}
4301
+ * @memberof Engine */
4213
4302
  let time = 0;
4214
4303
 
4215
- /** Actual clock time since start in seconds (not affected by pause or frame rate clamping) */
4304
+ /** Actual clock time since start in seconds (not affected by pause or frame rate clamping)
4305
+ * @type {Number}
4306
+ * @memberof Engine */
4216
4307
  let timeReal = 0;
4217
4308
 
4218
- /** Is the game paused? Causes time and objects to not be updated */
4309
+ /** Is the game paused? Causes time and objects to not be updated
4310
+ * @type {Boolean}
4311
+ * @default 0
4312
+ * @memberof Engine */
4219
4313
  let paused = 0;
4220
4314
 
4221
4315
  /** Set if game is paused
4222
4316
  * @param {Boolean} paused
4223
- */
4317
+ * @memberof Engine */
4224
4318
  function setPaused(_paused) { paused = _paused; }
4225
4319
 
4226
4320
  ///////////////////////////////////////////////////////////////////////////////
@@ -4232,7 +4326,7 @@ function setPaused(_paused) { paused = _paused; }
4232
4326
  * @param {Function} gameRender - Called before objects are rendered, draw any background effects that appear behind objects
4233
4327
  * @param {Function} gameRenderPost - Called after objects are rendered, draw effects or hud that appear above all objects
4234
4328
  * @param {String} [tileImageSource] - Tile image to use, everything starts when the image is finished loading
4235
- */
4329
+ * @memberof Engine */
4236
4330
  function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, tileImageSource)
4237
4331
  {
4238
4332
  // init engine when tiles load or fail to load
@@ -4396,7 +4490,8 @@ function enginePreRender()
4396
4490
  glEnable && glPreRender();
4397
4491
  }
4398
4492
 
4399
- /** Update each engine object, remove destroyed objects, and update time */
4493
+ /** Update each engine object, remove destroyed objects, and update time
4494
+ * @memberof Engine */
4400
4495
  function engineObjectsUpdate()
4401
4496
  {
4402
4497
  // get list of solid objects for physics optimzation
@@ -4422,7 +4517,8 @@ function engineObjectsUpdate()
4422
4517
  time = ++frame / frameRate;
4423
4518
  }
4424
4519
 
4425
- /** Destroy and remove all objects */
4520
+ /** Destroy and remove all objects
4521
+ * @memberof Engine */
4426
4522
  function engineObjectsDestroy()
4427
4523
  {
4428
4524
  for (const o of engineObjects)
@@ -4434,7 +4530,8 @@ function engineObjectsDestroy()
4434
4530
  * @param {Vector2} [pos] - Center of test area
4435
4531
  * @param {Number} [size] - Radius of circle if float, rectangle size if Vector2
4436
4532
  * @param {Function} [callbackFunction] - Calls this function on every object that passes the test
4437
- * @param {Array} [objects=engineObjects] - List of objects to check */
4533
+ * @param {Array} [objects=engineObjects] - List of objects to check
4534
+ * @memberof Engine */
4438
4535
  function engineObjectsCallback(pos, size, callbackFunction, objects=engineObjects)
4439
4536
  {
4440
4537
  if (!pos) // all objects