littlejsengine 1.13.1 → 1.13.4

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 (66) hide show
  1. package/README.md +15 -12
  2. package/dist/littlejs.d.ts +94 -74
  3. package/dist/littlejs.esm.js +422 -306
  4. package/dist/littlejs.esm.min.js +1 -1
  5. package/dist/littlejs.js +416 -306
  6. package/dist/littlejs.min.js +1 -1
  7. package/dist/littlejs.release.js +414 -304
  8. package/examples/box2d/game.js +1 -1
  9. package/examples/box2d/gameObjects.js +1 -1
  10. package/examples/box2d/scenes.js +1 -1
  11. package/examples/breakoutTutorial/README.md +44 -41
  12. package/examples/breakoutTutorial/game.js +2 -2
  13. package/examples/electron/build.bat +7 -0
  14. package/examples/electron/build.js +124 -0
  15. package/examples/electron/electron.js +35 -0
  16. package/examples/electron/game.js +140 -0
  17. package/examples/electron/index.html +13 -0
  18. package/examples/electron/package.json +12 -0
  19. package/examples/electron/tiles.png +0 -0
  20. package/examples/empty/game.js +1 -0
  21. package/examples/htmlMenu/game.js +1 -1
  22. package/examples/index.html +154 -93
  23. package/examples/module/game.js +5 -2
  24. package/examples/particles/index.html +12 -3
  25. package/examples/platformer/gameEffects.js +3 -3
  26. package/examples/shorts/base.html +1 -1
  27. package/examples/shorts/blending.js +9 -5
  28. package/examples/shorts/box2d.js +1 -1
  29. package/examples/shorts/box2dCar.js +1 -1
  30. package/examples/shorts/clock.js +1 -1
  31. package/examples/shorts/colors.js +2 -2
  32. package/examples/shorts/maze.js +1 -1
  33. package/examples/shorts/nineSlice.js +9 -9
  34. package/examples/shorts/piano.js +2 -2
  35. package/examples/shorts/raycasting.js +2 -2
  36. package/examples/shorts/shapes.js +9 -9
  37. package/examples/shorts/slidingPuzzle.js +2 -2
  38. package/examples/shorts/starfield.js +5 -7
  39. package/examples/shorts/systemFont.js +1 -1
  40. package/examples/shorts/uiSystem.js +1 -0
  41. package/examples/starter/build.js +9 -8
  42. package/examples/starter/game.js +5 -2
  43. package/examples/starter/index.html +2 -2
  44. package/examples/stress/index.html +5 -5
  45. package/examples/style.css +5 -2
  46. package/examples/typescript/build.js +1 -1
  47. package/examples/typescript/game.js +2 -2
  48. package/examples/typescript/game.ts +5 -2
  49. package/examples/uiSystem/game.js +2 -1
  50. package/package.json +2 -2
  51. package/plugins/box2d.js +19 -94
  52. package/plugins/drawUtilities.js +24 -18
  53. package/plugins/postProcess.js +7 -0
  54. package/plugins/uiSystem.js +4 -4
  55. package/src/engine.js +7 -2
  56. package/src/engineAudio.js +1 -1
  57. package/src/engineDebug.js +2 -2
  58. package/src/engineDraw.js +243 -150
  59. package/src/engineExport.js +6 -0
  60. package/src/engineInput.js +2 -2
  61. package/src/engineMedals.js +4 -4
  62. package/src/engineObject.js +3 -3
  63. package/src/engineParticles.js +8 -1
  64. package/src/engineSettings.js +55 -8
  65. package/src/engineUtilities.js +7 -7
  66. package/src/engineWebGL.js +25 -5
@@ -16,10 +16,11 @@
16
16
  * @param {TileInfo} startTile - Starting tile for the nine-slice pattern
17
17
  * @param {number} [borderSize] - Width of the border sections
18
18
  * @param {number} [extraSpace] - Extra spacing adjustment
19
+ * @param {number} [angle] - Angle to rotate by
19
20
  * @memberof DrawUtilities */
20
- function drawNineSliceScreen(pos, size, startTile, borderSize=32, extraSpace=1)
21
+ function drawNineSliceScreen(pos, size, startTile, borderSize=32, extraSpace=2, angle=0)
21
22
  {
22
- drawNineSlice(pos, size, startTile, WHITE, borderSize, BLACK, extraSpace, false, true, overlayContext);
23
+ drawNineSlice(pos, size, startTile, WHITE, borderSize, BLACK, extraSpace, angle, false, true, overlayContext);
23
24
  }
24
25
 
25
26
  /** Draw a scalable nine-slice UI element in world space
@@ -31,11 +32,12 @@ function drawNineSliceScreen(pos, size, startTile, borderSize=32, extraSpace=1)
31
32
  * @param {number} [borderSize] - Width of the border sections
32
33
  * @param {Color} [additiveColor] - Additive color
33
34
  * @param {number} [extraSpace] - Extra spacing adjustment
35
+ * @param {number} [angle] - Angle to rotate by
34
36
  * @param {boolean} [useWebGL=glEnable] - Use WebGL for rendering
35
37
  * @param {boolean} [screenSpace] - Use screen space coordinates
36
38
  * @param {CanvasRenderingContext2D} [context] - Canvas context to use
37
39
  * @memberof DrawUtilities */
38
- function drawNineSlice(pos, size, startTile, color, borderSize=1, additiveColor, extraSpace=.01, useWebGL=glEnable, screenSpace, context)
40
+ function drawNineSlice(pos, size, startTile, color, borderSize=1, additiveColor, extraSpace=.05, angle=0, useWebGL=glEnable, screenSpace, context)
39
41
  {
40
42
  // setup nine slice tiles
41
43
  const centerTile = startTile.offset(startTile.size);
@@ -43,26 +45,27 @@ function drawNineSlice(pos, size, startTile, color, borderSize=1, additiveColor,
43
45
  const cornerSize = vec2(borderSize);
44
46
  const cornerOffset = size.scale(.5).subtract(cornerSize.scale(.5));
45
47
  const flip = screenSpace ? -1 : 1;
48
+ const rotateAngle = screenSpace ? -angle : angle;
46
49
 
47
50
  // center
48
- drawTile(pos, centerSize, centerTile, color, 0, false, additiveColor, useWebGL, screenSpace, context);
49
- for(let i=4; i--;)
51
+ drawTile(pos, centerSize, centerTile, color, angle, false, additiveColor, useWebGL, screenSpace, context);
52
+ for (let i=4; i--;)
50
53
  {
51
54
  // sides
52
55
  const horizontal = i%2;
53
56
  const sidePos = cornerOffset.multiply(vec2(horizontal?i==1?1:-1:0, horizontal?0:i?-1:1));
54
57
  const sideSize = vec2(horizontal ? borderSize : centerSize.x, horizontal ? centerSize.y : borderSize);
55
58
  const sideTile = centerTile.offset(startTile.size.multiply(vec2(i==1?1:i==3?-1:0,i==0?-flip:i==2?flip:0)))
56
- drawTile(pos.add(sidePos), sideSize, sideTile, color, 0, false, additiveColor, useWebGL, screenSpace, context);
59
+ drawTile(pos.add(sidePos.rotate(rotateAngle)), sideSize, sideTile, color, angle, false, additiveColor, useWebGL, screenSpace, context);
57
60
  }
58
- for(let i=4; i--;)
61
+ for (let i=4; i--;)
59
62
  {
60
63
  // corners
61
64
  const flipX = i>1;
62
65
  const flipY = i && i<3;
63
66
  const cornerPos = cornerOffset.multiply(vec2(flipX?-1:1, flipY?-1:1));
64
67
  const cornerTile = centerTile.offset(startTile.size.multiply(vec2(flipX?-1:1,flipY?flip:-flip)));
65
- drawTile(pos.add(cornerPos), cornerSize, cornerTile, color, 0, false, additiveColor, useWebGL, screenSpace, context);
68
+ drawTile(pos.add(cornerPos.rotate(rotateAngle)), cornerSize, cornerTile, color, angle, false, additiveColor, useWebGL, screenSpace, context);
66
69
  }
67
70
  }
68
71
 
@@ -73,10 +76,11 @@ function drawNineSlice(pos, size, startTile, color, borderSize=1, additiveColor,
73
76
  * @param {TileInfo} startTile - Starting tile for the three-slice pattern
74
77
  * @param {number} [borderSize] - Width of the border sections
75
78
  * @param {number} [extraSpace] - Extra spacing adjustment
79
+ * @param {number} [angle] - Angle to rotate by
76
80
  * @memberof DrawUtilities */
77
- function drawThreeSliceScreen(pos, size, startTile, borderSize=32, extraSpace=1)
81
+ function drawThreeSliceScreen(pos, size, startTile, borderSize=32, extraSpace=2, angle=0)
78
82
  {
79
- drawThreeSlice(pos, size, startTile, WHITE, borderSize, BLACK, extraSpace, false, true, overlayContext);
83
+ drawThreeSlice(pos, size, startTile, WHITE, borderSize, BLACK, extraSpace, angle, false, true, overlayContext);
80
84
  }
81
85
 
82
86
  /** Draw a scalable three-slice UI element in world space
@@ -88,11 +92,12 @@ function drawThreeSliceScreen(pos, size, startTile, borderSize=32, extraSpace=1)
88
92
  * @param {number} [borderSize] - Width of the border sections
89
93
  * @param {Color} [additiveColor] - Additive color
90
94
  * @param {number} [extraSpace] - Extra spacing adjustment
95
+ * @param {number} [angle] - Angle to rotate by
91
96
  * @param {boolean} [useWebGL=glEnable] - Use WebGL for rendering
92
97
  * @param {boolean} [screenSpace] - Use screen space coordinates
93
98
  * @param {CanvasRenderingContext2D} [context] - Canvas context to use
94
99
  * @memberof DrawUtilities */
95
- function drawThreeSlice(pos, size, startTile, color, borderSize=1, additiveColor, extraSpace=.01, useWebGL=glEnable, screenSpace, context)
100
+ function drawThreeSlice(pos, size, startTile, color, borderSize=1, additiveColor, extraSpace=.05, angle=0, useWebGL=glEnable, screenSpace, context)
96
101
  {
97
102
  // setup three slice tiles
98
103
  const cornerTile = startTile.frame(0);
@@ -102,25 +107,26 @@ function drawThreeSlice(pos, size, startTile, color, borderSize=1, additiveColor
102
107
  const cornerSize = vec2(borderSize);
103
108
  const cornerOffset = size.scale(.5).subtract(cornerSize.scale(.5));
104
109
  const flip = screenSpace ? -1 : 1;
110
+ const rotateAngle = screenSpace ? -angle : angle;
105
111
 
106
112
  // center
107
- drawTile(pos, centerSize, centerTile, color, 0, false, additiveColor, useWebGL, screenSpace, context);
108
- for(let i=4; i--;)
113
+ drawTile(pos, centerSize, centerTile, color, angle, false, additiveColor, useWebGL, screenSpace, context);
114
+ for (let i=4; i--;)
109
115
  {
110
116
  // sides
111
- const angle = i*PI/2;
117
+ const a = angle + i*PI/2;
112
118
  const horizontal = i%2;
113
119
  const sidePos = cornerOffset.multiply(vec2(horizontal?i==1?1:-1:0, horizontal?0:i?-flip:flip));
114
120
  const sideSize = vec2(horizontal ? centerSize.y : centerSize.x, borderSize);
115
- drawTile(pos.add(sidePos), sideSize, sideTile, color, angle, false, additiveColor, useWebGL, screenSpace, context);
121
+ drawTile(pos.add(sidePos.rotate(rotateAngle)), sideSize, sideTile, color, a, false, additiveColor, useWebGL, screenSpace, context);
116
122
  }
117
- for(let i=4; i--;)
123
+ for (let i=4; i--;)
118
124
  {
119
125
  // corners
120
- const angle = i*PI/2;
126
+ const a = angle + i*PI/2;
121
127
  const flipX = !i || i>2;
122
128
  const flipY = i>1;
123
129
  const cornerPos = cornerOffset.multiply(vec2(flipX?-1:1, flipY?-flip:flip));
124
- drawTile(pos.add(cornerPos), cornerSize, cornerTile, color, angle, false, additiveColor, useWebGL, screenSpace, context);
130
+ drawTile(pos.add(cornerPos.rotate(rotateAngle)), cornerSize, cornerTile, color, a, false, additiveColor, useWebGL, screenSpace, context);
125
131
  }
126
132
  }
@@ -32,6 +32,13 @@ class PostProcessPlugin
32
32
  postProcess = this;
33
33
 
34
34
  if (headlessMode) return;
35
+
36
+ if (!glEnable)
37
+ {
38
+ console.warn('PostProcessPlugin: WebGL not enabled!');
39
+ return;
40
+ }
41
+
35
42
  if (!shaderCode) // default shader pass through
36
43
  shaderCode = 'void mainImage(out vec4 c,vec2 p){c=texture(iChannel0,p/iResolution.xy);}';
37
44
 
@@ -66,7 +66,7 @@ class UISystemPlugin
66
66
 
67
67
  function updateInvisible(o)
68
68
  {
69
- for(const c of o.children)
69
+ for (const c of o.children)
70
70
  updateInvisible(c);
71
71
  o.updateInvisible();
72
72
  }
@@ -82,7 +82,7 @@ class UISystemPlugin
82
82
  if (o.parent)
83
83
  o.pos = o.localPos.add(o.parent.pos);
84
84
  // update in reverse order to detect mouse enter/leave
85
- for(let i=o.children.length; i--;)
85
+ for (let i=o.children.length; i--;)
86
86
  updateObject(o.children[i]);
87
87
  o.update();
88
88
  }
@@ -100,7 +100,7 @@ class UISystemPlugin
100
100
  if (o.parent)
101
101
  o.pos = o.localPos.add(o.parent.pos);
102
102
  o.render();
103
- for(const c of o.children)
103
+ for (const c of o.children)
104
104
  renderObject(c);
105
105
  }
106
106
  uiSystem.uiObjects.forEach(o=> o.parent || renderObject(o));
@@ -157,7 +157,7 @@ class UISystemPlugin
157
157
  * @param {boolean} [mirror] */
158
158
  drawTile(pos, size, tileInfo, color=uiSystem.defaultColor, angle=0, mirror=false)
159
159
  {
160
- drawTile(pos, size, tileInfo, color, angle, mirror, BLACK, false, true, uiSystem.uiContext);
160
+ drawTile(pos, size, tileInfo, color, angle, mirror, CLEAR_BLACK, false, true, uiSystem.uiContext);
161
161
  }
162
162
 
163
163
  /** Draw text to the UI context
package/src/engine.js CHANGED
@@ -30,7 +30,7 @@ const engineName = 'LittleJS';
30
30
  * @type {string}
31
31
  * @default
32
32
  * @memberof Engine */
33
- const engineVersion = '1.13.1';
33
+ const engineVersion = '1.13.4';
34
34
 
35
35
  /** Frames per second to update
36
36
  * @type {number}
@@ -297,7 +297,6 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
297
297
  'margin:0;' + // fill the window
298
298
  'overflow:hidden;' + // no scroll bars
299
299
  'background:#000;' + // set background color
300
- (canvasPixelated ? 'image-rendering:pixelated;' : '') + // pixel art
301
300
  'user-select:none;' + // prevent hold to select
302
301
  '-webkit-user-select:none;' + // compatibility for ios
303
302
  (!touchInputEnable ? '' : // no touch css settings
@@ -325,7 +324,13 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
325
324
  mainCanvas.style.cssText = overlayCanvas.style.cssText = styleCanvas;
326
325
  if (glCanvas)
327
326
  glCanvas.style.cssText = styleCanvas;
327
+ setCanvasPixelated(canvasPixelated);
328
+ setOverlayCanvasPixelated(overlayCanvasPixelated);
328
329
  updateCanvas();
330
+
331
+ // create offscreen canvas for image processing
332
+ workCanvas = new OffscreenCanvas(256, 256);
333
+ workContext = workCanvas.getContext('2d', { willReadFrequently: true });
329
334
 
330
335
  // create promises for loading images
331
336
  const promises = imageSources.map((src, textureIndex)=>
@@ -423,7 +423,7 @@ function zzfxG
423
423
  repeatTime = repeatTime * sampleRate | 0;
424
424
 
425
425
  // generate waveform
426
- for(length = attack + decay + sustain + release + delay | 0;
426
+ for (length = attack + decay + sustain + release + delay | 0;
427
427
  i < length; b[i++] = s * volume) // sample
428
428
  {
429
429
  if (!(++crush%(bitCrush*100|0))) // bit crush
@@ -474,7 +474,7 @@ function debugRender()
474
474
  overlayContext.fillText('6: Toggle Video Capture', x, y += h);
475
475
 
476
476
  let keysPressed = '';
477
- for(const i in inputData[0])
477
+ for (const i in inputData[0])
478
478
  {
479
479
  if (keyIsDown(i, 0))
480
480
  keysPressed += i + ' ' ;
@@ -483,7 +483,7 @@ function debugRender()
483
483
 
484
484
  let buttonsPressed = '';
485
485
  if (inputData[1])
486
- for(const i in inputData[1])
486
+ for (const i in inputData[1])
487
487
  {
488
488
  if (keyIsDown(i, 1))
489
489
  buttonsPressed += i + ' ' ;