littlejsengine 1.19.3 → 1.20.0

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 (50) hide show
  1. package/FAQ.md +841 -820
  2. package/README.md +29 -25
  3. package/dist/littlejs.d.ts +2455 -935
  4. package/dist/littlejs.esm.js +30344 -21110
  5. package/dist/littlejs.esm.min.js +4 -3
  6. package/dist/littlejs.js +30259 -21052
  7. package/dist/littlejs.min.js +2 -2
  8. package/dist/littlejs.release.js +26567 -20455
  9. package/package.json +10 -5
  10. package/plugins/audioEffects.js +28 -24
  11. package/plugins/box2d.js +2516 -2073
  12. package/plugins/drawUtilities.js +206 -31
  13. package/plugins/gltf.js +740 -0
  14. package/plugins/jsconfig.json +19 -0
  15. package/plugins/lightSystem.js +719 -332
  16. package/plugins/math3d.js +58 -17
  17. package/plugins/medalSystem.js +326 -280
  18. package/plugins/newgrounds.js +400 -199
  19. package/plugins/pathFinder.js +208 -175
  20. package/plugins/pluginExport.js +15 -0
  21. package/plugins/postProcess.js +56 -13
  22. package/plugins/render3d.js +1643 -1577
  23. package/plugins/render3dDebug.js +109 -0
  24. package/plugins/render3dExtras.js +1754 -0
  25. package/plugins/render3dVoxels.js +502 -0
  26. package/plugins/textureSheet.js +496 -458
  27. package/plugins/threejs.js +183 -163
  28. package/plugins/tweakables.js +411 -0
  29. package/plugins/tweenSystem.js +263 -145
  30. package/plugins/uiSystem.js +2024 -1687
  31. package/plugins/zzfxm.js +159 -159
  32. package/src/engine.js +191 -75
  33. package/src/engineAudio.js +229 -125
  34. package/src/engineBuild.mjs +289 -256
  35. package/src/engineDebug.js +912 -742
  36. package/src/engineDraw.js +295 -193
  37. package/src/engineEditor.js +2431 -0
  38. package/src/engineExport.js +12 -0
  39. package/src/engineInput.js +1462 -1293
  40. package/src/engineMath.js +1274 -1252
  41. package/src/engineObject.js +194 -80
  42. package/src/engineParticles.js +583 -532
  43. package/src/engineRelease.js +67 -45
  44. package/src/engineSettings.js +77 -29
  45. package/src/engineTileLayer.js +995 -741
  46. package/src/engineUtilities.js +19 -13
  47. package/src/engineWebGL.js +239 -82
  48. package/src/jsconfig.json +17 -13
  49. package/plugins/box2d.wasm.js +0 -630
  50. package/plugins/box2d.wasm.wasm +0 -0
@@ -1,163 +1,183 @@
1
- /**
2
- * LittleJS Three.js Plugin
3
- * - Renders a three.js scene on a canvas behind the LittleJS canvases
4
- * - The three.js module is passed in by the user, nothing is bundled
5
- * - Keep canvasClearColor transparent so the 3D scene shows through
6
- * - Aligned camera mode locks the 3D camera to the LittleJS 2D camera
7
- * - ThreeJSObject lets LittleJS physics drive a three.js mesh
8
- * - Call new ThreeJSPlugin(THREE) in gameInit to set up
9
- * @namespace ThreeJS
10
- */
11
-
12
- 'use strict';
13
-
14
- ///////////////////////////////////////////////////////////////////////////////
15
-
16
- /** Global ThreeJS plugin object
17
- * @type {ThreeJSPlugin}
18
- * @memberof ThreeJS */
19
- let threeJS;
20
-
21
- ///////////////////////////////////////////////////////////////////////////////
22
- /**
23
- * ThreeJS Plugin - Renders a three.js scene behind the LittleJS canvas
24
- * @example
25
- * // in gameInit, with three.js loaded by the user
26
- * new ThreeJSPlugin(THREE);
27
- * threeJS.scene.add(new THREE.AmbientLight);
28
- * @memberof ThreeJS
29
- */
30
- class ThreeJSPlugin
31
- {
32
- /** Set up the three.js rendering layer, call in gameInit
33
- * @param {Object} THREE - The three.js module, supplied by the user
34
- * @param {number} [cameraFOV] - Vertical field of view in degrees */
35
- constructor(THREE, cameraFOV=60)
36
- {
37
- ASSERT(!threeJS, 'ThreeJS plugin already initialized');
38
- threeJS = this;
39
- if (headlessMode) return;
40
- ASSERT(mainCanvas, 'ThreeJS plugin must be created after engineInit, call in gameInit');
41
- ASSERT(THREE && THREE.WebGLRenderer, 'three.js module must be passed in');
42
-
43
- /** @property {Object} - The three.js module passed into the constructor */
44
- this.THREE = THREE;
45
- /** @property {Object} - The three.js renderer */
46
- this.renderer = new THREE.WebGLRenderer({antialias: true});
47
- /** @property {Object} - The three.js scene, add lights and meshes here */
48
- this.scene = new THREE.Scene();
49
- /** @property {Object} - The three.js perspective camera */
50
- this.camera = new THREE.PerspectiveCamera(cameraFOV, 1, .1, 1e3);
51
- /** @property {boolean} - Lock the camera to the LittleJS 2D camera so the z=0 plane matches world space */
52
- this.cameraAlign2D = true;
53
-
54
- // insert the canvas below the engine canvases and match the layout
55
- const threeCanvas = this.renderer.domElement;
56
- const rootElement = mainCanvas.parentElement;
57
- rootElement.insertBefore(threeCanvas, rootElement.firstChild);
58
- threeCanvas.style.cssText = mainCanvas.style.cssText;
59
-
60
- // composite the 3D canvas into screenshots and video capture
61
- setBackgroundCanvas(threeCanvas);
62
-
63
- // render automatically each frame after the engine renders
64
- engineAddPlugin(undefined, ()=> this.render());
65
- }
66
-
67
- /** Position the camera so the z=0 plane exactly matches LittleJS world space,
68
- * called automatically when cameraAlign2D is set */
69
- alignCamera2D()
70
- {
71
- const halfHeight = mainCanvasSize.y / 2 / cameraScale; // half visible height in world units
72
- const distance = halfHeight / tan(this.camera.fov/2 * PI/180);
73
- this.camera.position.set(cameraPos.x, cameraPos.y, distance);
74
- // reset all axes in case a free camera was used, littlejs angles are clockwise
75
- this.camera.rotation.set(0, 0, -cameraAngle);
76
- }
77
-
78
- /** Sync the canvas layout and render the scene, called automatically each frame */
79
- render()
80
- {
81
- if (!this.renderer) return; // headless mode
82
-
83
- // keep renderer size and css in sync with the LittleJS canvas
84
- // mainCanvasSize is css pixels, three scales it by the pixel ratio
85
- const threeCanvas = this.renderer.domElement;
86
- const dpr = getCanvasPixelRatio();
87
- const bufferSizeX = mainCanvasSize.x * dpr | 0;
88
- const bufferSizeY = mainCanvasSize.y * dpr | 0;
89
- if (threeCanvas.width != bufferSizeX || threeCanvas.height != bufferSizeY)
90
- {
91
- this.renderer.setPixelRatio(dpr);
92
- this.renderer.setSize(mainCanvasSize.x, mainCanvasSize.y, false);
93
- this.camera.aspect = mainCanvasSize.x / mainCanvasSize.y;
94
- this.camera.updateProjectionMatrix();
95
- }
96
- if (threeCanvas.style.cssText != mainCanvas.style.cssText)
97
- threeCanvas.style.cssText = mainCanvas.style.cssText;
98
-
99
- if (this.cameraAlign2D)
100
- this.alignCamera2D();
101
- this.renderer.render(this.scene, this.camera);
102
- }
103
- }
104
-
105
- ///////////////////////////////////////////////////////////////////////////////
106
- /**
107
- * ThreeJS Object - EngineObject that drives a three.js mesh
108
- * - LittleJS physics moves the object and the mesh follows automatically
109
- * - Destroying the object removes the mesh from the scene
110
- * @extends EngineObject
111
- * @memberof ThreeJS
112
- */
113
- class ThreeJSObject extends EngineObject
114
- {
115
- /** Create an engine object that drives a three.js mesh
116
- * @param {Vector2} [pos] - World space position
117
- * @param {Vector2} [size] - World space size
118
- * @param {Object} [mesh] - The three.js object3d to drive
119
- * @param {number} [z] - Mesh height above the 2D plane */
120
- constructor(pos, size, mesh, z=0)
121
- {
122
- super(pos, size);
123
- ASSERT(threeJS, 'ThreeJS plugin must be initialized first');
124
-
125
- /** @property {Object} - The three.js object3d this object drives */
126
- this.mesh = mesh;
127
- /** @property {number} - Mesh height above the 2D plane */
128
- this.z = z;
129
- if (mesh)
130
- {
131
- threeJS.scene.add(mesh);
132
- this.syncMesh();
133
- }
134
- }
135
-
136
- /** Update the object and sync the mesh to its transform */
137
- update()
138
- {
139
- super.update();
140
- this.syncMesh();
141
- }
142
-
143
- /** Copy this object's transform to the mesh */
144
- syncMesh()
145
- {
146
- if (!this.mesh) return;
147
- this.mesh.position.set(this.pos.x, this.pos.y, this.z);
148
- this.mesh.rotation.z = -this.angle; // littlejs angles are clockwise
149
- }
150
-
151
- /** The mesh is this object's visual, the default 2D rendering is skipped */
152
- render() {}
153
-
154
- /** Destroy this object and remove its mesh from the scene
155
- * @param {boolean} [immediate] */
156
- destroy(immediate)
157
- {
158
- if (this.destroyed) return;
159
- // note: frequently destroyed objects should also dispose geometry and material
160
- this.mesh && threeJS.scene.remove(this.mesh);
161
- super.destroy(immediate);
162
- }
163
- }
1
+ /**
2
+ * LittleJS Three.js Plugin
3
+ * - Renders a three.js scene on a canvas behind the LittleJS canvases
4
+ * - The three.js module is passed in by the user, nothing is bundled
5
+ * - Keep canvasClearColor transparent so the 3D scene shows through
6
+ * - Aligned camera mode locks the 3D camera to the LittleJS 2D camera
7
+ * - ThreeJSObject lets LittleJS physics drive a three.js mesh
8
+ * - Call new ThreeJSPlugin(THREE) in gameInit to set up
9
+ * @namespace ThreeJS
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ ///////////////////////////////////////////////////////////////////////////////
15
+
16
+ /** Global ThreeJS plugin object
17
+ * @type {ThreeJSPlugin}
18
+ * @memberof ThreeJS */
19
+ let threeJS;
20
+
21
+ ///////////////////////////////////////////////////////////////////////////////
22
+ /**
23
+ * ThreeJS Plugin - Renders a three.js scene behind the LittleJS canvas
24
+ * @example
25
+ * // in gameInit, with three.js loaded by the user
26
+ * new ThreeJSPlugin(THREE);
27
+ * threeJS.scene.add(new THREE.AmbientLight);
28
+ * @memberof ThreeJS
29
+ */
30
+ class ThreeJSPlugin
31
+ {
32
+ /** Set up the three.js rendering layer, call in gameInit
33
+ * @param {Object} THREE - The three.js module, supplied by the user
34
+ * @param {number} [cameraFOV] - Vertical field of view in degrees */
35
+ constructor(THREE, cameraFOV=60)
36
+ {
37
+ ASSERT(!threeJS, 'ThreeJS plugin already initialized');
38
+ threeJS = this;
39
+ if (headlessMode) return;
40
+ ASSERT(mainCanvas, 'ThreeJS plugin must be created after engineInit, call in gameInit');
41
+ ASSERT(THREE && THREE.WebGLRenderer, 'three.js module must be passed in');
42
+
43
+ /** @property {Object} - The three.js module passed into the constructor */
44
+ this.THREE = THREE;
45
+ /** @property {Object} - The three.js renderer */
46
+ this.renderer = new THREE.WebGLRenderer({antialias: true});
47
+ /** @property {Object} - The three.js scene, add lights and meshes here */
48
+ this.scene = new THREE.Scene();
49
+ /** @property {Object} - The three.js perspective camera */
50
+ this.camera = new THREE.PerspectiveCamera(cameraFOV, 1, .1, 1e3);
51
+ /** @property {boolean} - Lock the camera to the LittleJS 2D camera so the z=0 plane matches world space */
52
+ this.cameraAlign2D = true;
53
+ /** @property {number|undefined} - Near plane of the aligned camera before any zoom out, from camera.near on the
54
+ * first aligned frame; while aligned, change this rather than camera.near
55
+ * @type {number|undefined} */
56
+ this.cameraNear = undefined;
57
+ /** @property {number|undefined} - Far plane of the aligned camera before any zoom out, from camera.far on the
58
+ * first aligned frame; while aligned, change this rather than camera.far
59
+ * @type {number|undefined} */
60
+ this.cameraFar = undefined;
61
+
62
+ // insert the canvas below the engine canvases and match the layout
63
+ const threeCanvas = this.renderer.domElement;
64
+ const rootElement = mainCanvas.parentElement;
65
+ rootElement.insertBefore(threeCanvas, rootElement.firstChild);
66
+ threeCanvas.style.cssText = mainCanvas.style.cssText;
67
+
68
+ // composite the 3D canvas into screenshots and video capture
69
+ setBackgroundCanvas(threeCanvas);
70
+
71
+ // render automatically each frame after the engine renders
72
+ engineAddPlugin(undefined, ()=> this.render());
73
+ }
74
+
75
+ /** Position the camera so the z=0 plane exactly matches LittleJS world space,
76
+ * called automatically when cameraAlign2D is set */
77
+ alignCamera2D()
78
+ {
79
+ const halfHeight = mainCanvasSize.y / 2 / cameraScale; // half visible height in world units
80
+ const distance = halfHeight / tan(this.camera.fov/2 * PI/180);
81
+
82
+ // zoomed out far enough that the z=0 plane would be past the far plane, push both planes out together
83
+ // so the depth precision stays what it was, and bring them back from where they began when zoomed in again
84
+ const baseNear = this.cameraNear ??= this.camera.near, baseFar = this.cameraFar ??= this.camera.far;
85
+ const scale = max(1, distance * 2 / baseFar), near = baseNear * scale, far = baseFar * scale;
86
+ if (near != this.camera.near || far != this.camera.far)
87
+ {
88
+ this.camera.near = near;
89
+ this.camera.far = far;
90
+ this.camera.updateProjectionMatrix();
91
+ }
92
+ this.camera.position.set(cameraPos.x, cameraPos.y, distance);
93
+ // reset all axes in case a free camera was used, littlejs angles are clockwise
94
+ this.camera.rotation.set(0, 0, -cameraAngle);
95
+ }
96
+
97
+ /** Sync the canvas layout and render the scene, called automatically each frame */
98
+ render()
99
+ {
100
+ if (!this.renderer) return; // headless mode
101
+
102
+ // keep renderer size and css in sync with the LittleJS canvas
103
+ // mainCanvasSize is css pixels, three scales it by the pixel ratio
104
+ const threeCanvas = this.renderer.domElement;
105
+ const dpr = getCanvasPixelRatio();
106
+ const bufferSizeX = mainCanvasSize.x * dpr | 0;
107
+ const bufferSizeY = mainCanvasSize.y * dpr | 0;
108
+ if (threeCanvas.width != bufferSizeX || threeCanvas.height != bufferSizeY)
109
+ {
110
+ this.renderer.setPixelRatio(dpr);
111
+ this.renderer.setSize(mainCanvasSize.x, mainCanvasSize.y, false);
112
+ this.camera.aspect = mainCanvasSize.x / mainCanvasSize.y;
113
+ this.camera.updateProjectionMatrix();
114
+ }
115
+ if (threeCanvas.style.cssText != mainCanvas.style.cssText)
116
+ threeCanvas.style.cssText = mainCanvas.style.cssText;
117
+
118
+ if (this.cameraAlign2D)
119
+ this.alignCamera2D();
120
+ this.renderer.render(this.scene, this.camera);
121
+ }
122
+ }
123
+
124
+ ///////////////////////////////////////////////////////////////////////////////
125
+ /**
126
+ * ThreeJS Object - EngineObject that drives a three.js mesh
127
+ * - LittleJS physics moves the object and the mesh follows automatically
128
+ * - Destroying the object removes the mesh from the scene
129
+ * @extends EngineObject
130
+ * @memberof ThreeJS
131
+ */
132
+ class ThreeJSObject extends EngineObject
133
+ {
134
+ /** Create an engine object that drives a three.js mesh
135
+ * @param {Vector2} [pos] - World space position
136
+ * @param {Vector2} [size] - World space size
137
+ * @param {Object} [mesh] - The three.js object3d to drive
138
+ * @param {number} [z] - Mesh height above the 2D plane */
139
+ constructor(pos, size, mesh, z=0)
140
+ {
141
+ super(pos, size);
142
+ ASSERT(threeJS, 'ThreeJS plugin must be initialized first');
143
+
144
+ /** @property {Object} - The three.js object3d this object drives */
145
+ this.mesh = mesh;
146
+ /** @property {number} - Mesh height above the 2D plane */
147
+ this.z = z;
148
+ if (mesh)
149
+ {
150
+ threeJS.scene?.add(mesh); // no scene in headless mode
151
+ this.syncMesh();
152
+ }
153
+ }
154
+
155
+ /** Update the transform and sync the mesh to it, after the parent has placed a child, and while paused too
156
+ * @param {boolean} [updateChildren] - Also update the children's transforms */
157
+ updateTransforms(updateChildren=true)
158
+ {
159
+ super.updateTransforms(updateChildren);
160
+ this.syncMesh();
161
+ }
162
+
163
+ /** Copy this object's transform to the mesh */
164
+ syncMesh()
165
+ {
166
+ if (!this.mesh) return;
167
+ this.mesh.position.set(this.pos.x, this.pos.y, this.z);
168
+ this.mesh.rotation.z = -this.angle; // littlejs angles are clockwise
169
+ }
170
+
171
+ /** The mesh is this object's visual, the default 2D rendering is skipped */
172
+ render() {}
173
+
174
+ /** Destroy this object and remove its mesh from the scene
175
+ * @param {boolean} [immediate] */
176
+ destroy(immediate)
177
+ {
178
+ if (this.destroyed) return;
179
+ // note: frequently destroyed objects should also dispose geometry and material
180
+ this.mesh && threeJS.scene?.remove(this.mesh);
181
+ super.destroy(immediate);
182
+ }
183
+ }