littlejsengine 1.15.2 → 1.15.8

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 (42) hide show
  1. package/dist/littlejs.d.ts +190 -63
  2. package/dist/littlejs.esm.js +1267 -605
  3. package/dist/littlejs.esm.min.js +1 -1
  4. package/dist/littlejs.js +1261 -604
  5. package/dist/littlejs.min.js +1 -1
  6. package/dist/littlejs.release.js +1179 -552
  7. package/examples/electron/index.html +2 -2
  8. package/examples/index.html +4 -3
  9. package/examples/particles/index.html +22 -6
  10. package/examples/shorts/base.html +2 -1
  11. package/examples/shorts/box2dCar.js +1 -1
  12. package/examples/shorts/box2dPool.js +9 -10
  13. package/examples/shorts/empty.js +1 -1
  14. package/examples/shorts/input.js +30 -25
  15. package/examples/shorts/music.js +1 -0
  16. package/examples/shorts/musicPlayer.js +1 -0
  17. package/examples/shorts/sequencer.js +2 -0
  18. package/examples/shorts/sound.js +1 -0
  19. package/examples/shorts/tileLayer.js +2 -2
  20. package/examples/shorts/tiles.png +0 -0
  21. package/examples/shorts/timers.js +1 -0
  22. package/examples/shorts/uiSystem.js +26 -14
  23. package/examples/shorts/videoPlayer.js +2 -1
  24. package/examples/starter/index.html +3 -2
  25. package/examples/uiSystem/game.js +28 -15
  26. package/package.json +1 -1
  27. package/plugins/box2d.js +1 -1
  28. package/plugins/desktop.ini +2 -0
  29. package/plugins/pluginExport.js +2 -0
  30. package/plugins/uiSystem.js +503 -91
  31. package/src/engine.js +2 -169
  32. package/src/engineAudio.js +0 -1
  33. package/src/engineBuild.js +1 -0
  34. package/src/engineDebug.js +84 -54
  35. package/src/engineDraw.js +81 -40
  36. package/src/engineExport.js +4 -1
  37. package/src/engineInput.js +526 -381
  38. package/src/engineObject.js +27 -23
  39. package/src/engineSettings.js +11 -6
  40. package/src/engineSplash.js +173 -0
  41. package/src/engineTileLayer.js +3 -3
  42. package/src/engineUtilities.js +17 -1
package/src/engineDraw.js CHANGED
@@ -151,7 +151,7 @@ class TileInfo
151
151
  this.padding = padding;
152
152
  /** @property {TextureInfo} - The texture info for this tile */
153
153
  this.textureInfo = textureInfos[this.textureIndex];
154
- /** @property {float} - Shrinks tile by this many pixels to prevent neighbors bleeding */
154
+ /** @property {number} - Shrinks tile by this many pixels to prevent neighbors bleeding */
155
155
  this.bleedScale = bleedScale;
156
156
  }
157
157
 
@@ -250,15 +250,11 @@ function drawTile(pos, size=new Vector2(1), tileInfo, color=WHITE,
250
250
 
251
251
  const textureInfo = tileInfo && tileInfo.textureInfo;
252
252
  const bleedScale = tileInfo ? tileInfo.bleedScale : 0;
253
- if (useWebGL)
253
+ if (useWebGL && glEnable)
254
254
  {
255
255
  ASSERT(!!glContext, 'WebGL is not enabled!');
256
256
  if (screenSpace)
257
- {
258
- // convert to world space
259
- pos = screenToWorld(pos);
260
- size = size.scale(1/cameraScale);
261
- }
257
+ [pos, size, angle] = screenToWorldTransform(pos, size, angle);
262
258
  if (textureInfo)
263
259
  {
264
260
  // calculate uvs and render
@@ -346,7 +342,8 @@ function drawRectGradient(pos, size, colorTop=WHITE, colorBottom=BLACK, angle=0,
346
342
  ASSERT(isColor(colorTop) && isColor(colorBottom), 'color is invalid');
347
343
  ASSERT(isNumber(angle), 'angle must be a number');
348
344
  ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
349
- if (useWebGL)
345
+
346
+ if (useWebGL && glEnable)
350
347
  {
351
348
  ASSERT(!!glContext, 'WebGL is not enabled!');
352
349
  if (screenSpace)
@@ -354,6 +351,7 @@ function drawRectGradient(pos, size, colorTop=WHITE, colorBottom=BLACK, angle=0,
354
351
  // convert to world space
355
352
  pos = screenToWorld(pos);
356
353
  size = size.scale(1/cameraScale);
354
+ angle += cameraAngle;
357
355
  }
358
356
  // build 4 corner points for the rectangle
359
357
  const points = [], colors = [];
@@ -409,17 +407,14 @@ function drawLineList(points, width=.1, color, wrap=false, pos=vec2(), angle=0,
409
407
  ASSERT(isVector2(pos), 'pos must be a vec2');
410
408
  ASSERT(isNumber(angle), 'angle must be a number');
411
409
  ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
412
- if (useWebGL)
410
+
411
+ if (useWebGL && glEnable)
413
412
  {
414
413
  ASSERT(!!glContext, 'WebGL is not enabled!');
415
- let scale = 1;
414
+ let size = vec2(1);
416
415
  if (screenSpace)
417
- {
418
- // convert to world space
419
- pos = screenToWorld(pos);
420
- scale = 1/cameraScale;
421
- }
422
- glDrawOutlineTransform(points, color.rgbaInt(), width, pos.x, pos.y, scale, scale, angle, wrap);
416
+ [pos, size, angle] = screenToWorldTransform(pos, size, angle);
417
+ glDrawOutlineTransform(points, color.rgbaInt(), width, pos.x, pos.y, size.x, size.y, angle, wrap);
423
418
  }
424
419
  else
425
420
  {
@@ -515,19 +510,15 @@ function drawPoly(points, color=WHITE, lineWidth=0, lineColor=BLACK, pos=vec2(),
515
510
  ASSERT(isNumber(angle), 'angle must be a number');
516
511
  ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
517
512
 
518
- if (useWebGL)
513
+ if (useWebGL && glEnable)
519
514
  {
520
515
  ASSERT(!!glContext, 'WebGL is not enabled!');
521
- let scale = 1;
516
+ let size = vec2(1);
522
517
  if (screenSpace)
523
- {
524
- // convert to world space
525
- pos = screenToWorld(pos);
526
- scale = 1/cameraScale;
527
- }
528
- glDrawPointsTransform(points, color.rgbaInt(), pos.x, pos.y, scale, scale, angle);
518
+ [pos, size, angle] = screenToWorldTransform(pos, size, angle);
519
+ glDrawPointsTransform(points, color.rgbaInt(), pos.x, pos.y, size.x, size.y, angle);
529
520
  if (lineWidth > 0)
530
- glDrawOutlineTransform(points, lineColor.rgbaInt(), lineWidth, pos.x, pos.y, scale, scale, angle);
521
+ glDrawOutlineTransform(points, lineColor.rgbaInt(), lineWidth, pos.x, pos.y, size.x, size.y, angle);
531
522
  }
532
523
  else
533
524
  {
@@ -570,7 +561,7 @@ function drawEllipse(pos, size=vec2(1), color=WHITE, angle=0, lineWidth=0, lineC
570
561
  ASSERT(lineWidth >= 0 && lineWidth < size.x && lineWidth < size.y, 'invalid lineWidth');
571
562
  ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
572
563
 
573
- if (useWebGL)
564
+ if (useWebGL && glEnable)
574
565
  {
575
566
  // draw as a regular polygon
576
567
  const sides = glCircleSides;
@@ -633,14 +624,10 @@ function drawCanvas2D(pos, size, angle=0, mirror=false, drawFunction, screenSpac
633
624
  ASSERT(typeof drawFunction === 'function', 'drawFunction must be a function');
634
625
 
635
626
  if (!screenSpace)
636
- {
637
- // transform from world space to screen space
638
- pos = worldToScreen(pos);
639
- size = size.scale(cameraScale);
640
- }
627
+ [pos, size, angle] = worldToScreenTransform(pos, size, angle);
641
628
  context.save();
642
629
  context.translate(pos.x+.5, pos.y+.5);
643
- context.rotate(angle-cameraAngle);
630
+ context.rotate(angle);
644
631
  context.scale(mirror ? -size.x : size.x, -size.y);
645
632
  drawFunction(context);
646
633
  context.restore();
@@ -651,7 +638,7 @@ function drawCanvas2D(pos, size, angle=0, mirror=false, drawFunction, screenSpac
651
638
 
652
639
  /** Draw text on main canvas in world space
653
640
  * Automatically splits new lines into rows
654
- * @param {string} text
641
+ * @param {string|number} text
655
642
  * @param {Vector2} pos
656
643
  * @param {number} [size]
657
644
  * @param {Color} [color=(1,1,1,1)]
@@ -666,12 +653,19 @@ function drawCanvas2D(pos, size, angle=0, mirror=false, drawFunction, screenSpac
666
653
  * @memberof Draw */
667
654
  function drawText(text, pos, size=1, color, lineWidth=0, lineColor, textAlign, font, fontStyle, maxWidth, angle=0, context=drawContext)
668
655
  {
669
- drawTextScreen(text, worldToScreen(pos), size*cameraScale, color, lineWidth*cameraScale, lineColor, textAlign, font, fontStyle, maxWidth, angle, context);
656
+ // convert to screen space
657
+ pos = worldToScreen(pos);
658
+ size *= cameraScale;
659
+ lineWidth *= cameraScale;
660
+ angle -= cameraAngle;
661
+ angle *= -1;
662
+
663
+ drawTextScreen(text, pos, size, color, lineWidth, lineColor, textAlign, font, fontStyle, maxWidth, angle, context);
670
664
  }
671
665
 
672
666
  /** Draw text on overlay canvas in world space
673
667
  * Automatically splits new lines into rows
674
- * @param {string} text
668
+ * @param {string|number} text
675
669
  * @param {Vector2} pos
676
670
  * @param {number} [size]
677
671
  * @param {Color} [color=(1,1,1,1)]
@@ -690,7 +684,7 @@ function drawTextOverlay(text, pos, size=1, color, lineWidth=0, lineColor, textA
690
684
 
691
685
  /** Draw text on overlay canvas in screen space
692
686
  * Automatically splits new lines into rows
693
- * @param {string} text
687
+ * @param {string|number} text
694
688
  * @param {Vector2} pos
695
689
  * @param {number} [size]
696
690
  * @param {Color} [color=(1,1,1,1)]
@@ -825,11 +819,58 @@ function worldToScreenDelta(worldDelta)
825
819
  return new Vector2(x * cameraScale, y * -cameraScale);
826
820
  }
827
821
 
828
- /** Get the camera's visible area in world space
822
+ /** Convert screen space transform to world space
823
+ * @param {Vector2} screenPos
824
+ * @param {Vector2} screenSize
825
+ * @param {number} [screenAngle]
826
+ * @return {[Vector2, Vector2, number]} - [pos, size, angle]
827
+ * @memberof Draw */
828
+ function screenToWorldTransform(screenPos, screenSize, screenAngle=0)
829
+ {
830
+ return [
831
+ screenToWorld(screenPos),
832
+ screenSize.scale(1/cameraScale),
833
+ screenAngle + cameraAngle
834
+ ];
835
+ }
836
+
837
+ /** Convert world space transform to screen space
838
+ * @param {Vector2} worldPos
839
+ * @param {Vector2} worldSize
840
+ * @param {number} [worldAngle]
841
+ * @return {[Vector2, Vector2, number]} - [pos, size, angle]
842
+ * @memberof Draw */
843
+ function worldToScreenTransform(worldPos, worldSize, worldAngle=0)
844
+ {
845
+ return [
846
+ worldToScreen(worldPos),
847
+ worldSize.scale(cameraScale),
848
+ worldAngle - cameraAngle
849
+ ];
850
+ }
851
+
852
+ /** Get the size of the camera window in world space
829
853
  * @return {Vector2}
830
854
  * @memberof Draw */
831
855
  function getCameraSize() { return mainCanvasSize.scale(1/cameraScale); }
832
856
 
857
+ /** Check if a point or circle is on screen
858
+ * If size is a Vector2, uses the largest dimension as diameter
859
+ * This can be used to cull offscreen objects from render or update
860
+ * @param {Vector2} pos - world space position
861
+ * @param {Vector2|number} size - world space size or diameter
862
+ * @return {boolean}
863
+ * @memberof Draw */
864
+ function isOnScreen(pos, size=0)
865
+ {
866
+ pos = worldToScreen(pos);
867
+ if (size instanceof Vector2)
868
+ size = max(size.x, size.y); // use largest dimension
869
+ size *= cameraScale/2;
870
+ return pos.x + size > 0 && pos.x - size < mainCanvasSize.x &&
871
+ pos.y + size > 0 && pos.y - size < mainCanvasSize.y;
872
+ }
873
+
833
874
  /** Enable normal or additive blend mode
834
875
  * @param {boolean} [additive]
835
876
  * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
@@ -993,7 +1034,7 @@ class FontImage
993
1034
  }
994
1035
 
995
1036
  /** Draw text in world space using the image font
996
- * @param {string} text
1037
+ * @param {string|number} text
997
1038
  * @param {Vector2} pos
998
1039
  * @param {number} [scale=.25]
999
1040
  * @param {boolean} [center]
@@ -1005,7 +1046,7 @@ class FontImage
1005
1046
  }
1006
1047
 
1007
1048
  /** Draw text on overlay canvas in world space using the image font
1008
- * @param {string} text
1049
+ * @param {string|number} text
1009
1050
  * @param {Vector2} pos
1010
1051
  * @param {number} [scale]
1011
1052
  * @param {boolean} [center]
@@ -1014,7 +1055,7 @@ class FontImage
1014
1055
  { this.drawText(text, pos, scale, center, overlayContext); }
1015
1056
 
1016
1057
  /** Draw text on overlay canvas in screen space using the image font
1017
- * @param {string} text
1058
+ * @param {string|number} text
1018
1059
  * @param {Vector2} pos
1019
1060
  * @param {number} [scale]
1020
1061
  * @param {boolean} [center]
@@ -124,6 +124,7 @@ export
124
124
  setInputWASDEmulateDirection,
125
125
  setTouchGamepadEnable,
126
126
  setTouchGamepadCenterButton,
127
+ setTouchGamepadButtonCount,
127
128
  setTouchGamepadAnalog,
128
129
  setTouchGamepadSize,
129
130
  setTouchGamepadAlpha,
@@ -295,12 +296,14 @@ export
295
296
  mouseInWindow,
296
297
  isUsingGamepad,
297
298
  inputPreventDefault,
299
+ gamepadPrimary,
298
300
  setInputPreventDefault,
299
301
  gamepadIsDown,
300
302
  gamepadWasPressed,
301
303
  gamepadWasReleased,
302
304
  gamepadStick,
303
- gamepadsUpdate,
305
+ gamepadDpad,
306
+ gamepadConnected,
304
307
  vibrate,
305
308
  vibrateStop,
306
309
  isTouchDevice,