littlejsengine 1.19.3 → 1.21.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.
- package/FAQ.md +841 -820
- package/README.md +29 -25
- package/dist/littlejs.d.ts +2857 -955
- package/dist/littlejs.esm.js +33428 -20995
- package/dist/littlejs.esm.min.js +4 -3
- package/dist/littlejs.js +33386 -20996
- package/dist/littlejs.min.js +2 -2
- package/dist/littlejs.release.js +27841 -20422
- package/package.json +10 -5
- package/plugins/audioEffects.js +28 -24
- package/plugins/box2d.js +2516 -2073
- package/plugins/drawUtilities.js +206 -31
- package/plugins/gltf.js +786 -0
- package/plugins/jsconfig.json +19 -0
- package/plugins/lightSystem.js +719 -332
- package/plugins/math3d.js +148 -27
- package/plugins/medalSystem.js +326 -280
- package/plugins/newgrounds.js +400 -199
- package/plugins/pathFinder.js +208 -175
- package/plugins/pluginExport.js +25 -0
- package/plugins/postProcess.js +96 -24
- package/plugins/render3d.js +2067 -1632
- package/plugins/render3dDebug.js +110 -0
- package/plugins/render3dEditor.js +1812 -0
- package/plugins/render3dExtras.js +1948 -0
- package/plugins/render3dLevel.js +189 -0
- package/plugins/render3dVoxels.js +514 -0
- package/plugins/sceneSystem.js +58 -0
- package/plugins/textureSheet.js +496 -458
- package/plugins/threejs.js +183 -163
- package/plugins/tweakables.js +411 -0
- package/plugins/tweenSystem.js +265 -145
- package/plugins/uiSystem.js +2024 -1687
- package/plugins/zzfxm.js +159 -159
- package/src/engine.js +378 -97
- package/src/engineAudio.js +231 -127
- package/src/engineBuild.mjs +292 -256
- package/src/engineDebug.js +967 -743
- package/src/engineDraw.js +391 -198
- package/src/engineEditor.js +2452 -0
- package/src/engineExport.js +18 -0
- package/src/engineInput.js +1466 -1293
- package/src/engineLogo.js +19 -0
- package/src/engineMath.js +1274 -1252
- package/src/engineObject.js +197 -82
- package/src/engineParticles.js +583 -532
- package/src/engineRelease.js +79 -45
- package/src/engineSettings.js +115 -29
- package/src/engineTileLayer.js +995 -741
- package/src/engineUtilities.js +19 -13
- package/src/engineWebGL.js +239 -82
- package/src/jsconfig.json +17 -13
- package/plugins/box2d.wasm.js +0 -630
- package/plugins/box2d.wasm.wasm +0 -0
package/plugins/threejs.js
CHANGED
|
@@ -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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
//
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
this.
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
this.
|
|
161
|
-
|
|
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
|
+
}
|