littlejsengine 1.24.3 → 1.25.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/CHANGELOG.md +36 -0
- package/EDITOR.md +2 -2
- package/FAQ.md +6 -0
- package/REFERENCE.md +84 -40
- package/dist/littlejs.d.ts +474 -219
- package/dist/littlejs.esm.js +2318 -1743
- package/dist/littlejs.esm.min.js +38 -24
- package/dist/littlejs.js +2316 -1743
- package/dist/littlejs.min.js +37 -23
- package/dist/littlejs.release.js +2313 -1786
- package/package.json +1 -1
- package/plugins/box2d.js +32 -23
- package/plugins/drawUtilities.js +374 -380
- package/plugins/gltf.js +325 -54
- package/plugins/lightSystem.js +2 -2
- package/plugins/math3d.js +1013 -1014
- package/plugins/newgrounds.js +1 -4
- package/plugins/particleEffects.js +3 -4
- package/plugins/pathFinder.js +52 -28
- package/plugins/pluginExport.js +2 -0
- package/plugins/postProcess.js +196 -65
- package/plugins/render3d.js +8 -6
- package/plugins/render3dEditor.js +3 -3
- package/plugins/render3dExtras.js +19 -2
- package/plugins/render3dLevel.js +15 -4
- package/plugins/tweenSystem.js +43 -38
- package/plugins/uiSystem.js +25 -20
- package/src/engine.js +9 -5
- package/src/engineAudio.js +10 -6
- package/src/engineDebug.js +3 -2
- package/src/engineDraw.js +9 -9
- package/src/engineEditor.js +75 -23
- package/src/engineInput.js +4 -7
- package/src/engineMath.js +3 -6
- package/src/engineObject.js +8 -9
- package/src/engineParticles.js +8 -7
- package/src/engineRelease.js +17 -10
- package/src/engineTileLayer.js +33 -14
- package/src/engineUtilities.js +15 -2
- package/src/engineWebGL.js +31 -9
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,42 @@ What changed in each release, newest first. Releases before 1.20.0 are on the
|
|
|
7
7
|
|
|
8
8
|
Nothing yet.
|
|
9
9
|
|
|
10
|
+
## 1.25.0 - 2026-10-04
|
|
11
|
+
|
|
12
|
+
### New Changes
|
|
13
|
+
|
|
14
|
+
- glTF skinned animation: a rigged character plays its animations, its mesh bent by its joints each frame, the four strongest of up to eight a vertex, on the CPU, so shadows, picking and custom shaders work with it; `object.play(name, loop, speed, blend)` cross-fades from the pose it is in over `blend` seconds, and `object.getJointMatrix(name)` gives a joint's place to hang a sword on a hand
|
|
15
|
+
- Tilt shift and depth of field post effects: `postProcessTiltShift(focus, size, blur)` keeps a band across the screen sharp, in 2D or 3D, and `postProcessDepthOfField(focus, range, blur)` keeps what is at a distance sharp, reading the 3D depth, with the edges of what is in focus kept crisp; the new 3D Focus Blur example focuses either with the mouse
|
|
16
|
+
- `postProcess.values`: a game's own values for the post process shader, set every frame, and any effect setting may name one in place of a number, to change it live without making the shader again, all but glow's size; the shader is made at the first render, so values set right after the plugin is made are in it
|
|
17
|
+
- The 3D Mesh example steps through a dropped model's animations with two buttons or the arrow keys, each cross-faded from the one before
|
|
18
|
+
|
|
19
|
+
### Breaking Changes
|
|
20
|
+
|
|
21
|
+
- The names deprecated in 1.20 are gone: `collideTiles` is `collideLevel`, the weld joint's `setSpringDampingRatio` and `getSpringDampingRatio` are `setDampingRatio` and `getDampingRatio` (the wheel joint keeps its own), and `NewgroundsPlugin.logView()`, which did nothing, is removed
|
|
22
|
+
- `drawNineSliceScreen` and `drawThreeSliceScreen` take only the order since 1.20, a color after the tile and then the border size; a number in the color's place asserts in a debug build
|
|
23
|
+
|
|
24
|
+
### Fixes
|
|
25
|
+
|
|
26
|
+
- REFERENCE says where the draw functions' parameter orders differ, and has a section on what functions give back: what each raycast returns, overlaps and collide helpers, not found, how a failed load is reported and how each kind of thing is ended; the FAQ lists the global names a game's own top level declarations clash with in a script build
|
|
27
|
+
- REFERENCE has a section on units and directions (angles in radians, clockwise in 2D, what is per frame and what is in seconds), says which vector and color methods give a copy, and names parameters as the code does; the Box2D shape methods, the vector helpers and a few others say what they return
|
|
28
|
+
- In a browser with no audio, a zzfx sound and the page hiding do nothing, where they threw
|
|
29
|
+
- A resume of the audio the browser refuses is caught, where it showed as an uncaught error in the console
|
|
30
|
+
- `debug`, `debugOverlay` and `debugWatermark` are `false` in a release build, as their types say, where they were 0
|
|
31
|
+
- `Box2dPinJoint`'s docs say its point defaults to objectA's position, which the d.ts showed as objectB's
|
|
32
|
+
- TypeScript: `tileLayersLoad` and `objectLayersLoad` take a `TiledMap`, `level3DLoad` a `Level3D`, the types' defaults and properties are records, a tool's `pos` and `ray` and `onPlayFrom`'s position are typed, `levelEditor.open` and `close` return nothing, `Sound` takes a zzfx array as numbers, and `fetchJSON` gives `any`, as JSON is, so its result goes straight into any of them
|
|
33
|
+
- A JSON, glTF or particle effect file that fails to read names the file, and says when it is a web page, as a dev server sends for a mistyped path, where it gave only "Unexpected token '<'"; an OBJ file with no faces warns, naming the file
|
|
34
|
+
- In a release build `levelEditor.edit2D` is there and changes nothing, where it was undefined and a call on it threw, so a game needs no guard around it
|
|
35
|
+
- A shader that fails to build on a device says why in the console in a release build too, where the screen stayed blank with no message: when the engine's own fails, the game draws with Canvas2D, a game's `Shader` that fails draws as if it had none, and a post process that fails leaves the frame as it is
|
|
36
|
+
- The post process depth is read at full precision, where phones with Mali and Adreno GPUs read it at 11 bits and the outline drew false lines on flat ground; the outline draws nothing with no depth texture, and nothing wrong at the sky of a camera with no far plane, where both gave NaN pixels; a value or a setting may not be named as a GLSL word or a name the shader uses, which was a compile error or a value silently hidden; a setting below .01 keeps its digits
|
|
37
|
+
- The 3D shader gives a mesh flattened to nothing on an axis no normal, where it was NaN, keeps the reflection's Fresnel term from NaN specks where a surface is seen head on, and treats fog that starts where it ends, and a shininess of 0, as defined
|
|
38
|
+
- `lineTest`, and the tile raycasts on it, from a whole x or y heading down the grid start in the cell they head into, where they tested the cell behind first and could hit at the start
|
|
39
|
+
- A particle whose `gravityScale` makes it rise lands on a ceiling, where its ground was the way the world's gravity points
|
|
40
|
+
- `readSaveData` takes only an object from storage, where a stored string was spread into its letters
|
|
41
|
+
- Faster where a game grows: path smoothing on a winding path checks lines from each corner, not each cell, a tween stopped among many no longer searches the list, a CSG cut leaves what is far from it alone, so a mesh cut many times does not grow slower to cut, and a paint stroke in the level editor draws the cells it changed, the whole layer only for a game's `onTile` or its own `onRedraw`
|
|
42
|
+
- Examples: the breakout tutorial runs at every step, the platformer's debug explosion is on B, not the dodge key, the Box2D example's smoke rises and its explosion falls off, the raycaster has no fisheye, the 3D Mesh viewer's normals leave a rigged model alone, positions are copied where they were shared, and a list of smaller fixes across the shorts
|
|
43
|
+
- An object whose child's update throws leaves the engine's list of children being updated as it was, where each throw kept them on it for good
|
|
44
|
+
- Level editor: a turned or mirrored stamp turns or mirrors its objects too, each object's rotation with it, a box placed from the corner that becomes its own, a polygon's points and a tile object's image mirrored
|
|
45
|
+
|
|
10
46
|
## 1.24.3 - 2026-10-03
|
|
11
47
|
|
|
12
48
|
### Fixes
|
package/EDITOR.md
CHANGED
|
@@ -22,8 +22,8 @@ is run by `test/editorCustom.test.mjs` straight from this file, so it works as w
|
|
|
22
22
|
and release are ended for you.
|
|
23
23
|
5. **A type is named by a string**, never by its class, because minified builds rename classes.
|
|
24
24
|
6. **Use `levelEditor.edit3D` and `levelEditor.edit2D` only inside what the editor calls**: a key's action, a
|
|
25
|
-
button's click, a tool's callbacks, `onUpdate`, `onDraw`. In a release build
|
|
26
|
-
|
|
25
|
+
button's click, a tool's callbacks, `onUpdate`, `onDraw`. In a release build none of those are ever called;
|
|
26
|
+
`edit2D` is there and changes nothing, and `edit3D` is undefined, as it is in a game without the 3D plugins.
|
|
27
27
|
7. **`levelEditor.is3D`** says which editor is in use, for a game that has both kinds of level.
|
|
28
28
|
|
|
29
29
|
## The hooks
|
package/FAQ.md
CHANGED
|
@@ -196,6 +196,12 @@ This will show you any errors that occur and allows stepping through code to hel
|
|
|
196
196
|
A common issue is the image data failing to load with a message like "The image element contains cross-origin data, and may not be loaded."
|
|
197
197
|
This is probably because the game was loaded directly without using a web server!
|
|
198
198
|
|
|
199
|
+
### Why does my game say a name "has already been declared"?
|
|
200
|
+
|
|
201
|
+
In a script tag build the engine's names are globals, so a top-level `let`, `const` or `class` in your game with the same name is an error, as is any declaration of a name the engine declares with `let` or `const`, like `time`. A `function` or `var` named like an engine function replaces it instead, which breaks the engine wherever it calls that function. The names most likely to clash are the short ones: `time`, `frame`, `paused`, `debug`, `gravity`, `tile`, `rand`, `percent`, `lerp`, `clamp`, `mod`, `sign`, `min`, `max`, `abs`, `floor`, `round`, `ceil`, `sin`, `cos`, `tan`, `PI`, the colors (`RED`, `GREEN`, `BLUE`, `GRAY`, `WHITE`, `BLACK` and the rest), `mousePos`, `cameraPos`, `medals`, `speak`, `vibrate`, `tweak`, the classes `Timer`, `Sound`, `Color`, `Light`, `Mesh`, `Particle` and `Shader`, and the plugin objects `box2d`, `render3D`, `uiSystem`, `postProcess` and `levelEditor`. [REFERENCE.md](REFERENCE.md) lists every name.
|
|
202
|
+
|
|
203
|
+
Rename yours, keep your game's state inside an object or class, or use the ES module build, where nothing is global and you import only the names you use (`import * as LJS from 'littlejsengine'` keeps them all under `LJS`).
|
|
204
|
+
|
|
199
205
|
### Do I need a local server to run LittleJS games, and how do I set one up?
|
|
200
206
|
|
|
201
207
|
Yes, this is a necessary step because web browsers just have protection from loading local files which includes images.
|
package/REFERENCE.md
CHANGED
|
@@ -82,6 +82,36 @@ let remaining = 36000;
|
|
|
82
82
|
})();
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
+
## Units and directions
|
|
86
|
+
- **Space:** world units, y up. Draws and objects take full sizes (a circle's diameter); only the math helpers and
|
|
87
|
+
lights take a radius, and their parameter says so
|
|
88
|
+
- **2D angles:** radians, clockwise: `EngineObject.angle`, `cameraAngle`, the `angle` of every draw and of a
|
|
89
|
+
`ParticleEmitter`; `Vector2.angle()` is 0 up
|
|
90
|
+
- **3D angles:** radians, `rotation3D` is pitch, yaw and roll, turning as three.js does, counter clockwise seen
|
|
91
|
+
down an axis; `Camera3D.fov` is radians; a 3D level file and the 3D editor's `setTransform` take degrees, as
|
|
92
|
+
does `ThreeJSPlugin.cameraFOV`
|
|
93
|
+
- **Per frame:** speeds and spins, `velocity`, `angleVelocity`, a particle's `speed` and `angleSpeed`, damping and
|
|
94
|
+
gravity, at the fixed 60 updates a second
|
|
95
|
+
- **Seconds:** `Timer`, `Tween`, `time`, a particle emitter's `emitTime` and `particleTime` and its `emitRate` (per
|
|
96
|
+
second) and `lifeTime`; a particle's `fadeRate` is a part of its life, not seconds
|
|
97
|
+
- **Milliseconds:** `gamepadVibrate`'s duration, `vibrate` patterns and `saveDataURL`'s `revokeTime`
|
|
98
|
+
|
|
99
|
+
## What functions give back
|
|
100
|
+
- **Raycasts:** where the ray hits, a Vector2: `tileCollisionRaycast`, `lineTest`; how far along the ray, a number:
|
|
101
|
+
`raycastBox`, `raycastSphere`, `raycastPlane`, `HeightMap.raycast`; a record of the hit: `VoxelMap.raycast` (a
|
|
102
|
+
`VoxelHit`), `render3D.pick` (`{object, distance}`), `box2d.raycast` (a `Box2dRaycastResult`); every object
|
|
103
|
+
hit, a list: `engineObjectsRaycast`; nothing hit is `undefined`, or an empty list
|
|
104
|
+
- **Overlaps:** `isOverlapping` and `isIntersecting` say whether, a boolean, as does a layer's `collisionTest`;
|
|
105
|
+
`tileCollisionTest` gives the layer hit; the collide helpers (`collideCircleBox`, `collideSphereBox` and the rest)
|
|
106
|
+
give the push that moves the first shape out, each `undefined` for none
|
|
107
|
+
- **Not found:** `undefined`, but `PathFinder.getNode` and `getNearestClearNode`, which give `null`
|
|
108
|
+
- **Loading:** an image that fails, from `engineInit` or `loadTexture`, and a `Sound` made from a file that fails,
|
|
109
|
+
warn in the console and the game goes on without them; `fetchJSON`, `loadGLTF`, `loadOBJ` and `Sound.loadSound`
|
|
110
|
+
reject with an error naming the file, for the game to catch
|
|
111
|
+
- **Ending things:** objects, particles, UI, Box2D objects and joints are ended with `destroy`; a `Mesh` or a
|
|
112
|
+
`GLTFModel` frees its GPU buffers with `dispose`, a `TextureInfo` its texture with `destroyWebGLTexture`; a
|
|
113
|
+
playing sound, a `Tween` and an animation `stop`
|
|
114
|
+
|
|
85
115
|
## LittleJS Utilities Classes and Functions
|
|
86
116
|
- General purpose math library
|
|
87
117
|
- Vector2 - Fast, simple, easy 2D vector class
|
|
@@ -116,7 +146,7 @@ lerpAngle(angleA, angleB, percent) // Linearly interpolates with wrap
|
|
|
116
146
|
smoothStep(percent) // Applies smoothstep function, percent clamped to 0-1
|
|
117
147
|
isPowerOfTwo(value) // Checks if the value is a power of two
|
|
118
148
|
nearestPowerOfTwo(value) // Smallest power of two not less than the value
|
|
119
|
-
isOverlapping(
|
|
149
|
+
isOverlapping(posA, sizeA, posB, sizeB) // Checks if bounding boxes overlap
|
|
120
150
|
isIntersecting(start, end, pos, size) // Checks if ray intersects box
|
|
121
151
|
// the collide helpers answer how far out, where isOverlapping answers whether; boxes are axis aligned and centered
|
|
122
152
|
// with a full size, and each returns undefined when the shapes are not touching
|
|
@@ -169,13 +199,13 @@ Vector2.length() // Get length
|
|
|
169
199
|
Vector2.lengthSquared() // Get length squared
|
|
170
200
|
Vector2.distance(v) // Get distance to vector
|
|
171
201
|
Vector2.distanceSquared(v) // Get distance to vector squared
|
|
172
|
-
Vector2.normalize(length=1) //
|
|
173
|
-
Vector2.clampLength(length=1) //
|
|
202
|
+
Vector2.normalize(length=1) // Copy of this vector at a length, its direction kept
|
|
203
|
+
Vector2.clampLength(length=1) // Copy of this vector no longer than a length
|
|
174
204
|
Vector2.dot(v) // Dot product with vector
|
|
175
205
|
Vector2.cross(v) // Cross product with vector
|
|
176
206
|
Vector2.reflect(normal, restitution=1) // Reflect off a surface normal
|
|
177
|
-
Vector2.floor() //
|
|
178
|
-
Vector2.round() //
|
|
207
|
+
Vector2.floor() // Copy with each component floored
|
|
208
|
+
Vector2.round() // Copy with each component rounded
|
|
179
209
|
Vector2.abs() // Get copy with absolute value components
|
|
180
210
|
Vector2.snap(grid) // Snap down to the grid, grid is steps per unit
|
|
181
211
|
Vector2.mod(divisor=1) // Get modulo of each component
|
|
@@ -188,6 +218,8 @@ Vector2.rotate(angle) // Rotate by angle
|
|
|
188
218
|
Vector2.setDirection(direction, length=1) // Set integer direction (0-3) and length
|
|
189
219
|
Vector2.direction() // Get integer direction (0-3)
|
|
190
220
|
Vector2.toString(digits=3) // Get string representation
|
|
221
|
+
// every Vector2 and Color method gives a new one and leaves it as it is, but set, setFrom, setAngle and
|
|
222
|
+
// setDirection, and Color's set, setFrom, setAlpha, setHSLA and setHex, which change it in place
|
|
191
223
|
|
|
192
224
|
// RGBA color object
|
|
193
225
|
Color(r=1, g=1, b=1, a=1) // Create an RGBA color
|
|
@@ -199,11 +231,11 @@ Color.subtract(c) // Subtract a color
|
|
|
199
231
|
Color.multiply(c) // Multiply by a color
|
|
200
232
|
Color.divide(c) // Divide by a color
|
|
201
233
|
Color.scale(scale, alphaScale=scale) // Scale by a float
|
|
202
|
-
Color.clamp() //
|
|
234
|
+
Color.clamp() // Copy with each component clamped to 0 to 1
|
|
203
235
|
Color.lerp(c, percent) // Interpolate between colors
|
|
204
236
|
Color.setHSLA(h=0, s=0, l=1, a=1) // Set the color from HSLA values
|
|
205
237
|
Color.HSLA() // Get the color in HSLA format
|
|
206
|
-
Color.mutate(amount=.05, alphaAmount=0) //
|
|
238
|
+
Color.mutate(amount=.05, alphaAmount=0) // Copy randomly diverged from this color
|
|
207
239
|
Color.setHex(hex) // Set this color from a hex code
|
|
208
240
|
Color.setAlpha(a=1) // Set the alpha of this color
|
|
209
241
|
Color.withAlpha(a=1) // Get a copy of this color with the alpha set
|
|
@@ -267,6 +299,14 @@ drawEllipseGradient(pos, size=(1,1), colorInner=WHITE, colorOuter=CLEAR_WHITE, a
|
|
|
267
299
|
drawCircleGradient(pos, size=1, colorInner=WHITE, colorOuter=CLEAR_WHITE)
|
|
268
300
|
drawCanvas2D(pos, size, angle=0, mirror=false, drawFunction, screenSpace=drawScreenSpace, context)
|
|
269
301
|
|
|
302
|
+
// Where the orders differ, worth a look when changing one draw for another:
|
|
303
|
+
// - angle is after the colors in drawTile, drawRect, drawEllipse and the gradients, after size in drawCanvas2D,
|
|
304
|
+
// after lineColor in drawRegularPoly and after pos in drawLine, drawLineList and drawPoly; drawCircle has none
|
|
305
|
+
// - a line's width is before its color in drawLine and drawLineList, the outline's after the fill color, with
|
|
306
|
+
// lineColor, in drawPoly, drawRegularPoly, drawEllipse, drawCircle and the text
|
|
307
|
+
// - pos comes first in most draws, but is an offset near the end in drawLine, drawLineList and drawPoly
|
|
308
|
+
// - drawText and drawTextScreen draw with Canvas2D and take no useWebGL or screenSpace
|
|
309
|
+
|
|
270
310
|
// Text functions
|
|
271
311
|
drawText(text, pos, size=1, color=WHITE, lineWidth=0, lineColor=BLACK, textAlign='center', font, fontStyle, maxWidth, angle=0)
|
|
272
312
|
drawTextScreen(text, pos, size, color=WHITE, lineWidth=0, lineColor=BLACK, textAlign='center', font, fontStyle, maxWidth, angle=0)
|
|
@@ -487,12 +527,12 @@ AudioFilter.node, AudioReverb.node, ... // Each effect's wrapped Web A
|
|
|
487
527
|
|
|
488
528
|
```javascript
|
|
489
529
|
// Keyboard, keys are KeyboardEvent.code names like 'KeyW', 'Space' or 'ArrowUp', not characters
|
|
490
|
-
keyIsDown(key)
|
|
491
|
-
keyWasPressed(key)
|
|
492
|
-
keyWasReleased(key)
|
|
530
|
+
keyIsDown(key, device=0) // Is key down? device 0 is the keyboard and mouse, 1 on the gamepads
|
|
531
|
+
keyWasPressed(key, device=0) // Was key pressed this frame?
|
|
532
|
+
keyWasReleased(key, device=0) // Was key released this frame?
|
|
493
533
|
keyDirection(up, down, left, right) // Get input vector from arrow keys or wasd
|
|
494
534
|
inputClear() // Clear all input state
|
|
495
|
-
inputClearKey(key)
|
|
535
|
+
inputClearKey(key, device=0, clearDown=true, clearPressed=true, clearReleased=true) // Clear input state for a key
|
|
496
536
|
|
|
497
537
|
// Mouse / Touch
|
|
498
538
|
mousePos // World space mouse position
|
|
@@ -713,9 +753,9 @@ TileCollisionLayer.collisionTest(pos, size=(0,0), object) // Like tileCollisionT
|
|
|
713
753
|
TileCollisionLayer.collisionRaycast(posStart, posEnd, object, normal) // Like tileCollisionRaycast for this layer only
|
|
714
754
|
TileCollisionLayer.isSolid = true // Solid layers block objects and particles, the solidOnly tests
|
|
715
755
|
// skip the others
|
|
716
|
-
tileCollisionGetData(pos)
|
|
756
|
+
tileCollisionGetData(pos, solidOnly=true) // Get tile collision data at pos
|
|
717
757
|
tileCollisionTest(pos, size=(0,0), object) // Check if collision should occur
|
|
718
|
-
tileCollisionRaycast(posStart, posEnd,
|
|
758
|
+
tileCollisionRaycast(posStart, posEnd, callbackObject, normal, solidOnly=true) // Where the ray meets the first tile hit,
|
|
719
759
|
// or undefined; a normal vec2 passed in is set to the surface's
|
|
720
760
|
tileCollisionLayers // List of all tile collision layers
|
|
721
761
|
tileLayersLoad(tileMapData, tileInfo=tile(), renderOrder=0, collisionLayer, draw=true) // collisionLayer is the index
|
|
@@ -783,7 +823,7 @@ particleEffectsBuiltIn // the built-in names: fire, torch, smok
|
|
|
783
823
|
// itself, a continuous one goes until destroyed
|
|
784
824
|
'fire' // hue .08, continuous
|
|
785
825
|
'torch' // hue .09, continuous
|
|
786
|
-
'smoke' // no hue,
|
|
826
|
+
'smoke' // no hue, gray, continuous
|
|
787
827
|
'steam' // no hue, white, continuous
|
|
788
828
|
'explosion' // hue .12, one-shot
|
|
789
829
|
'sparks' // hue .17, continuous
|
|
@@ -806,9 +846,10 @@ particleEffectsBuiltIn // the built-in names: fire, torch, smok
|
|
|
806
846
|
'confetti' // hue 0 and .6, mixed, one-shot
|
|
807
847
|
'splash' // hue .58, one-shot
|
|
808
848
|
particleEffectApply(emitter, effect) // set a live 2D emitter to an effect
|
|
809
|
-
particleEffectApply3D(
|
|
810
|
-
particleEffectFromEmitter(emitter)
|
|
811
|
-
particleEffectsAddBehavior(name, update, update3D) // add a behavior effects
|
|
849
|
+
particleEffectApply3D(emitter, effect) // the same for a ParticleEmitter3D, its particles, place and scale kept
|
|
850
|
+
particleEffectFromEmitter(emitter, name='Effect') // a 2D emitter's settings as an effect, to save or build in 3D
|
|
851
|
+
particleEffectsAddBehavior(name, update, update3D, min=-2, max=2, value=1, description='') // add a behavior effects
|
|
852
|
+
// can name, with 2D and 3D pushes; min, max and value for the designer
|
|
812
853
|
particleEffectsAdd(effects) // add effects to play by name, one of the same name replaces it
|
|
813
854
|
particleEffectsGet(name) // an effect's data, any case, to change or build by hand
|
|
814
855
|
await particleEffectsLoad(url) // load the file the particle designer's Save Library wrote, and add its effects
|
|
@@ -973,7 +1014,7 @@ uiSystem.drawSlice(slice, pos, size, color=WHITE) // Draw a TileSlice to the UI
|
|
|
973
1014
|
uiSystem.nativeHeight // If set, UI coords are normalized to this height
|
|
974
1015
|
uiSystem.destroyObjects() // Remove all UI elements
|
|
975
1016
|
uiSystem.isMouseOverUI() // True if the mouse is over a visible hoverable UI object, or a confirm dialog is open
|
|
976
|
-
uiSetDebug(
|
|
1017
|
+
uiSetDebug(debugMode) // Toggle uiDebug rendering of widget bounds
|
|
977
1018
|
|
|
978
1019
|
// Confirm dialog
|
|
979
1020
|
uiSystem.showConfirmDialog(text='Are you sure?', yes, no, size, exitKey='Escape') // the exit key or gamepad B answers no, the title and buttons scale with size
|
|
@@ -1129,6 +1170,16 @@ postProcessChromatic(strength=.005) // red and blue split apart toward
|
|
|
1129
1170
|
postProcessGlow(threshold=.6, strength=1, size=6) // the bloom as a piece
|
|
1130
1171
|
postProcessOutline(color=BLACK, thickness=1, threshold=.02) // lines where the 3D depth jumps, needs
|
|
1131
1172
|
// render3D.depthTexture
|
|
1173
|
+
postProcessTiltShift(focus=.5, size=.25, blur=8) // a sharp band across the screen at focus, 0 bottom to 1 top,
|
|
1174
|
+
// size its height, blurred above and below, 2D or 3D
|
|
1175
|
+
postProcessDepthOfField(focus=10, range=4, blur=8) // sharp at focus world units from the camera, range deep,
|
|
1176
|
+
// blurred nearer and farther; needs render3D.depthTexture
|
|
1177
|
+
postProcess.values = {focus: .5} // the game's own values for the shader, a uniform each, set every
|
|
1178
|
+
// frame; any effect setting but glow's size, which sets its sample
|
|
1179
|
+
// count, may be such a name, to change it live; set them after the
|
|
1180
|
+
// plugin is made, as the shader is made at the first render;
|
|
1181
|
+
// not named _x, iX, gl_x, c, uv or p, which the shader uses:
|
|
1182
|
+
new PostProcessPlugin(postProcessEffects(postProcessTiltShift('focus'))); postProcess.values.focus = .6; // live
|
|
1132
1183
|
```
|
|
1133
1184
|
|
|
1134
1185
|
## LittleJS 3D Math
|
|
@@ -1164,7 +1215,7 @@ m.invert() m.transpose() // in place, return self
|
|
|
1164
1215
|
m.copy() m.transformPoint(v) m.transformDirection(v) m.getTranslation() // or v.transform(m), v.transformDirection(m)
|
|
1165
1216
|
m.getScale() m.getRotation() // the scale and the vec3(pitch, yaw, roll) back out of a transform, a mirror is a negative x
|
|
1166
1217
|
m.determinant() // of the rotation and scale part: negative when it mirrors, 0 when it flattens
|
|
1167
|
-
buildMatrix(pos, rotation, scale,
|
|
1218
|
+
buildMatrix(pos, rotation, scale, matrix) // translate * rotate * scale, any arg optional; matrix is written into
|
|
1168
1219
|
// instead of a new matrix, for a loop that builds many each frame
|
|
1169
1220
|
|
|
1170
1221
|
// Collision - boxes are centered with full size, upright unless given a rotation, an Euler vec3 like rotation3D;
|
|
@@ -1687,8 +1738,9 @@ await loadOBJ(url, smooth) // fetch then parse, in an async gameInit; chain .cen
|
|
|
1687
1738
|
// units
|
|
1688
1739
|
|
|
1689
1740
|
// glTF models - the glTF plugin, .gltf with its files beside it or .glb in one file; meshes with their node placement,
|
|
1690
|
-
// vertex colors, material colors and base color textures,
|
|
1691
|
-
// Draco or meshopt compressed geometry, which throws
|
|
1741
|
+
// vertex colors, material colors and base color textures, node animations and skinned characters, four joints a
|
|
1742
|
+
// vertex, bent on the CPU each frame; no morph targets, and no Draco or meshopt compressed geometry, which throws
|
|
1743
|
+
// saying so
|
|
1692
1744
|
const model = await loadGLTF(url) // a GLTFModel, in an async gameInit; or await parseGLTF(data, baseUrl, files) on
|
|
1693
1745
|
// bytes or JSON you already have; files, a Map of the .bin and image files a
|
|
1694
1746
|
// .gltf names by their paths, like the files of a drop, in place of fetching,
|
|
@@ -1709,15 +1761,20 @@ model.createObject(pos3D) // a GLTFObject, an EngineObject3D with a c
|
|
|
1709
1761
|
// emissive 1 for an unlit one; move and turn the root and the parts follow
|
|
1710
1762
|
model.animations // one GLTFAnimation each: name, duration in seconds, and the channels that
|
|
1711
1763
|
// move, turn and scale nodes; model.getAnimation(nameOrNumber) finds one
|
|
1712
|
-
object.play(animation=0, loop=true, speed=1) // play one on a GLTFObject by name or number, its parts move
|
|
1713
|
-
// speed below 0 plays it backward,
|
|
1764
|
+
object.play(animation=0, loop=true, speed=1, blend=0) // play one on a GLTFObject by name or number, its parts move
|
|
1765
|
+
// and a skinned mesh bends with it; speed below 0 plays it backward, one that
|
|
1766
|
+
// does not loop holds its end, and blend is seconds to cross-fade from the pose
|
|
1767
|
+
// it is in, the animation it leaves going on through the fade
|
|
1768
|
+
object.getJointMatrix(name) // a node's world Matrix4 as posed now, by its name in the file, to hang a sword
|
|
1769
|
+
// on a hand; undefined for a name the model does not have
|
|
1714
1770
|
object.stop() // hold the pose where it is; object.setAnimationTime(t) poses it at a time
|
|
1715
1771
|
object.animation .animationTime .animationSpeed .animationLoop .animationPlaying
|
|
1716
1772
|
model.getPose(animation, time) // one Matrix4 per part, how far it moved from its resting place
|
|
1717
1773
|
model.dispose() // free the part meshes, the combined mesh and the textures of a model that
|
|
1718
1774
|
// is done with; destroy the objects createObject made first
|
|
1719
1775
|
// colors come in converted from glTF's linear values, a NEAREST sampler makes a part pixelated, sparse accessors
|
|
1720
|
-
// are read, and object.parts is what an animation poses
|
|
1776
|
+
// are read, and object.parts is what an animation poses; a skinned part's object bends a mesh of its own, so
|
|
1777
|
+
// characters of one model hold their own poses, and part.skin is what bends it
|
|
1721
1778
|
model.center().fit(size) // move the model's bounds onto the origin and scale its largest extent to
|
|
1722
1779
|
// size, every part together, like Mesh.center and fit; getBounds and
|
|
1723
1780
|
// transform(matrix) as well
|
|
@@ -1840,8 +1897,8 @@ new THREE.Raycaster() // render3D.screenToRay, pick and engi
|
|
|
1840
1897
|
OBJLoader // loadOBJ(url) or parseOBJ(text)
|
|
1841
1898
|
GLTFLoader // loadGLTF(url): model.createObject(pos) is the scene as objects, model.mesh
|
|
1842
1899
|
// is everything as one Mesh
|
|
1843
|
-
mixer.clipAction(clip).play() // object.play(name) on the object createObject made,
|
|
1844
|
-
|
|
1900
|
+
mixer.clipAction(clip).play() // object.play(name) on the object createObject made, skinned characters
|
|
1901
|
+
crossFadeTo(next, seconds) // object.play(next, true, 1, seconds); bone.getWorldPosition: getJointMatrix
|
|
1845
1902
|
EffectComposer and UnrealBloomPass // postProcessBloom()
|
|
1846
1903
|
renderer.render(scene, camera) // nothing to do, the engine draws every frame and handles resizing
|
|
1847
1904
|
position.setUsage(THREE.DynamicDrawUsage) // mesh.dynamicDraw = true once, then mesh.dirty = true when the points
|
|
@@ -2301,7 +2358,7 @@ debugPoint(pos, color, time, angle) // Draw debug point
|
|
|
2301
2358
|
debugLine(posA, posB, color, width=.1, time) // Draw debug line
|
|
2302
2359
|
debugPoly(pos, points, color=WHITE, time=0, angle=0, fill) // Draw debug polygon
|
|
2303
2360
|
debugText(text, pos, size=1, color=WHITE, time=0, angle=0) // Draw debug text
|
|
2304
|
-
debugOverlap(
|
|
2361
|
+
debugOverlap(posA, sizeA, posB, sizeB, color) // Draw a debug overlap between two boxes
|
|
2305
2362
|
// each debug draw also takes screenSpace as its last parameter, defaulting to drawScreenSpace; debugText takes a
|
|
2306
2363
|
// font before it
|
|
2307
2364
|
debugClear() // Clear all debug primitives
|
|
@@ -2327,19 +2384,6 @@ debugTweakables = false // Is the tweakables panel shown? setDebugTweakables(sho
|
|
|
2327
2384
|
debugWatermark // Should watermark with FPS appear in debug mode?
|
|
2328
2385
|
```
|
|
2329
2386
|
|
|
2330
|
-
## Deprecated
|
|
2331
|
-
|
|
2332
|
-
Old names and argument orders that still work, marked `@deprecated` in the types; use the new ones, the old are
|
|
2333
|
-
kept until 1.25 at least.
|
|
2334
|
-
|
|
2335
|
-
```javascript
|
|
2336
|
-
obj.collideTiles // since 1.20, use obj.collideLevel, the same flag
|
|
2337
|
-
weldJoint.setSpringDampingRatio(ratio) // since 1.20, use setDampingRatio, and getDampingRatio for the getter
|
|
2338
|
-
newgrounds.logView() // since 1.20, does nothing, the view is logged when the plugin starts
|
|
2339
|
-
drawNineSliceScreen(pos, size, startTile, borderSize, extraSpace, angle) // since 1.20, the order is now
|
|
2340
|
-
drawThreeSliceScreen(pos, size, startTile, borderSize, extraSpace, angle) // (pos, size, startTile, color, ...)
|
|
2341
|
-
```
|
|
2342
|
-
|
|
2343
2387
|
[LittleJS Engine](https://github.com/KilledByAPixel/LittleJS) Copyright 2021 Frank Force
|
|
2344
2388
|
|
|
2345
2389
|

|