littlejsengine 1.15.8 → 1.16.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 (53) hide show
  1. package/dist/littlejs.d.ts +87 -85
  2. package/dist/littlejs.esm.js +578 -532
  3. package/dist/littlejs.esm.min.js +1 -1
  4. package/dist/littlejs.js +562 -521
  5. package/dist/littlejs.min.js +1 -1
  6. package/dist/littlejs.release.js +485 -444
  7. package/examples/box2d/game.js +2 -2
  8. package/examples/breakout/game.js +3 -3
  9. package/examples/electron/game.js +1 -2
  10. package/examples/electron/index.html +2 -2
  11. package/examples/htmlMenu/game.js +0 -1
  12. package/examples/index.html +1 -1
  13. package/examples/module/game.js +1 -2
  14. package/examples/particles/index.html +1 -1
  15. package/examples/platformer/game.js +11 -4
  16. package/examples/puzzle/game.js +2 -2
  17. package/examples/shorts/base.html +3 -4
  18. package/examples/shorts/box2dPool.js +2 -2
  19. package/examples/shorts/empty.js +1 -1
  20. package/examples/shorts/{systemFont.js → fontImage.js} +3 -3
  21. package/examples/shorts/fps.js +1 -1
  22. package/examples/shorts/helloWorld.js +2 -2
  23. package/examples/shorts/nineSlice.js +2 -2
  24. package/examples/shorts/slidingPuzzle.js +1 -1
  25. package/examples/shorts/uiSystem.js +1 -1
  26. package/examples/starter/game.js +1 -2
  27. package/examples/starter/index.html +2 -3
  28. package/examples/stress/index.html +1 -1
  29. package/examples/typescript/game.js +1 -2
  30. package/examples/typescript/game.ts +1 -2
  31. package/examples/uiSystem/game.js +4 -7
  32. package/package.json +1 -1
  33. package/plugins/box2d.js +8 -8
  34. package/plugins/drawUtilities.js +6 -6
  35. package/plugins/postProcess.js +13 -20
  36. package/plugins/uiSystem.js +15 -3
  37. package/reference.md +4 -6
  38. package/src/engine.js +240 -53
  39. package/src/engineAudio.js +3 -3
  40. package/src/engineBuild.js +0 -1
  41. package/src/engineDebug.js +78 -78
  42. package/src/engineDraw.js +107 -109
  43. package/src/engineExport.js +16 -11
  44. package/src/engineInput.js +14 -2
  45. package/src/engineMedals.js +3 -3
  46. package/src/engineObject.js +4 -2
  47. package/src/engineParticles.js +8 -6
  48. package/src/engineRelease.js +1 -1
  49. package/src/engineSettings.js +44 -30
  50. package/src/engineTileLayer.js +6 -6
  51. package/src/engineUtilities.js +2 -10
  52. package/src/engineWebGL.js +6 -5
  53. package/src/engineSplash.js +0 -173
@@ -48,6 +48,20 @@ let canvasClearColor = CLEAR_BLACK;
48
48
  * @memberof Settings */
49
49
  let canvasMaxSize = vec2(1920, 1080);
50
50
 
51
+ /** Minimum aspect ratio of the canvas (width/height), unused if 0
52
+ * Can be used with canvasMaxAspect to limit aspect ratio
53
+ * @type {number}
54
+ * @default
55
+ * @memberof Settings */
56
+ let canvasMinAspect = 0;
57
+
58
+ /** Maximum aspect ratio of the canvas (width/height), unused if 0
59
+ * Can be used with canvasMinAspect to limit aspect ratio
60
+ * @type {number}
61
+ * @default
62
+ * @memberof Settings */
63
+ let canvasMaxAspect = 0;
64
+
51
65
  /** Fixed size of the canvas, if enabled canvas size never changes
52
66
  * - you may also need to set mainCanvasSize if using screen space coords in startup
53
67
  * @type {Vector2}
@@ -60,15 +74,7 @@ let canvasFixedSize = vec2();
60
74
  * @type {boolean}
61
75
  * @default
62
76
  * @memberof Settings */
63
- let canvasPixelated = true;
64
-
65
- /** Use nearest canvas scaling for more pixelated look
66
- * - If enabled sets css image-rendering:pixelated
67
- * - This defaults to false because text looks better with smoothing
68
- * @type {boolean}
69
- * @default
70
- * @memberof Settings */
71
- let overlayCanvasPixelated = false;
77
+ let canvasPixelated = false;
72
78
 
73
79
  /** Disables texture filtering for crisper pixel art
74
80
  * @type {boolean}
@@ -116,13 +122,19 @@ let glCircleSides = 32;
116
122
  * @type {Vector2}
117
123
  * @default Vector2(16,16)
118
124
  * @memberof Settings */
119
- let tileSizeDefault = vec2(16);
125
+ let tileDefaultSize = vec2(16);
120
126
 
121
- /** How many pixels smaller to draw tiles to prevent bleeding from neighbors
127
+ /** Default padding pixels around tiles
122
128
  * @type {number}
123
129
  * @default
124
130
  * @memberof Settings */
125
- let tileFixBleedScale = 0;
131
+ let tileDefaultPadding = 0;
132
+
133
+ /** Default amount of pixels smaller to draw tiles to prevent neighbor bleeding
134
+ * @type {number}
135
+ * @default
136
+ * @memberof Settings */
137
+ let tileDefaultBleed = 0;
126
138
 
127
139
  ///////////////////////////////////////////////////////////////////////////////
128
140
  // Object settings
@@ -344,13 +356,22 @@ function setCanvasClearColor(color) { canvasClearColor = color.copy(); }
344
356
  * @memberof Settings */
345
357
  function setCanvasMaxSize(size) { canvasMaxSize = size.copy(); }
346
358
 
359
+ /** Set minimum aspect ratio of the canvas (width/height), unused if 0
360
+ * @param {number} aspect
361
+ * @memberof Settings */
362
+ function setCanvasMinAspect(aspect) { canvasMinAspect = aspect; }
363
+
364
+ /** Set maximum aspect ratio of the canvas (width/height), unused if 0
365
+ * @param {number} aspect
366
+ * @memberof Settings */
367
+ function setCanvasMaxAspect(aspect) { canvasMaxAspect = aspect; }
368
+
347
369
  /** Set fixed size of the canvas
348
370
  * @param {Vector2} size
349
371
  * @memberof Settings */
350
372
  function setCanvasFixedSize(size) { canvasFixedSize = size.copy(); }
351
373
 
352
374
  /** Use nearest scaling algorithm for canvas for more pixelated look
353
- * - If enabled sets css image-rendering:pixelated
354
375
  * @param {boolean} pixelated
355
376
  * @memberof Settings */
356
377
  function setCanvasPixelated(pixelated)
@@ -362,18 +383,6 @@ function setCanvasPixelated(pixelated)
362
383
  glCanvas.style.imageRendering = pixelated ? 'pixelated' : '';
363
384
  }
364
385
 
365
- /** Use nearest scaling algorithm for canvas for more pixelated look
366
- * - If enabled sets css image-rendering:pixelated
367
- * - This defaults to false because text looks better with smoothing
368
- * @param {boolean} pixelated
369
- * @memberof Settings */
370
- function setOverlayCanvasPixelated(pixelated)
371
- {
372
- overlayCanvasPixelated = pixelated;
373
- if (overlayCanvas)
374
- overlayCanvas.style.imageRendering = pixelated ? 'pixelated' : '';
375
- }
376
-
377
386
  /** Disables texture filtering for crisper pixel art
378
387
  * @param {boolean} pixelated
379
388
  * @memberof Settings */
@@ -417,12 +426,17 @@ function setGLCircleSides(sides) { glCircleSides = sides; }
417
426
  /** Set default size of tiles in pixels
418
427
  * @param {Vector2} size
419
428
  * @memberof Settings */
420
- function setTileSizeDefault(size) { tileSizeDefault = size.copy(); }
429
+ function setTileDefaultSize(size) { tileDefaultSize = size.copy(); }
421
430
 
422
- /** Set to prevent tile bleeding from neighbors in pixels
423
- * @param {number} scale
431
+ /** Default padding pixels around tiles
432
+ * @param {number} padding
433
+ * @memberof Settings */
434
+ function setTileDefaultPadding(padding) { tileDefaultPadding = padding; }
435
+
436
+ /** Default amount of pixels smaller to draw tiles to prevent neighbor bleeding
437
+ * @param {number} bleed
424
438
  * @memberof Settings */
425
- function setTileFixBleedScale(scale) { tileFixBleedScale = scale; }
439
+ function setTileDefaultBleed(bleed) { tileDefaultBleed = bleed; }
426
440
 
427
441
  /** Set if collisions between objects are enabled
428
442
  * @param {boolean} enable
@@ -573,7 +587,7 @@ function setMedalsPreventUnlock(preventUnlock) { medalsPreventUnlock = preventUn
573
587
  /** Set if watermark with FPS should be shown
574
588
  * @param {boolean} show
575
589
  * @memberof Debug */
576
- function setShowWatermark(show) { showWatermark = show; }
590
+ function setDebugWatermark(show) { debugWatermark = show; }
577
591
 
578
592
  /** Set key code used to toggle debug mode, Esc by default
579
593
  * @param {string} key
@@ -211,8 +211,7 @@ class CanvasLayer extends EngineObject
211
211
  /** Destroy this canvas layer */
212
212
  destroy()
213
213
  {
214
- if (this.destroyed)
215
- return;
214
+ if (this.destroyed) return;
216
215
 
217
216
  this.textureInfo.destroyWebGLTexture();
218
217
  super.destroy();
@@ -444,8 +443,8 @@ class TileLayer extends CanvasLayer
444
443
  if (!this.context) return;
445
444
 
446
445
  // save current render settings
447
- /** @type {[HTMLCanvasElement|OffscreenCanvas, CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D, Vector2, Vector2, number]} */
448
- this.savedRenderSettings = [drawCanvas, drawContext, mainCanvasSize, cameraPos, cameraScale];
446
+ /** @type {[HTMLCanvasElement|OffscreenCanvas, CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D, Vector2, Vector2, number, Color]} */
447
+ this.savedRenderSettings = [drawCanvas, drawContext, mainCanvasSize, cameraPos, cameraScale, canvasClearColor];
449
448
 
450
449
  // set the draw canvas and context to this layer
451
450
  // use camera settings to match this layer's canvas
@@ -454,6 +453,7 @@ class TileLayer extends CanvasLayer
454
453
  cameraPos = this.size.scale(.5);
455
454
  const tileSize = this.tileInfo ? this.tileInfo.size : vec2(1);
456
455
  cameraScale = tileSize.x;
456
+ canvasClearColor = CLEAR_BLACK;
457
457
  mainCanvasSize = this.size.multiply(tileSize);
458
458
  if (clear)
459
459
  {
@@ -463,7 +463,7 @@ class TileLayer extends CanvasLayer
463
463
  }
464
464
 
465
465
  // disable smoothing for pixel art
466
- this.context.imageSmoothingEnabled = !tilesPixelated;
466
+ drawContext.imageSmoothingEnabled = !tilesPixelated;
467
467
 
468
468
  // setup gl rendering if enabled
469
469
  glPreRender();
@@ -479,7 +479,7 @@ class TileLayer extends CanvasLayer
479
479
  //debugSaveCanvas(this.canvas);
480
480
 
481
481
  // set stuff back to normal
482
- [drawCanvas, drawContext, mainCanvasSize, cameraPos, cameraScale] = this.savedRenderSettings;
482
+ [drawCanvas, drawContext, mainCanvasSize, cameraPos, cameraScale, canvasClearColor] = this.savedRenderSettings;
483
483
  }
484
484
 
485
485
  /** Draw the tile at a given position in the tile grid
@@ -126,11 +126,7 @@ function percent(value, valueA, valueB)
126
126
  * @return {number}
127
127
  * @memberof Utilities */
128
128
  function lerp(valueA, valueB, percent)
129
- {
130
- if (valueA >= 0 && valueA <= 1 && ((valueB < 0 || valueB > 1) && (percent < 0 || percent > 1)))
131
- console.warn('lerp() parameter order changed! use lerp(start, end, p)');
132
- return valueA + clamp(percent) * (valueB-valueA);
133
- }
129
+ { return valueA + clamp(percent) * (valueB-valueA); }
134
130
 
135
131
  /** Gets percent between percentA and percentB and linearly interpolates between lerpA and lerpB
136
132
  * A shortcut for lerp(lerpA, lerpB, percent(value, percentA, percentB))
@@ -161,11 +157,7 @@ function distanceWrap(valueA, valueB, wrapSize=1)
161
157
  * @return {number}
162
158
  * @memberof Utilities */
163
159
  function lerpWrap(valueA, valueB, percent, wrapSize=1)
164
- {
165
- if (valueA >= 0 && valueA <= 1 && ((valueB < 0 || valueB > 1) && (percent < 0 || percent > 1)))
166
- console.warn('lerpWrap() parameter order changed! use lerpWrap(start, end, p)');
167
- return valueA + clamp(percent) * distanceWrap(valueB, valueA, wrapSize);
168
- }
160
+ { return valueA + clamp(percent) * distanceWrap(valueB, valueA, wrapSize); }
169
161
 
170
162
  /** Returns signed wrapped distance between the two angles passed in
171
163
  * @param {number} angleA
@@ -13,7 +13,7 @@
13
13
 
14
14
  'use strict';
15
15
 
16
- /** The WebGL canvas which appears above the main canvas and below the overlay canvas
16
+ /** The WebGL canvas which appears below the main canvas
17
17
  * @type {HTMLCanvasElement}
18
18
  * @memberof WebGL */
19
19
  let glCanvas;
@@ -43,7 +43,7 @@ const gl_MAX_POLY_VERTEXES = gl_ARRAY_BUFFER_SIZE / gl_POLY_VERTEX_BYTE_STRIDE |
43
43
  ///////////////////////////////////////////////////////////////////////////////
44
44
 
45
45
  // Initialize WebGL, called automatically by the engine
46
- function glInit()
46
+ function glInit(rootElement)
47
47
  {
48
48
  // keep set of texture infos so they can be restored if context is lost
49
49
  glTextureInfos = new Set;
@@ -67,8 +67,7 @@ function glInit()
67
67
  return;
68
68
  }
69
69
 
70
- // attach the WebGL canvas
71
- const rootElement = mainCanvas.parentElement;
70
+ // attach the WebGL canvas;
72
71
  rootElement.appendChild(glCanvas);
73
72
 
74
73
  // startup webgl
@@ -286,6 +285,9 @@ function glClearCanvas()
286
285
  glCanvas.width = drawCanvas.width;
287
286
  glCanvas.height = drawCanvas.height;
288
287
  glContext.viewport(0, 0, glCanvas.width, glCanvas.height);
288
+ const color = canvasClearColor;
289
+ if (color.a > 0)
290
+ glContext.clearColor(color.r, color.g, color.b, color.a);
289
291
  glContext.clear(glContext.COLOR_BUFFER_BIT);
290
292
  }
291
293
 
@@ -515,7 +517,6 @@ function glDraw(x, y, sizeX, sizeY, angle=0, uv0X=0, uv0Y=0, uv1X=1, uv1Y=1, rgb
515
517
  glFlush();
516
518
  glSetInstancedMode();
517
519
 
518
- glPolyMode = false;
519
520
  let offset = glBatchCount++ * gl_INDICES_PER_INSTANCE;
520
521
  glPositionData[offset++] = x;
521
522
  glPositionData[offset++] = y;
@@ -1,173 +0,0 @@
1
- /**
2
- * LittleJS Engine Splash Screen
3
- * @namespace Settings
4
- */
5
-
6
- 'use strict';
7
-
8
- ///////////////////////////////////////////////////////////////////////////////
9
- // LittleJS splash screen and logo
10
-
11
- function drawEngineSplashScreen(t)
12
- {
13
- const x = overlayContext;
14
- const w = overlayCanvas.width = innerWidth;
15
- const h = overlayCanvas.height = innerHeight;
16
-
17
- {
18
- // background
19
- const p3 = percent(t, 1, .8);
20
- const p4 = percent(t, 0, .5);
21
- const g = x.createRadialGradient(w/2,h/2,0,w/2,h/2,hypot(w,h)*.7);
22
- g.addColorStop(0,hsl(0,0,lerp(0,p3/2,p4),p3).toString());
23
- g.addColorStop(1,hsl(0,0,0,p3).toString());
24
- x.save();
25
- x.fillStyle = g;
26
- x.fillRect(0,0,w,h);
27
- }
28
-
29
- // draw LittleJS logo...
30
- const rect = (X, Y, W, H, C)=>
31
- {
32
- x.beginPath();
33
- x.rect(X,Y,W,C?H*p:H);
34
- x.fillStyle = C;
35
- C ? x.fill() : x.stroke();
36
- };
37
- const line = (X, Y, Z, W)=>
38
- {
39
- x.beginPath();
40
- x.lineTo(X,Y);
41
- x.lineTo(Z,W);
42
- x.stroke();
43
- };
44
- const circle = (X, Y, R, A=0, B=2*PI, C, F)=>
45
- {
46
- const D = (A+B)/2, E = p*(B-A)/2;
47
- x.beginPath();
48
- F && x.lineTo(X,Y);
49
- x.arc(X,Y,R,D-E,D+E);
50
- x.fillStyle = C;
51
- C ? x.fill() : x.stroke();
52
- };
53
- const color = (c=0, l=0) =>
54
- hsl([.98,.3,.57,.14][c%4],.8,[0,.3,.5,.8,.9][l]).toString();
55
- const alpha = wave(1,1,t);
56
- const p = percent(alpha, .1, .5);
57
-
58
- // setup
59
- x.translate(w/2,h/2);
60
- const size = min(6, min(w,h)/99); // fit to screen
61
- x.scale(size,size);
62
- x.translate(-40,-35);
63
- x.lineJoin = x.lineCap = 'round';
64
- x.lineWidth = .1 + p*1.9;
65
-
66
- // drawing effect
67
- const p2 = percent(alpha,.1,1);
68
- x.setLineDash([99*p2,99]);
69
-
70
- // cab top
71
- rect(7,16,18,-8,color(2,2));
72
- rect(7,8,18,4,color(2,3));
73
- rect(25,8,8,8,color(2,1));
74
- rect(25,8,-18,8);
75
- rect(25,8,8,8);
76
-
77
- // cab
78
- rect(25,16,7,23,color());
79
- rect(11,39,14,-23,color(1,1));
80
- rect(11,16,14,18,color(1,2));
81
- rect(11,16,14,8,color(1,3));
82
- rect(25,16,-14,24);
83
-
84
- // cab window
85
- rect(15,29,6,-9,color(2,2));
86
- circle(15,21,5,0,PI/2,color(2,4),1);
87
- rect(21,21,-6,9);
88
-
89
- // little stack
90
- rect(37,14,9,6,color(3,2));
91
- rect(37,14,4.5,6,color(3,3));
92
- rect(37,14,9,6);
93
-
94
- // big stack
95
- rect(50,20,10,-8,color(0,1));
96
- rect(50,20,6.5,-8,color(0,2));
97
- rect(50,20,3.5,-8,color(0,3));
98
- rect(50,20,10,-8);
99
- circle(55,2,11.4,.5,PI-.5,color(3,3));
100
- circle(55,2,11.4,.5,PI/2,color(3,2),1);
101
- circle(55,2,11.4,.5,PI-.5);
102
- rect(45,7,20,-7,color(0,2));
103
- rect(45,-1,20,4,color(0,3));
104
- rect(45,-1,20,8);
105
-
106
- // engine
107
- for (let i=5; i--;)
108
- {
109
- // stagger radius to fix slight seam
110
- circle(60-i*6,30, 9.9,0,2*PI,color(i+2,3));
111
- circle(60-i*6,30,10.0,-.5,PI+.5,color(i+2,2));
112
- circle(60-i*6,30,10.1,.5,PI-.5,color(i+2,1));
113
- }
114
-
115
- // engine outline
116
- circle(36,30,10,PI/2,PI*3/2);
117
- circle(48,30,10,PI/2,PI*3/2);
118
- circle(60,30,10);
119
- line(36,20,60,20);
120
-
121
- // engine front light
122
- circle(60,30,4,PI,3*PI,color(3,2));
123
- circle(60,30,4,PI,2*PI,color(3,3));
124
- circle(60,30,4,PI,3*PI);
125
-
126
- // front brush
127
- for (let i=6; i--;)
128
- {
129
- x.beginPath();
130
- x.lineTo(53,54);
131
- x.lineTo(53,40);
132
- x.lineTo(53+(1+i*2.9)*p,40);
133
- x.lineTo(53+(4+i*3.5)*p,54);
134
- x.fillStyle = color(0,i%2+2);
135
- x.fill();
136
- i%2 && x.stroke();
137
- }
138
-
139
- // wheels
140
- rect(6,40,5,5);
141
- rect(6,40,5,5,color());
142
- rect(15,54,38,-14,color());
143
- for (let i=3; i--;)
144
- for (let j=2; j--;)
145
- {
146
- circle(15*i+15,47,j?7:1,PI,3*PI,color(i,3));
147
- x.stroke();
148
- circle(15*i+15,47,j?7:1,0,PI,color(i,2));
149
- x.stroke();
150
- }
151
- line(6,40,68,40); // center
152
- line(77,54,4,54); // bottom
153
-
154
- // draw engine name
155
- const s = engineName;
156
- x.font = '900 16px arial';
157
- x.textAlign = 'center';
158
- x.textBaseline = 'top';
159
- x.lineWidth = .1+p*3.9;
160
- let w2 = 0;
161
- for (let i=0; i<s.length; ++i)
162
- w2 += x.measureText(s[i]).width;
163
- for (let j=2; j--;)
164
- for (let i=0, X=41-w2/2; i<s.length; ++i)
165
- {
166
- x.fillStyle = color(i,2);
167
- const w = x.measureText(s[i]).width;
168
- x[j?'strokeText':'fillText'](s[i],X+w/2,55.5,17*p);
169
- X += w;
170
- }
171
-
172
- x.restore();
173
- }