littlejsengine 1.24.3 → 1.26.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 +123 -0
- package/EDITOR.md +2 -2
- package/FAQ.md +55 -11
- package/README.md +6 -2
- package/REFERENCE.md +203 -57
- package/dist/littlejs.d.ts +933 -313
- package/dist/littlejs.esm.js +5143 -2419
- package/dist/littlejs.esm.min.js +38 -24
- package/dist/littlejs.js +5132 -2416
- package/dist/littlejs.min.js +37 -23
- package/dist/littlejs.release.js +4905 -2232
- package/package.json +4 -4
- package/plugins/box2d.js +141 -56
- package/plugins/drawUtilities.js +374 -380
- package/plugins/gltf.js +383 -60
- package/plugins/lightSystem.js +412 -30
- package/plugins/math3d.js +1015 -1014
- package/plugins/medalSystem.js +19 -7
- package/plugins/newgrounds.js +5 -6
- package/plugins/parallax.js +1 -0
- package/plugins/particleEffects.js +47 -14
- package/plugins/pathFinder.js +60 -38
- package/plugins/pluginExport.js +11 -0
- package/plugins/postProcess.js +200 -67
- package/plugins/render3d.js +493 -2391
- package/plugins/render3dDebug.js +5 -8
- package/plugins/render3dEditor.js +84 -9
- package/plugins/render3dExtras.js +122 -33
- package/plugins/render3dLevel.js +67 -8
- package/plugins/render3dMesh.js +1158 -0
- package/plugins/render3dObject.js +1451 -0
- package/plugins/render3dVoxels.js +15 -3
- package/plugins/textureSheet.js +9 -8
- package/plugins/threejs.js +1 -1
- package/plugins/tweenSystem.js +117 -87
- package/plugins/uiSystem.js +62 -28
- package/plugins/wavedash.js +229 -0
- package/src/engine.js +192 -40
- package/src/engineAudio.js +47 -27
- package/src/engineBuild.mjs +6 -1
- package/src/engineDebug.js +23 -162
- package/src/engineDraw.js +148 -43
- package/src/engineEditor.js +153 -40
- package/src/engineExport.js +0 -3
- package/src/engineInput.js +31 -25
- package/src/engineMath.js +38 -20
- package/src/engineObject.js +68 -50
- package/src/engineParticles.js +66 -18
- package/src/engineRelease.js +18 -15
- package/src/engineSettings.js +48 -9
- package/src/engineTileLayer.js +44 -18
- package/src/engineUtilities.js +56 -11
- package/src/engineWebGL.js +68 -22
package/REFERENCE.md
CHANGED
|
@@ -82,6 +82,40 @@ 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
|
+
- **Materials:** `roughness`, `reflectivity` and `specular` run 0 to 1, `shininess` 1 up, about 10,000 a mirror (a roughness of 0 sets it far higher), and
|
|
98
|
+
`emissive` from 0 up
|
|
99
|
+
- **Milliseconds:** `gamepadVibrate`'s duration, `vibrate` patterns and `saveDataURL`'s `revokeTime`
|
|
100
|
+
- **Limits:** the GPU draws with 32-bit floats: keep the world within about ±10,000 units of the origin, and a
|
|
101
|
+
shader's `iTime` gets coarse in a game left running for days; the FAQ says more
|
|
102
|
+
|
|
103
|
+
## What functions give back
|
|
104
|
+
- **Raycasts:** where the ray hits, a Vector2: `tileCollisionRaycast`, `lineTest`; how far along the ray, a number:
|
|
105
|
+
`raycastBox`, `raycastSphere`, `raycastPlane`, `HeightMap.raycast`; a record of the hit: `VoxelMap.raycast` (a
|
|
106
|
+
`VoxelHit`), `render3D.pick` (`{object, distance}`), `box2d.raycast` (a `Box2dRaycastResult`); every object
|
|
107
|
+
hit, a list: `engineObjectsRaycast`; nothing hit is `undefined`, or an empty list
|
|
108
|
+
- **Overlaps:** `isOverlapping` and `isIntersecting` say whether, a boolean, as does a layer's `collisionTest`;
|
|
109
|
+
`tileCollisionTest` gives the layer hit; the collide helpers (`collideCircleBox`, `collideSphereBox` and the rest)
|
|
110
|
+
give the push that moves the first shape out, each `undefined` for none
|
|
111
|
+
- **Not found:** `undefined`, but `PathFinder.getNode` and `getNearestClearNode`, which give `null`
|
|
112
|
+
- **Loading:** an image that fails, from `engineInit` or `loadTexture`, and a `Sound` made from a file that fails,
|
|
113
|
+
warn in the console and the game goes on without them; `fetchJSON`, `loadGLTF`, `loadOBJ` and `Sound.loadSound`
|
|
114
|
+
reject with an error naming the file, for the game to catch
|
|
115
|
+
- **Ending things:** objects, particles, UI, Box2D objects and joints are ended with `destroy`; a `Mesh` or a
|
|
116
|
+
`GLTFModel` frees its GPU buffers with `dispose`, a `TextureInfo` its texture with `destroyWebGLTexture`; a
|
|
117
|
+
playing sound, a `Tween` and an animation `stop`
|
|
118
|
+
|
|
85
119
|
## LittleJS Utilities Classes and Functions
|
|
86
120
|
- General purpose math library
|
|
87
121
|
- Vector2 - Fast, simple, easy 2D vector class
|
|
@@ -116,7 +150,7 @@ lerpAngle(angleA, angleB, percent) // Linearly interpolates with wrap
|
|
|
116
150
|
smoothStep(percent) // Applies smoothstep function, percent clamped to 0-1
|
|
117
151
|
isPowerOfTwo(value) // Checks if the value is a power of two
|
|
118
152
|
nearestPowerOfTwo(value) // Smallest power of two not less than the value
|
|
119
|
-
isOverlapping(
|
|
153
|
+
isOverlapping(posA, sizeA, posB, sizeB) // Checks if bounding boxes overlap
|
|
120
154
|
isIntersecting(start, end, pos, size) // Checks if ray intersects box
|
|
121
155
|
// the collide helpers answer how far out, where isOverlapping answers whether; boxes are axis aligned and centered
|
|
122
156
|
// with a full size, and each returns undefined when the shapes are not touching
|
|
@@ -169,13 +203,13 @@ Vector2.length() // Get length
|
|
|
169
203
|
Vector2.lengthSquared() // Get length squared
|
|
170
204
|
Vector2.distance(v) // Get distance to vector
|
|
171
205
|
Vector2.distanceSquared(v) // Get distance to vector squared
|
|
172
|
-
Vector2.normalize(length=1) //
|
|
173
|
-
Vector2.clampLength(length=1) //
|
|
206
|
+
Vector2.normalize(length=1) // Copy of this vector at a length, its direction kept
|
|
207
|
+
Vector2.clampLength(length=1) // Copy of this vector no longer than a length
|
|
174
208
|
Vector2.dot(v) // Dot product with vector
|
|
175
209
|
Vector2.cross(v) // Cross product with vector
|
|
176
210
|
Vector2.reflect(normal, restitution=1) // Reflect off a surface normal
|
|
177
|
-
Vector2.floor() //
|
|
178
|
-
Vector2.round() //
|
|
211
|
+
Vector2.floor() // Copy with each component floored
|
|
212
|
+
Vector2.round() // Copy with each component rounded
|
|
179
213
|
Vector2.abs() // Get copy with absolute value components
|
|
180
214
|
Vector2.snap(grid) // Snap down to the grid, grid is steps per unit
|
|
181
215
|
Vector2.mod(divisor=1) // Get modulo of each component
|
|
@@ -188,6 +222,8 @@ Vector2.rotate(angle) // Rotate by angle
|
|
|
188
222
|
Vector2.setDirection(direction, length=1) // Set integer direction (0-3) and length
|
|
189
223
|
Vector2.direction() // Get integer direction (0-3)
|
|
190
224
|
Vector2.toString(digits=3) // Get string representation
|
|
225
|
+
// every Vector2 and Color method gives a new one and leaves it as it is, but set, setFrom, setAngle and
|
|
226
|
+
// setDirection, and Color's set, setFrom, setAlpha, setHSLA and setHex, which change it in place
|
|
191
227
|
|
|
192
228
|
// RGBA color object
|
|
193
229
|
Color(r=1, g=1, b=1, a=1) // Create an RGBA color
|
|
@@ -199,11 +235,11 @@ Color.subtract(c) // Subtract a color
|
|
|
199
235
|
Color.multiply(c) // Multiply by a color
|
|
200
236
|
Color.divide(c) // Divide by a color
|
|
201
237
|
Color.scale(scale, alphaScale=scale) // Scale by a float
|
|
202
|
-
Color.clamp() //
|
|
238
|
+
Color.clamp() // Copy with each component clamped to 0 to 1
|
|
203
239
|
Color.lerp(c, percent) // Interpolate between colors
|
|
204
240
|
Color.setHSLA(h=0, s=0, l=1, a=1) // Set the color from HSLA values
|
|
205
241
|
Color.HSLA() // Get the color in HSLA format
|
|
206
|
-
Color.mutate(amount=.05, alphaAmount=0) //
|
|
242
|
+
Color.mutate(amount=.05, alphaAmount=0) // Copy randomly diverged from this color
|
|
207
243
|
Color.setHex(hex) // Set this color from a hex code
|
|
208
244
|
Color.setAlpha(a=1) // Set the alpha of this color
|
|
209
245
|
Color.withAlpha(a=1) // Get a copy of this color with the alpha set
|
|
@@ -267,6 +303,14 @@ drawEllipseGradient(pos, size=(1,1), colorInner=WHITE, colorOuter=CLEAR_WHITE, a
|
|
|
267
303
|
drawCircleGradient(pos, size=1, colorInner=WHITE, colorOuter=CLEAR_WHITE)
|
|
268
304
|
drawCanvas2D(pos, size, angle=0, mirror=false, drawFunction, screenSpace=drawScreenSpace, context)
|
|
269
305
|
|
|
306
|
+
// Where the orders differ, worth a look when changing one draw for another:
|
|
307
|
+
// - angle is after the colors in drawTile, drawRect, drawEllipse and the gradients, after size in drawCanvas2D,
|
|
308
|
+
// after lineColor in drawRegularPoly and after pos in drawLine, drawLineList and drawPoly; drawCircle has none
|
|
309
|
+
// - a line's width is before its color in drawLine and drawLineList, the outline's after the fill color, with
|
|
310
|
+
// lineColor, in drawPoly, drawRegularPoly, drawEllipse, drawCircle and the text
|
|
311
|
+
// - pos comes first in most draws, but is an offset near the end in drawLine, drawLineList and drawPoly
|
|
312
|
+
// - drawText and drawTextScreen draw with Canvas2D and take no useWebGL or screenSpace
|
|
313
|
+
|
|
270
314
|
// Text functions
|
|
271
315
|
drawText(text, pos, size=1, color=WHITE, lineWidth=0, lineColor=BLACK, textAlign='center', font, fontStyle, maxWidth, angle=0)
|
|
272
316
|
drawTextScreen(text, pos, size, color=WHITE, lineWidth=0, lineColor=BLACK, textAlign='center', font, fontStyle, maxWidth, angle=0)
|
|
@@ -283,6 +327,9 @@ new Shader(fragmentCode) // fragmentCode defines void mainImage(out vec
|
|
|
283
327
|
// style; it gives the surface color, then the object's color and additive color
|
|
284
328
|
// apply in 2D, and the lighting, shadows and fog in 3D
|
|
285
329
|
obj.shader = shader // any EngineObject or EngineObject3D; draws that share a Shader share a batch
|
|
330
|
+
shader.dispose() // frees its programs and takes it off the engine's list, which keeps every Shader
|
|
331
|
+
// for a lost context; for one made each time a scene starts; drawn again it
|
|
332
|
+
// compiles again, so let go of only one nothing draws with
|
|
286
333
|
// names in the snippet: iChannel0 the texture, iTime, iResolution, localUV 0 to 1 across the sprite or the mesh uv,
|
|
287
334
|
// premultipliedTexture true for a render target or a smooth image (tilesPixelated false), whose rgb and alpha
|
|
288
335
|
// change together;
|
|
@@ -407,7 +454,9 @@ glDraw(x, y, sizeX, sizeY, angle=0, uv0X, uv0Y, uv1X, uv1Y, rgba=-1, rgbaAdditiv
|
|
|
407
454
|
```javascript
|
|
408
455
|
// Sound Object
|
|
409
456
|
Sound(zzfxSound, randomness, range, taper, onloadCallback) // Create a zzfx sound
|
|
410
|
-
|
|
457
|
+
zzfx(...zzfxSound) // Generate and play a zzfx sound at once, no Sound kept
|
|
458
|
+
Sound(filename, randomness, range, taper, onloadCallback) // Load a wave, mp3, or ogg; onloadCallback(sound) is
|
|
459
|
+
// called once it loads or fails to, isLoaded says which
|
|
411
460
|
Sound.play(pos, volume=1, pitch=1, randomnessScale=1, loop=false, paused=false) // Play a sound, returns SoundInstance
|
|
412
461
|
Sound.playLoop(pos, volume=1, pitch=1, randomnessScale=1, paused=false) // Play on a loop, like play with loop on
|
|
413
462
|
Sound.playMusic(volume=1, loop=true, paused=false) // Play as music with looping
|
|
@@ -440,7 +489,8 @@ speakStop() // Stop all queued speech
|
|
|
440
489
|
getNoteFrequency(semitoneOffset, rootFrequency=220) // Get frequency for musical notes
|
|
441
490
|
|
|
442
491
|
// Audio settings
|
|
443
|
-
soundEnable = true // Should sound be enabled?
|
|
492
|
+
soundEnable = true // Should sound be enabled? set it before sounds are made, setSoundEnable(false)
|
|
493
|
+
// before they are, setSoundVolume(0) to mute while the game runs
|
|
444
494
|
soundIgnoreSilentSwitch = false // play with an iPhone's silent switch on, as media, pausing the player's music;
|
|
445
495
|
// off, the switch mutes the game; setSoundIgnoreSilentSwitch(true)
|
|
446
496
|
soundVolume = .3 // Volume scale to apply to all sound
|
|
@@ -487,12 +537,12 @@ AudioFilter.node, AudioReverb.node, ... // Each effect's wrapped Web A
|
|
|
487
537
|
|
|
488
538
|
```javascript
|
|
489
539
|
// Keyboard, keys are KeyboardEvent.code names like 'KeyW', 'Space' or 'ArrowUp', not characters
|
|
490
|
-
keyIsDown(key)
|
|
491
|
-
keyWasPressed(key)
|
|
492
|
-
keyWasReleased(key)
|
|
540
|
+
keyIsDown(key, device=0) // Is key down? device 0 is the keyboard and mouse, 1 on the gamepads
|
|
541
|
+
keyWasPressed(key, device=0) // Was key pressed this frame?
|
|
542
|
+
keyWasReleased(key, device=0) // Was key released this frame?
|
|
493
543
|
keyDirection(up, down, left, right) // Get input vector from arrow keys or wasd
|
|
494
544
|
inputClear() // Clear all input state
|
|
495
|
-
inputClearKey(key)
|
|
545
|
+
inputClearKey(key, device=0, clearDown=true, clearPressed=true, clearReleased=true) // Clear input state for a key
|
|
496
546
|
|
|
497
547
|
// Mouse / Touch
|
|
498
548
|
mousePos // World space mouse position
|
|
@@ -638,7 +688,7 @@ EngineObject.clampSpeed // Hold each axis of velocity to objectMaxSpeed while
|
|
|
638
688
|
EngineObject.parent / children // Set by addChild, a child is placed by its parent and sits out solid collision
|
|
639
689
|
|
|
640
690
|
// Engine Object settings
|
|
641
|
-
enablePhysicsSolver = true // Enable collisions, between objects and with tiles?
|
|
691
|
+
enablePhysicsSolver = true // Enable collisions, between objects and with tiles, and in 3D with solids and the level?
|
|
642
692
|
objectDefaultMass = 1 // Default object mass for collisions
|
|
643
693
|
objectDefaultDamping = 1 // Fraction of velocity kept each frame (1 keeps all)
|
|
644
694
|
objectDefaultAngleDamping = 1 // Fraction of angular velocity kept each frame (1 keeps all)
|
|
@@ -713,9 +763,9 @@ TileCollisionLayer.collisionTest(pos, size=(0,0), object) // Like tileCollisionT
|
|
|
713
763
|
TileCollisionLayer.collisionRaycast(posStart, posEnd, object, normal) // Like tileCollisionRaycast for this layer only
|
|
714
764
|
TileCollisionLayer.isSolid = true // Solid layers block objects and particles, the solidOnly tests
|
|
715
765
|
// skip the others
|
|
716
|
-
tileCollisionGetData(pos)
|
|
766
|
+
tileCollisionGetData(pos, solidOnly=true) // Get tile collision data at pos
|
|
717
767
|
tileCollisionTest(pos, size=(0,0), object) // Check if collision should occur
|
|
718
|
-
tileCollisionRaycast(posStart, posEnd,
|
|
768
|
+
tileCollisionRaycast(posStart, posEnd, callbackObject, normal, solidOnly=true) // Where the ray meets the first tile hit,
|
|
719
769
|
// or undefined; a normal vec2 passed in is set to the surface's
|
|
720
770
|
tileCollisionLayers // List of all tile collision layers
|
|
721
771
|
tileLayersLoad(tileMapData, tileInfo=tile(), renderOrder=0, collisionLayer, draw=true) // collisionLayer is the index
|
|
@@ -783,7 +833,7 @@ particleEffectsBuiltIn // the built-in names: fire, torch, smok
|
|
|
783
833
|
// itself, a continuous one goes until destroyed
|
|
784
834
|
'fire' // hue .08, continuous
|
|
785
835
|
'torch' // hue .09, continuous
|
|
786
|
-
'smoke' // no hue,
|
|
836
|
+
'smoke' // no hue, gray, continuous
|
|
787
837
|
'steam' // no hue, white, continuous
|
|
788
838
|
'explosion' // hue .12, one-shot
|
|
789
839
|
'sparks' // hue .17, continuous
|
|
@@ -806,9 +856,11 @@ particleEffectsBuiltIn // the built-in names: fire, torch, smok
|
|
|
806
856
|
'confetti' // hue 0 and .6, mixed, one-shot
|
|
807
857
|
'splash' // hue .58, one-shot
|
|
808
858
|
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
|
|
859
|
+
particleEffectApply3D(emitter, effect) // the same for a ParticleEmitter3D, its particles, place and scale kept
|
|
860
|
+
particleEffectFromEmitter(emitter, name='Effect') // a 2D emitter's settings as an effect, to save or build in 3D
|
|
861
|
+
particleEffectsAddBehavior(name, update, update3D, min=-2, max=2, value=1, description='') // add a behavior effects
|
|
862
|
+
// can name, with 2D and 3D pushes; min and max for the designer and to clamp
|
|
863
|
+
// a strength to, value to start at
|
|
812
864
|
particleEffectsAdd(effects) // add effects to play by name, one of the same name replaces it
|
|
813
865
|
particleEffectsGet(name) // an effect's data, any case, to change or build by hand
|
|
814
866
|
await particleEffectsLoad(url) // load the file the particle designer's Save Library wrote, and add its effects
|
|
@@ -973,7 +1025,7 @@ uiSystem.drawSlice(slice, pos, size, color=WHITE) // Draw a TileSlice to the UI
|
|
|
973
1025
|
uiSystem.nativeHeight // If set, UI coords are normalized to this height
|
|
974
1026
|
uiSystem.destroyObjects() // Remove all UI elements
|
|
975
1027
|
uiSystem.isMouseOverUI() // True if the mouse is over a visible hoverable UI object, or a confirm dialog is open
|
|
976
|
-
uiSetDebug(
|
|
1028
|
+
uiSetDebug(debugMode) // Toggle uiDebug rendering of widget bounds
|
|
977
1029
|
|
|
978
1030
|
// Confirm dialog
|
|
979
1031
|
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
|
|
@@ -1083,6 +1135,20 @@ light.glow = 0 // size across of a soft hazy glow over the light, like
|
|
|
1083
1135
|
// over the lit scene after the lightmap, so it shows in the dark, in front of everything
|
|
1084
1136
|
light.glowFalloff = 1 // how fast the glow fades from its middle, .5 a wide haze, 2 a tight bright core
|
|
1085
1137
|
|
|
1138
|
+
// One directional light, a sun: lights the whole scene from one direction, added with the point lights
|
|
1139
|
+
new DirectionalLight(sunDirection=vec2(-1,1), color=WHITE) // toward the sun, as render3D.sunDirection; its color
|
|
1140
|
+
sun.sunDirection // toward the sun, it shines the other way
|
|
1141
|
+
sun.castShadow = true // foreground casters (castShadow) throw long shadows; no lightSystem.shadows needed
|
|
1142
|
+
sun.shadowLength = 20 // world units a long shadow reaches before it has faded out; a caster casts from inside
|
|
1143
|
+
// the shadow map only, (shadowMapScale - 1) / 2 of a view past the screen
|
|
1144
|
+
sun.backgroundDepth = 3 // world units the light gets into a background area from its edges facing it
|
|
1145
|
+
lightSystem.directionalLight // the one there is, or undefined; a second one asserts, destroy the first
|
|
1146
|
+
// (a release build destroys the first itself)
|
|
1147
|
+
lightSystem.directionalTextureSize = 512 // pixels across its work textures, which cover the shadow map's area; a
|
|
1148
|
+
// power of two, as shadowMapSize is, or the shadows shimmer as the view pans
|
|
1149
|
+
obj.castBackgroundShadow = false // a background: dark to the directional light inside, lit at its edges;
|
|
1150
|
+
// a background layer sets castShadow = false and this true
|
|
1151
|
+
|
|
1086
1152
|
// Per-object lightmap contribution hook (on every EngineObject)
|
|
1087
1153
|
class LavaTile extends EngineObject {
|
|
1088
1154
|
renderLight() {
|
|
@@ -1129,6 +1195,16 @@ postProcessChromatic(strength=.005) // red and blue split apart toward
|
|
|
1129
1195
|
postProcessGlow(threshold=.6, strength=1, size=6) // the bloom as a piece
|
|
1130
1196
|
postProcessOutline(color=BLACK, thickness=1, threshold=.02) // lines where the 3D depth jumps, needs
|
|
1131
1197
|
// render3D.depthTexture
|
|
1198
|
+
postProcessTiltShift(focus=.5, size=.25, blur=8) // a sharp band across the screen at focus, 0 bottom to 1 top,
|
|
1199
|
+
// size its height, blurred above and below, 2D or 3D
|
|
1200
|
+
postProcessDepthOfField(focus=10, range=4, blur=8) // sharp at focus world units from the camera, range deep,
|
|
1201
|
+
// blurred nearer and farther; needs render3D.depthTexture
|
|
1202
|
+
postProcess.values = {focus: .5} // the game's own values for the shader, a uniform each, set every
|
|
1203
|
+
// frame; any effect setting but glow's size, which sets its sample
|
|
1204
|
+
// count, may be such a name, to change it live; set them after the
|
|
1205
|
+
// plugin is made, as the shader is made at the first render;
|
|
1206
|
+
// not named _x, iX, gl_x, c, uv or p, which the shader uses:
|
|
1207
|
+
new PostProcessPlugin(postProcessEffects(postProcessTiltShift('focus'))); postProcess.values.focus = .6; // live
|
|
1132
1208
|
```
|
|
1133
1209
|
|
|
1134
1210
|
## LittleJS 3D Math
|
|
@@ -1164,7 +1240,7 @@ m.invert() m.transpose() // in place, return self
|
|
|
1164
1240
|
m.copy() m.transformPoint(v) m.transformDirection(v) m.getTranslation() // or v.transform(m), v.transformDirection(m)
|
|
1165
1241
|
m.getScale() m.getRotation() // the scale and the vec3(pitch, yaw, roll) back out of a transform, a mirror is a negative x
|
|
1166
1242
|
m.determinant() // of the rotation and scale part: negative when it mirrors, 0 when it flattens
|
|
1167
|
-
buildMatrix(pos, rotation, scale,
|
|
1243
|
+
buildMatrix(pos, rotation, scale, matrix) // translate * rotate * scale, any arg optional; matrix is written into
|
|
1168
1244
|
// instead of a new matrix, for a loop that builds many each frame
|
|
1169
1245
|
|
|
1170
1246
|
// Collision - boxes are centered with full size, upright unless given a rotation, an Euler vec3 like rotation3D;
|
|
@@ -1343,6 +1419,19 @@ render3D.setSky(topColor, horizonColor, bottomColor, ambient=.5) // dome colors
|
|
|
1343
1419
|
// color from below, both times ambient; 0 leaves ambient dark
|
|
1344
1420
|
render3D.setFog(fogStart, fogEnd, fogColor) // the fog distances and color at once, no color keeps the current one
|
|
1345
1421
|
render3D.sky = buildSky(topColor, horizonColor, bottomColor, sides, rings) // or set a dome yourself
|
|
1422
|
+
render3D.skyBox = cubeMap // a CubeMap drawn behind everything in place of the dome, undefined by default;
|
|
1423
|
+
// fog fades to fogColor, so set it to the sky box's horizon color
|
|
1424
|
+
render3D.environment = cubeMap // what reflective surfaces reflect, undefined reflects the sky's colors; one
|
|
1425
|
+
// made again and again disposes the one it replaces, its GPU memory
|
|
1426
|
+
makeCubeMap(size, colorOf) // a CubeMap of six size by size faces, colorOf(direction) the Color each way,
|
|
1427
|
+
// a unit Vector3; paint a sky in code, 64 or so is plenty for a blurry one
|
|
1428
|
+
await loadCubeMap([px, nx, py, ny, pz, nz]) // a CubeMap from six square image urls, +x, -x, +y, -y, +z and -z,
|
|
1429
|
+
// a sky box set shown as three.js shows it, each face as its image is drawn
|
|
1430
|
+
cubeMap.size cubeMap.faces cubeMap.dispose() // its face size, its six faces, and freeing its GPU texture
|
|
1431
|
+
const mirror = new CubeMap(128) // no faces: a cube map to draw the scene into
|
|
1432
|
+
mirror.capture(pos3D) // draw the scene around pos3D into it in the next frame's pass, six views of
|
|
1433
|
+
// the whole scene: once for a still scene, every few frames for a moving one
|
|
1434
|
+
mirror.capturePos // where it was last captured from, captured again from there after a lost context
|
|
1346
1435
|
|
|
1347
1436
|
// Draw state, read at each draw; the pass sets it from each object's flags before render3D() and resets it before each
|
|
1348
1437
|
// callback, so set it inside those, or use the object flags below
|
|
@@ -1354,6 +1443,7 @@ render3D.specular = 0 // Phong highlight strength, the shiny spo
|
|
|
1354
1443
|
// out; shininess sets the size of the spot
|
|
1355
1444
|
render3D.shininess = 16 // the highlight's exponent, 4 broad like rubber, 100 sharp like polished metal
|
|
1356
1445
|
render3D.normalMap render3D.normalScale render3D.reflectivity render3D.emissiveMap render3D.emissiveMapColor
|
|
1446
|
+
render3D.environmentMap // the cube map reflected in place of render3D.environment, from obj.environment
|
|
1357
1447
|
// the material, set from each object's fields of the same names
|
|
1358
1448
|
render3D.receiveShadow = true // false keeps the next draws out of the shadow map's darkening
|
|
1359
1449
|
render3D.shader = undefined // a Shader for the next draws, set from each object's shader; with emissive 1
|
|
@@ -1474,13 +1564,20 @@ obj.emissive = 1 // 0 by default; how much it lights itse
|
|
|
1474
1564
|
// things, between partly self lit, above 1 brighter for bloom; still casts
|
|
1475
1565
|
obj.specular = .5 // highlight strength, 0 is none and 1 is full, as render3D.specular; 0 by default
|
|
1476
1566
|
obj.shininess = 100 // 16 by default; the highlight's exponent, higher is smaller and sharper
|
|
1567
|
+
obj.roughness = .5 // shininess set the way glTF measures it, 0 a mirror to 1 matte: it sets
|
|
1568
|
+
// shininess = 2 / roughness^4 - 2, at least 1, and reads it back, as
|
|
1569
|
+
// .9 from about .9 up, where shininess is 1
|
|
1477
1570
|
obj.normalMap = textureInfo // bumps and grooves that catch the light, read at the color texture's uvs;
|
|
1478
1571
|
// green points up the image (OpenGL and glTF), flip the green of a DirectX one;
|
|
1479
1572
|
// no tangents needed, any mesh with uvs works; normalMapFromHeight makes one
|
|
1480
1573
|
obj.normalScale = 1 // how strongly it bends the surface, 0 turns it off
|
|
1481
|
-
obj.reflectivity = .5 // 0 by default, 1 a mirror
|
|
1482
|
-
//
|
|
1483
|
-
//
|
|
1574
|
+
obj.reflectivity = .5 // 0 by default, 1 a mirror; more at a glancing angle (Fresnel); shows
|
|
1575
|
+
// render3D.environment, sharper the higher shininess, as the highlight
|
|
1576
|
+
// is: 10000 a mirror, 1000 polished, 10 a wide blur;
|
|
1577
|
+
// with none, the colors of render3D.sky from setSky or buildSky, or the
|
|
1578
|
+
// ambient ones with no sky
|
|
1579
|
+
obj.environment = mirror // a CubeMap it reflects in place of render3D.environment, as one captured
|
|
1580
|
+
// from its own middle; undefined by default
|
|
1484
1581
|
obj.emissiveMap = textureInfo // where it glows, added on top of the lit surface so it shows in the dark
|
|
1485
1582
|
obj.emissiveMapColor = WHITE // multiplies the emissive map
|
|
1486
1583
|
obj.castShadow = false // true by default, false keeps it out of the shadow map; sprites and cut out
|
|
@@ -1687,8 +1784,9 @@ await loadOBJ(url, smooth) // fetch then parse, in an async gameInit; chain .cen
|
|
|
1687
1784
|
// units
|
|
1688
1785
|
|
|
1689
1786
|
// 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
|
|
1787
|
+
// vertex colors, material colors and base color textures, node animations and skinned characters, four joints a
|
|
1788
|
+
// vertex, bent on the CPU each frame; no morph targets, and no Draco or meshopt compressed geometry, which throws
|
|
1789
|
+
// saying so
|
|
1692
1790
|
const model = await loadGLTF(url) // a GLTFModel, in an async gameInit; or await parseGLTF(data, baseUrl, files) on
|
|
1693
1791
|
// bytes or JSON you already have; files, a Map of the .bin and image files a
|
|
1694
1792
|
// .gltf names by their paths, like the files of a drop, in place of fetching,
|
|
@@ -1700,7 +1798,7 @@ model.parts // one GLTFPart per primitive of every node
|
|
|
1700
1798
|
// are the set the texture's texCoord names, moved by KHR_texture_transform;
|
|
1701
1799
|
// normalMap and normalScale from normalTexture, emissiveMap and
|
|
1702
1800
|
// emissiveMapColor from emissiveTexture and emissiveFactor, read at the base
|
|
1703
|
-
// color texture's uvs
|
|
1801
|
+
// color texture's uvs, and roughness from roughnessFactor, 1 when it has none
|
|
1704
1802
|
model.mesh, model.textureInfo // everything as one Mesh tinted by its materials, and its texture when every
|
|
1705
1803
|
// part uses the same one; a model mixing plain and textured parts, or using
|
|
1706
1804
|
// several textures or unlit parts, draws right through createObject
|
|
@@ -1709,15 +1807,20 @@ model.createObject(pos3D) // a GLTFObject, an EngineObject3D with a c
|
|
|
1709
1807
|
// emissive 1 for an unlit one; move and turn the root and the parts follow
|
|
1710
1808
|
model.animations // one GLTFAnimation each: name, duration in seconds, and the channels that
|
|
1711
1809
|
// 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,
|
|
1810
|
+
object.play(animation=0, loop=true, speed=1, blend=0) // play one on a GLTFObject by name or number, its parts move
|
|
1811
|
+
// and a skinned mesh bends with it; speed below 0 plays it backward, one that
|
|
1812
|
+
// does not loop holds its end, and blend is seconds to cross-fade from the pose
|
|
1813
|
+
// it is in, the animation it leaves going on through the fade
|
|
1814
|
+
object.getJointMatrix(name) // a node's world Matrix4 as posed now, by its name in the file, to hang a sword
|
|
1815
|
+
// on a hand; undefined for a name the model does not have
|
|
1714
1816
|
object.stop() // hold the pose where it is; object.setAnimationTime(t) poses it at a time
|
|
1715
1817
|
object.animation .animationTime .animationSpeed .animationLoop .animationPlaying
|
|
1716
1818
|
model.getPose(animation, time) // one Matrix4 per part, how far it moved from its resting place
|
|
1717
1819
|
model.dispose() // free the part meshes, the combined mesh and the textures of a model that
|
|
1718
1820
|
// is done with; destroy the objects createObject made first
|
|
1719
1821
|
// 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
|
|
1822
|
+
// are read, and object.parts is what an animation poses; a skinned part's object bends a mesh of its own, so
|
|
1823
|
+
// characters of one model hold their own poses, and part.skin is what bends it
|
|
1721
1824
|
model.center().fit(size) // move the model's bounds onto the origin and scale its largest extent to
|
|
1722
1825
|
// size, every part together, like Mesh.center and fit; getBounds and
|
|
1723
1826
|
// transform(matrix) as well
|
|
@@ -1738,6 +1841,7 @@ emitter3D.gravityScale = 0 // a share of render3D.gravity added on top of its ow
|
|
|
1738
1841
|
// an emitter with an emitTime destroys itself once its last particle is gone, so a burst is fire and forget
|
|
1739
1842
|
// untextured particles are soft round dots, textured ones are billboards of the tile
|
|
1740
1843
|
emitter.collideLevel = false // particles hit the height maps and voxel maps, bounce by restitution, slide by friction
|
|
1844
|
+
// only: not solid objects, as 2D particles hit only tile layers
|
|
1741
1845
|
emitter.particleCreateCallback / particleUpdateCallback / particleCollideCallback / particleDestroyCallback
|
|
1742
1846
|
// as in 2D, each given a Particle3D {pos, velocity, age, lifeTime, emitter, destroy()}, one object
|
|
1743
1847
|
// the emitter reuses, so copy what you keep; the collide callback gets (particle, level, pos) and
|
|
@@ -1818,7 +1922,9 @@ material.side = THREE.DoubleSide // mesh.doubleSided = true
|
|
|
1818
1922
|
material.emissiveIntensity // obj.emissive
|
|
1819
1923
|
material.normalMap, normalScale // obj.normalMap, obj.normalScale (a number, three.js takes a Vector2)
|
|
1820
1924
|
material.shininess (MeshPhongMaterial) // obj.shininess, with obj.specular the strength
|
|
1821
|
-
material.
|
|
1925
|
+
material.reflectivity // obj.reflectivity, with render3D.environment or obj.environment the map
|
|
1926
|
+
material.metalness // none; a dark color with reflectivity reads as metal
|
|
1927
|
+
material.roughness (MeshStandardMaterial) // obj.roughness, which sets obj.shininess: 0 a mirror, 1 matte
|
|
1822
1928
|
material.emissiveMap, emissive // obj.emissiveMap, obj.emissiveMapColor
|
|
1823
1929
|
material.transparent, blending // obj.transparent, obj.additive
|
|
1824
1930
|
new THREE.ShaderMaterial({fragmentShader}) // obj.shader = new Shader(code), a mainImage snippet the engine wraps;
|
|
@@ -1833,15 +1939,20 @@ new THREE.SpotLight(color, i, d, angle, penumbra) // a Light3D with coneAngle =
|
|
|
1833
1939
|
// for its castShadow
|
|
1834
1940
|
light.castShadow, light.shadow.camera // render3D.shadows, shadowRange and shadowCenter
|
|
1835
1941
|
scene.fog = new THREE.Fog(c, near, far) // render3D.setFog(near, far, c)
|
|
1836
|
-
scene.background // render3D.setSky(topColor, horizonColor, bottomColor)
|
|
1942
|
+
scene.background // render3D.setSky(topColor, horizonColor, bottomColor), or
|
|
1943
|
+
// render3D.skyBox for a cube map
|
|
1944
|
+
scene.environment // render3D.environment
|
|
1945
|
+
material.envMap on one mesh // obj.environment
|
|
1946
|
+
new THREE.CubeCamera(near, far, target) // new CubeMap(size), then cubeMap.capture(pos3D) in place of update
|
|
1947
|
+
new THREE.CubeTextureLoader().load(urls) // await loadCubeMap(urls), the same order
|
|
1837
1948
|
OrbitControls // new CameraControl3D(target, distance)
|
|
1838
1949
|
PointerLockControls // new FirstPersonCamera3D
|
|
1839
1950
|
new THREE.Raycaster() // render3D.screenToRay, pick and engineObjectsRaycast3D
|
|
1840
1951
|
OBJLoader // loadOBJ(url) or parseOBJ(text)
|
|
1841
1952
|
GLTFLoader // loadGLTF(url): model.createObject(pos) is the scene as objects, model.mesh
|
|
1842
1953
|
// is everything as one Mesh
|
|
1843
|
-
mixer.clipAction(clip).play() // object.play(name) on the object createObject made,
|
|
1844
|
-
|
|
1954
|
+
mixer.clipAction(clip).play() // object.play(name) on the object createObject made, skinned characters
|
|
1955
|
+
crossFadeTo(next, seconds) // object.play(next, true, 1, seconds); bone.getWorldPosition: getJointMatrix
|
|
1845
1956
|
EffectComposer and UnrealBloomPass // postProcessBloom()
|
|
1846
1957
|
renderer.render(scene, camera) // nothing to do, the engine draws every frame and handles resizing
|
|
1847
1958
|
position.setUsage(THREE.DynamicDrawUsage) // mesh.dynamicDraw = true once, then mesh.dirty = true when the points
|
|
@@ -1879,7 +1990,11 @@ level3DVoxelSetup(tileInfo, (map)=> {}) // The sheet a level's block m
|
|
|
1879
1990
|
"fog": [25, 70], "fogColor": "#d6ecff", // start and end, an end of 0 for none; the horizon color
|
|
1880
1991
|
// when the level has a sky and no fogColor
|
|
1881
1992
|
"shadows": true,
|
|
1882
|
-
"lensFlare": true
|
|
1993
|
+
"lensFlare": true, // the sun's lens flare, a LensFlare3D made for it
|
|
1994
|
+
"skyBox": ["px.png", "nx.png", "py.png", "ny.png", "pz.png", "nz.png"], // render3D.skyBox, six images
|
|
1995
|
+
"environment": ["px.png", "nx.png", "py.png", "ny.png", "pz.png", "nz.png"]}, // as loadCubeMap takes
|
|
1996
|
+
// them, loaded in the background, the same urls once;
|
|
1997
|
+
// urls are from the page, not from the level's file
|
|
1883
1998
|
"objects": []}
|
|
1884
1999
|
|
|
1885
2000
|
// A level can hold a map of blocks, made a VoxelMap when it loads: its corner, its size in cells, and its blocks
|
|
@@ -1895,7 +2010,8 @@ level3DVoxelSetup(tileInfo, (map)=> {}) // The sheet a level's block m
|
|
|
1895
2010
|
// Prefabs - a prefab is a small level, objects about its own origin, placed many times under one name. The level
|
|
1896
2011
|
// editor saves one as it saves a level, so it is the prefab editor too, and there every instance follows its prefab
|
|
1897
2012
|
level3DAddPrefab(name, prefab) // Add {objects: [...]} as a type; its objects may be of other prefabs
|
|
1898
|
-
await level3DLoadPrefab(name, url) // Fetch a prefab file and add it
|
|
2013
|
+
await level3DLoadPrefab(name, url) // Fetch a prefab file and add it; a prefab used inside it is
|
|
2014
|
+
// named by its type, the game adds that one too
|
|
1899
2015
|
level3DSpawn(type, pos3D, rotation3D, scale3D, properties) // Make one object of any type from code, a prefab's
|
|
1900
2016
|
// instance or a plain type; rotation in radians
|
|
1901
2017
|
prefab = new Prefab3D // what a prefab's type makes, a handle that draws nothing:
|
|
@@ -1994,6 +2110,12 @@ obj.syncMesh() // copy the 2D transform to the mesh
|
|
|
1994
2110
|
read only, move it with `setPosition`, `setAngle` or `setTransform` and push it with velocities and forces
|
|
1995
2111
|
- Joints, raycasting, polygon/circle/edge fixtures
|
|
1996
2112
|
- Angular values are clockwise like `angle`: angular velocity, torque, joint angles and limits, motor speeds
|
|
2113
|
+
- The EngineObject's own physics fields do nothing on a Box2dObject, Box2D moves it: `velocity`, `angleVelocity`,
|
|
2114
|
+
`damping`, `angleDamping`, `mass`, `friction`, `restitution` and `gravityScale`. Use `getLinearVelocity`,
|
|
2115
|
+
`setLinearVelocity`, `setAngularVelocity`, `setLinearDamping`, `setAngularDamping`, `setMass`, the friction and
|
|
2116
|
+
restitution given to its shapes, and `setGravityScale`; a debug build warns once when one is set
|
|
2117
|
+
- A world made again after `engineObjectsDestroy` does not step exactly as a fresh one, as Box2D reuses its ids, so
|
|
2118
|
+
a replay or a lockstep game that needs the same steps every time reloads the page
|
|
1997
2119
|
- See `examples/box2d/` for a full demo
|
|
1998
2120
|
|
|
1999
2121
|
```javascript
|
|
@@ -2036,8 +2158,8 @@ obj.setAwake(awake=true)
|
|
|
2036
2158
|
obj.setFixedRotation(isFixed=true) // Stop the body from rotating
|
|
2037
2159
|
obj.setBullet(isBullet=true) // Continuous collision for fast bodies, so they don't pass through thin ones
|
|
2038
2160
|
obj.setSensor(isSensor=true) // The fixtures it has now detect contacts without colliding
|
|
2039
|
-
obj.setLinearDamping(damping) // Box2D's damping, 0 is none, larger slows it faster
|
|
2040
|
-
obj.setAngularDamping(damping)
|
|
2161
|
+
obj.setLinearDamping(damping) // Box2D's damping, a rate: 0 is none, larger slows it faster, no upper limit
|
|
2162
|
+
obj.setAngularDamping(damping) // the same for its turning, where an EngineObject's damping is 0 to 1
|
|
2041
2163
|
obj.setGravityScale(scale=1)
|
|
2042
2164
|
obj.setMassData(localCenter, mass, momentOfInertia) // undefined leaves that one as it is, inertia is about the
|
|
2043
2165
|
// center of mass
|
|
@@ -2148,6 +2270,46 @@ newgrounds.resendUnlocks() // advanced: send the ones whose request di
|
|
|
2148
2270
|
// the minute's session check does; one the server refused is not resent
|
|
2149
2271
|
```
|
|
2150
2272
|
|
|
2273
|
+
## LittleJS Wavedash
|
|
2274
|
+
- Optional plugin for Wavedash achievements and leaderboards, the same shape as the Newgrounds one
|
|
2275
|
+
- Wavedash serves the game's page and puts its SDK in `window.Wavedash`, so nothing is bundled; off Wavedash every call
|
|
2276
|
+
does nothing and medals unlock as any do
|
|
2277
|
+
- Make the plugin at the end of `gameInit`: it calls `Wavedash.init()`, until which Wavedash keeps its loading screen
|
|
2278
|
+
- Achievements are made with the Wavedash CLI, `--description` required; numbering the identifiers (`ACH_01_...`)
|
|
2279
|
+
orders them, since Wavedash lists them by identifier
|
|
2280
|
+
- A game built with its own minifier keeps the SDK's names (`Wavedash`, `init`, `success`, `data`, `id` and the
|
|
2281
|
+
methods) and real booleans: the SDK throws on a renamed call or a 1 for true (Terser's booleans_as_integers); the
|
|
2282
|
+
engine's own builds keep both
|
|
2283
|
+
|
|
2284
|
+
```javascript
|
|
2285
|
+
// the medals, each with the identifier of its achievement on Wavedash
|
|
2286
|
+
const medal_finish = new WavedashMedal(0, 'ACH_01_FINISH', 'Finish', 'Finish a level');
|
|
2287
|
+
function gameInit()
|
|
2288
|
+
{
|
|
2289
|
+
medalsInit('My Game');
|
|
2290
|
+
new WavedashPlugin({LEVEL_1: {lowerWins: true, display: 'milliseconds'}, HIGH_SCORE: {}}); // last, it calls init
|
|
2291
|
+
}
|
|
2292
|
+
// later, in game code
|
|
2293
|
+
medal_finish.unlock(); // Wavedash's toast on Wavedash, the engine's popup anywhere else
|
|
2294
|
+
wavedash.postScore('LEVEL_1', timeMs);
|
|
2295
|
+
|
|
2296
|
+
new WavedashMedal(id, achievement, name, description, icon, src) // a Medal that is also a Wavedash achievement; its
|
|
2297
|
+
// unlock is sent until Wavedash takes it, which it refuses until it has loaded
|
|
2298
|
+
// the player's, a moment after launch; saved unlocks are sent too; one refused
|
|
2299
|
+
// for a minute warns in the console with its identifier, a typo or not made
|
|
2300
|
+
medal.achievement // the identifier of its Wavedash achievement
|
|
2301
|
+
new WavedashPlugin(leaderboards) // sets the wavedash global, calls Wavedash.init and makes the leaderboards: by
|
|
2302
|
+
// name, lowerWins for times and golf (higher wins when left out) and display
|
|
2303
|
+
// 'number' (the default), 'seconds', 'milliseconds' or 'ticks' (60 a second)
|
|
2304
|
+
wavedash.isActive() // whether the game is on Wavedash, its SDK on the page
|
|
2305
|
+
await wavedash.postScore(name, score) // a whole number, milliseconds for a time, Wavedash keeping the best; true once
|
|
2306
|
+
// posted, false off Wavedash or when it failed or took over 15 seconds; a board
|
|
2307
|
+
// not in the table is made then, higher wins
|
|
2308
|
+
await wavedash.getScores(name, offset=0, limit=10, friendsOnly=false) // the entries as Wavedash gives them,
|
|
2309
|
+
// undefined off Wavedash or when they could not be read
|
|
2310
|
+
wavedash.leaderboards // each board's id promise by its name
|
|
2311
|
+
```
|
|
2312
|
+
|
|
2151
2313
|
## LittleJS Drawing Utilities
|
|
2152
2314
|
- Optional plugin: nine-slice and three-slice helpers for scalable UI panels, plus a crescent shape
|
|
2153
2315
|
- World-space (WebGL or 2D) and screen-space (2D by default, useWebGL for WebGL) variants
|
|
@@ -2282,7 +2444,7 @@ setLevelEditor(new MyEditor) // Make it the one in use, before the editor open
|
|
|
2282
2444
|
- Press Escape key to toggle debug overlay
|
|
2283
2445
|
- Number keys toggle debug functions while the overlay is open: 1 physics, 2 tiles (each tile layer's bounds, the
|
|
2284
2446
|
collision values on screen, and the tiles under the mouse; pressing 2 again steps through the layers one at a time,
|
|
2285
|
-
then off), 3 particles, 4 raycasts, 5 gamepads, 6 sound, 7 screenshot,
|
|
2447
|
+
then off), 3 particles, 4 raycasts, 5 gamepads, 6 sound, 7 screenshot, 9 tweakables panel,
|
|
2286
2448
|
0 level editor
|
|
2287
2449
|
- C, while the overlay is open, is a free camera for a 3D game: the mouse looks once captured or with the right
|
|
2288
2450
|
button held, WASD and QE fly, Shift is faster and the wheel sets the speed; the game runs on and reads no keys or
|
|
@@ -2301,15 +2463,12 @@ debugPoint(pos, color, time, angle) // Draw debug point
|
|
|
2301
2463
|
debugLine(posA, posB, color, width=.1, time) // Draw debug line
|
|
2302
2464
|
debugPoly(pos, points, color=WHITE, time=0, angle=0, fill) // Draw debug polygon
|
|
2303
2465
|
debugText(text, pos, size=1, color=WHITE, time=0, angle=0) // Draw debug text
|
|
2304
|
-
debugOverlap(
|
|
2466
|
+
debugOverlap(posA, sizeA, posB, sizeB, color) // Draw a debug overlap between two boxes
|
|
2305
2467
|
// each debug draw also takes screenSpace as its last parameter, defaulting to drawScreenSpace; debugText takes a
|
|
2306
2468
|
// font before it
|
|
2307
2469
|
debugClear() // Clear all debug primitives
|
|
2308
2470
|
debugScreenshot() // Save a screenshot at the end of this frame
|
|
2309
2471
|
debugShowErrors() // Show full page error message when an error occurs
|
|
2310
|
-
debugVideoCaptureStart() // Start capturing a video of the canvas
|
|
2311
|
-
debugVideoCaptureStop() // Stop capturing and save the video to disk
|
|
2312
|
-
debugVideoCaptureIsActive() // Is video currently being captured?
|
|
2313
2472
|
createCanvasContext(width, height=width, willReadFrequently=false) // Offscreen canvas to draw into, returns its
|
|
2314
2473
|
// 2D context; the canvas is context.canvas
|
|
2315
2474
|
saveCanvas(canvas, filename='screenshot', type='image/png') // Save canvas to a file
|
|
@@ -2327,19 +2486,6 @@ debugTweakables = false // Is the tweakables panel shown? setDebugTweakables(sho
|
|
|
2327
2486
|
debugWatermark // Should watermark with FPS appear in debug mode?
|
|
2328
2487
|
```
|
|
2329
2488
|
|
|
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
2489
|
[LittleJS Engine](https://github.com/KilledByAPixel/LittleJS) Copyright 2021 Frank Force
|
|
2344
2490
|
|
|
2345
2491
|

|