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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "littlejsengine",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.26.0",
|
|
4
4
|
"description": "LittleJS - Tiny and Fast HTML5 Game Engine",
|
|
5
5
|
"main": "dist/littlejs.esm.js",
|
|
6
6
|
"types": "dist/littlejs.d.ts",
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
"default": "./dist/littlejs.esm.js"
|
|
12
12
|
},
|
|
13
13
|
"./dist/*": "./dist/*",
|
|
14
|
+
"./plugins/*": "./plugins/*",
|
|
15
|
+
"./src/*": "./src/*",
|
|
14
16
|
"./package.json": "./package.json"
|
|
15
17
|
},
|
|
16
18
|
"repository": {
|
|
@@ -52,12 +54,10 @@
|
|
|
52
54
|
"test:browser": "node test/browser/run.mjs"
|
|
53
55
|
},
|
|
54
56
|
"engines": {
|
|
55
|
-
"node": "
|
|
57
|
+
"node": ">=22.12.0"
|
|
56
58
|
},
|
|
57
59
|
"devDependencies": {
|
|
58
60
|
"bestzip": "^2.2.1",
|
|
59
|
-
"electron": "^38.2.0",
|
|
60
|
-
"electron-packager": "^17.1.2",
|
|
61
61
|
"google-closure-compiler": "~20230502.0.0",
|
|
62
62
|
"jsdoc": "~4.0.2",
|
|
63
63
|
"roadroller": "~2.1.0",
|
package/plugins/box2d.js
CHANGED
|
@@ -35,7 +35,7 @@ let box2dDebug = false;
|
|
|
35
35
|
let box2dTempVectors;
|
|
36
36
|
function box2dTemp(v, slot=0)
|
|
37
37
|
{
|
|
38
|
-
ASSERT(isVector2(v));
|
|
38
|
+
ASSERT(isVector2(v), 'Box2D: expected a vec2', v);
|
|
39
39
|
const temp = (box2dTempVectors ||= [new box2d.instance.b2Vec2(), new box2d.instance.b2Vec2()])[slot];
|
|
40
40
|
temp.Set(v.x, v.y);
|
|
41
41
|
return temp;
|
|
@@ -88,6 +88,9 @@ function box2dWakeWithContacts(body)
|
|
|
88
88
|
edge.get_other().SetAwake(true);
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
// a number Box2D can take: it stops for good on NaN or Infinity, and a release build has no asserts to catch one first
|
|
92
|
+
const box2dFinite = (value, otherwise)=> isFinite(value) ? value : otherwise;
|
|
93
|
+
|
|
91
94
|
// wake both bodies of a joint whose length, spring, ratio or strength changed, a sleeping body would stay where it was
|
|
92
95
|
function box2dWakeJoint(joint)
|
|
93
96
|
{
|
|
@@ -147,6 +150,64 @@ function box2dDestroyGears(joint)
|
|
|
147
150
|
* @memberof Box2D */
|
|
148
151
|
function box2dSetDebug(enable) { box2dDebug = enable; }
|
|
149
152
|
|
|
153
|
+
// the EngineObject physics fields a Box2D body does not read, each with what moves the body instead; a debug build
|
|
154
|
+
// warns once a field when a game sets one, which did nothing and said nothing
|
|
155
|
+
const box2dUnusedFields = {
|
|
156
|
+
velocity: 'setLinearVelocity', angleVelocity: 'setAngularVelocity', damping: 'setLinearDamping',
|
|
157
|
+
angleDamping: 'setAngularDamping', mass: 'setMass or the density of its shapes',
|
|
158
|
+
friction: 'the friction of its shapes, given to addBox and the rest',
|
|
159
|
+
restitution: 'the restitution of its shapes, given to addBox and the rest'};
|
|
160
|
+
const box2dUnusedWarned = new Set, box2dUnusedStarts = new WeakMap;
|
|
161
|
+
|
|
162
|
+
// the values of those fields as numbers, a vector as its two, then gravityScale, kept for the object
|
|
163
|
+
function box2dUnusedFieldValues(o)
|
|
164
|
+
{
|
|
165
|
+
const values = [];
|
|
166
|
+
for (const name in box2dUnusedFields)
|
|
167
|
+
{
|
|
168
|
+
const value = o[name];
|
|
169
|
+
value instanceof Vector2 ? values.push(value.x, value.y) : values.push(value);
|
|
170
|
+
}
|
|
171
|
+
values.push(o.gravityScale);
|
|
172
|
+
return values;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// warn once a field
|
|
176
|
+
function box2dUnusedWarn(name, use)
|
|
177
|
+
{
|
|
178
|
+
if (box2dUnusedWarned.has(name)) return;
|
|
179
|
+
box2dUnusedWarned.add(name);
|
|
180
|
+
console.warn('Box2dObject.' + name + ' does nothing on a Box2D body, use ' + use);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// warn once a field of one set on a Box2dObject, and of gravityScale set on the field, not with setGravityScale;
|
|
184
|
+
// compared in place, as it runs for every body every step of a debug build
|
|
185
|
+
function box2dCheckUnusedFields(o)
|
|
186
|
+
{
|
|
187
|
+
const start = box2dUnusedStarts.get(o);
|
|
188
|
+
if (!start) return;
|
|
189
|
+
let i = 0;
|
|
190
|
+
for (const name in box2dUnusedFields)
|
|
191
|
+
{
|
|
192
|
+
const value = o[name];
|
|
193
|
+
let changed;
|
|
194
|
+
if (value instanceof Vector2)
|
|
195
|
+
{
|
|
196
|
+
changed = value.x !== start[i] || value.y !== start[i + 1];
|
|
197
|
+
i += 2;
|
|
198
|
+
}
|
|
199
|
+
else
|
|
200
|
+
changed = value !== start[i++];
|
|
201
|
+
changed && box2dUnusedWarn(name, box2dUnusedFields[name]);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// the body's own scale is a call into Box2D, asked only when the field changed since it was last asked,
|
|
205
|
+
// since setGravityScale sets both
|
|
206
|
+
if (o.gravityScale === start[i]) return;
|
|
207
|
+
start[i] = o.gravityScale;
|
|
208
|
+
Math.fround(o.gravityScale) === o.body.GetGravityScale() || box2dUnusedWarn('gravityScale', 'setGravityScale');
|
|
209
|
+
}
|
|
210
|
+
|
|
150
211
|
///////////////////////////////////////////////////////////////////////////////
|
|
151
212
|
/**
|
|
152
213
|
* Box2D Object - extend with your own custom physics objects
|
|
@@ -154,6 +215,10 @@ function box2dSetDebug(enable) { box2dDebug = enable; }
|
|
|
154
215
|
* - Provides interface for Box2D body and fixture functions
|
|
155
216
|
* - Each object can have multiple fixtures and joints
|
|
156
217
|
* - Angular values are clockwise like angle: angular velocity, torque, joint angles, limits and motor speeds
|
|
218
|
+
* - Box2D moves the body, so the EngineObject physics fields do nothing on it: velocity, angleVelocity, damping,
|
|
219
|
+
* angleDamping, mass, friction, restitution and gravityScale; use setLinearVelocity, setAngularVelocity,
|
|
220
|
+
* setLinearDamping, setAngularDamping, setMass, the friction and restitution of its shapes and setGravityScale.
|
|
221
|
+
* A debug build warns once when one of them is set
|
|
157
222
|
* @extends EngineObject
|
|
158
223
|
* @memberof Box2D
|
|
159
224
|
*/
|
|
@@ -196,6 +261,9 @@ class Box2dObject extends EngineObject
|
|
|
196
261
|
|
|
197
262
|
this.body.object = this; // link body to this object
|
|
198
263
|
box2d.objects.push(this); // keep track of all box2d objects
|
|
264
|
+
|
|
265
|
+
// a debug build notes the engine physics fields Box2D does not read, to warn when one is set
|
|
266
|
+
debug && box2dUnusedStarts.set(this, box2dUnusedFieldValues(this));
|
|
199
267
|
}
|
|
200
268
|
|
|
201
269
|
/** Destroy this object and its physics body
|
|
@@ -244,7 +312,7 @@ class Box2dObject extends EngineObject
|
|
|
244
312
|
this.drawFixtures(this.color, this.lineColor, this.lineWidth);
|
|
245
313
|
}
|
|
246
314
|
|
|
247
|
-
/**
|
|
315
|
+
/** Draw its fixtures for the debug view: yellow asleep, blue static, both when both */
|
|
248
316
|
renderDebugInfo()
|
|
249
317
|
{
|
|
250
318
|
const isAsleep = !this.getIsAwake();
|
|
@@ -253,7 +321,7 @@ class Box2dObject extends EngineObject
|
|
|
253
321
|
this.drawFixtures(color);
|
|
254
322
|
}
|
|
255
323
|
|
|
256
|
-
/**
|
|
324
|
+
/** Draw all this object's fixtures
|
|
257
325
|
* @param {Color} [color]
|
|
258
326
|
* @param {Color} [lineColor]
|
|
259
327
|
* @param {number} [lineWidth]
|
|
@@ -303,7 +371,8 @@ class Box2dObject extends EngineObject
|
|
|
303
371
|
* @param {number} [density]
|
|
304
372
|
* @param {number} [friction]
|
|
305
373
|
* @param {number} [restitution]
|
|
306
|
-
* @param {boolean} [isSensor]
|
|
374
|
+
* @param {boolean} [isSensor]
|
|
375
|
+
* @return {Object} - The fixture made, Box2D's own */
|
|
307
376
|
addShape(shape, density=1, friction=.2, restitution=0, isSensor=false)
|
|
308
377
|
{
|
|
309
378
|
ASSERT(isNumber(density), 'density must be a number');
|
|
@@ -332,7 +401,8 @@ class Box2dObject extends EngineObject
|
|
|
332
401
|
* @param {number} [density]
|
|
333
402
|
* @param {number} [friction]
|
|
334
403
|
* @param {number} [restitution]
|
|
335
|
-
* @param {boolean} [isSensor]
|
|
404
|
+
* @param {boolean} [isSensor]
|
|
405
|
+
* @return {Object|undefined} - The fixture made, Box2D's own, undefined for a shape too small to make */
|
|
336
406
|
addBox(size=vec2(1), offset=vec2(), angle=0, density, friction, restitution, isSensor)
|
|
337
407
|
{
|
|
338
408
|
ASSERT(isVector2(size), 'size must be a Vector2');
|
|
@@ -341,8 +411,8 @@ class Box2dObject extends EngineObject
|
|
|
341
411
|
ASSERT(isNumber(angle), 'angle must be a number');
|
|
342
412
|
|
|
343
413
|
// Box2D stops for good on a box with almost no area, like addPoly no fixture is made from one
|
|
344
|
-
ASSERT(size.x * size.y > 1e-6, 'box is too small for Box2D');
|
|
345
|
-
if (!(size.x * size.y > 1e-6)) return;
|
|
414
|
+
ASSERT(size.x * size.y > 1e-6 && isFinite(size.x * size.y), 'box is too small or too big for Box2D');
|
|
415
|
+
if (!(size.x * size.y > 1e-6) || !isFinite(size.x * size.y)) return;
|
|
346
416
|
|
|
347
417
|
const shape = new box2d.instance.b2PolygonShape();
|
|
348
418
|
shape.SetAsBox(size.x/2, size.y/2, box2dTemp(offset), -angle);
|
|
@@ -357,7 +427,8 @@ class Box2dObject extends EngineObject
|
|
|
357
427
|
* @param {number} [density]
|
|
358
428
|
* @param {number} [friction]
|
|
359
429
|
* @param {number} [restitution]
|
|
360
|
-
* @param {boolean} [isSensor]
|
|
430
|
+
* @param {boolean} [isSensor]
|
|
431
|
+
* @return {Object|undefined} - The fixture made, Box2D's own, undefined for a shape too small to make */
|
|
361
432
|
addPoly(points, density, friction, restitution, isSensor)
|
|
362
433
|
{
|
|
363
434
|
ASSERT(isArray(points), 'points must be an array');
|
|
@@ -404,7 +475,8 @@ class Box2dObject extends EngineObject
|
|
|
404
475
|
* @param {number} [density]
|
|
405
476
|
* @param {number} [friction]
|
|
406
477
|
* @param {number} [restitution]
|
|
407
|
-
* @param {boolean} [isSensor]
|
|
478
|
+
* @param {boolean} [isSensor]
|
|
479
|
+
* @return {Object|undefined} - The fixture made, Box2D's own, undefined for a shape too small to make */
|
|
408
480
|
addRegularPoly(diameter=1, sides=8, density, friction, restitution, isSensor)
|
|
409
481
|
{
|
|
410
482
|
ASSERT(isNumber(diameter) && diameter>0, 'diameter must be a positive number');
|
|
@@ -424,7 +496,8 @@ class Box2dObject extends EngineObject
|
|
|
424
496
|
* @param {number} [density]
|
|
425
497
|
* @param {number} [friction]
|
|
426
498
|
* @param {number} [restitution]
|
|
427
|
-
* @param {boolean} [isSensor]
|
|
499
|
+
* @param {boolean} [isSensor]
|
|
500
|
+
* @return {Object|undefined} - The fixture made, Box2D's own, undefined for a shape too small to make */
|
|
428
501
|
addRandomPoly(diameter=1, density, friction, restitution, isSensor)
|
|
429
502
|
{
|
|
430
503
|
ASSERT(isNumber(diameter) && diameter>0, 'diameter must be a positive number');
|
|
@@ -443,12 +516,14 @@ class Box2dObject extends EngineObject
|
|
|
443
516
|
* @param {number} [density]
|
|
444
517
|
* @param {number} [friction]
|
|
445
518
|
* @param {number} [restitution]
|
|
446
|
-
* @param {boolean} [isSensor]
|
|
519
|
+
* @param {boolean} [isSensor]
|
|
520
|
+
* @return {Object|undefined} - The fixture made, Box2D's own, undefined for a circle too big to make */
|
|
447
521
|
addCircle(diameter=1, offset=vec2(), density, friction, restitution, isSensor)
|
|
448
522
|
{
|
|
449
|
-
ASSERT(isNumber(diameter) && diameter>0, 'diameter must be a positive number');
|
|
523
|
+
ASSERT(isNumber(diameter) && diameter>0 && isFinite(diameter), 'diameter must be a positive number');
|
|
450
524
|
ASSERT(isVector2(offset), 'offset must be a Vector2');
|
|
451
|
-
|
|
525
|
+
if (!isFinite(diameter)) return; // Box2D stops for good on it, no fixture is made
|
|
526
|
+
|
|
452
527
|
const shape = new box2d.instance.b2CircleShape();
|
|
453
528
|
shape.set_m_p(box2dTemp(offset));
|
|
454
529
|
shape.set_m_radius(diameter/2);
|
|
@@ -463,7 +538,8 @@ class Box2dObject extends EngineObject
|
|
|
463
538
|
* @param {number} [density]
|
|
464
539
|
* @param {number} [friction]
|
|
465
540
|
* @param {number} [restitution]
|
|
466
|
-
* @param {boolean} [isSensor]
|
|
541
|
+
* @param {boolean} [isSensor]
|
|
542
|
+
* @return {Object} - The fixture made, Box2D's own */
|
|
467
543
|
addEdge(point1, point2, density, friction, restitution, isSensor)
|
|
468
544
|
{
|
|
469
545
|
ASSERT(isVector2(point1), 'point1 must be a Vector2');
|
|
@@ -481,7 +557,8 @@ class Box2dObject extends EngineObject
|
|
|
481
557
|
* @param {number} [density]
|
|
482
558
|
* @param {number} [friction]
|
|
483
559
|
* @param {number} [restitution]
|
|
484
|
-
* @param {boolean} [isSensor]
|
|
560
|
+
* @param {boolean} [isSensor]
|
|
561
|
+
* @return {Array<Object>} - The fixtures made, Box2D's own */
|
|
485
562
|
addEdgeList(points, density, friction, restitution, isSensor)
|
|
486
563
|
{
|
|
487
564
|
ASSERT(isArray(points), 'points must be an array');
|
|
@@ -514,7 +591,8 @@ class Box2dObject extends EngineObject
|
|
|
514
591
|
* @param {number} [density]
|
|
515
592
|
* @param {number} [friction]
|
|
516
593
|
* @param {number} [restitution]
|
|
517
|
-
* @param {boolean} [isSensor]
|
|
594
|
+
* @param {boolean} [isSensor]
|
|
595
|
+
* @return {Array<Object>} - The fixtures made, Box2D's own */
|
|
518
596
|
addEdgeLoop(points, density, friction, restitution, isSensor)
|
|
519
597
|
{
|
|
520
598
|
ASSERT(isArray(points), 'points must be an array');
|
|
@@ -676,12 +754,14 @@ class Box2dObject extends EngineObject
|
|
|
676
754
|
setAngularVelocity(angularVelocity)
|
|
677
755
|
{ this.body.SetAngularVelocity(-angularVelocity); }
|
|
678
756
|
|
|
679
|
-
/** Sets the linear damping
|
|
757
|
+
/** Sets the linear damping, Box2D's: a rate, 0 none and larger slows it faster, with no upper limit, where the
|
|
758
|
+
* damping of an EngineObject is the fraction it keeps each frame and does nothing on a Box2dObject
|
|
680
759
|
* @param {number} damping */
|
|
681
760
|
setLinearDamping(damping)
|
|
682
761
|
{ this.body.SetLinearDamping(damping); }
|
|
683
762
|
|
|
684
|
-
/** Sets the angular damping
|
|
763
|
+
/** Sets the angular damping, Box2D's: a rate, 0 none and larger slows its turning faster, with no upper limit;
|
|
764
|
+
* angleDamping does nothing on a Box2dObject
|
|
685
765
|
* @param {number} damping */
|
|
686
766
|
setAngularDamping(damping)
|
|
687
767
|
{ this.body.SetAngularDamping(damping); }
|
|
@@ -758,7 +838,7 @@ class Box2dObject extends EngineObject
|
|
|
758
838
|
const f = Math.fround;
|
|
759
839
|
const oldInertia = f(data.get_I() - box2dCenterInertia(oldMass, center.get_x(), center.get_y()));
|
|
760
840
|
const inertia = momentOfInertia ?? oldInertia;
|
|
761
|
-
mass
|
|
841
|
+
mass = box2dFinite(mass ?? oldMass, oldMass);
|
|
762
842
|
const offset = box2dCenterInertia(mass > 0 ? mass : 1, cx, cy); // a mass of 0 or less is 1 to Box2D
|
|
763
843
|
const I = f(inertia + offset);
|
|
764
844
|
data.set_mass(mass);
|
|
@@ -1079,13 +1159,15 @@ class Box2dJoint
|
|
|
1079
1159
|
const bodyA = jointDef.get_bodyA(), bodyB = jointDef.get_bodyB();
|
|
1080
1160
|
const bothLive = !box2d.isNull(bodyA) && !box2d.isNull(bodyB);
|
|
1081
1161
|
ASSERT(bothLive, 'a joint needs two objects that are not destroyed');
|
|
1082
|
-
|
|
1162
|
+
const twoObjects = !bothLive || box2d.instance.getPointer(bodyA) !== box2d.instance.getPointer(bodyB);
|
|
1163
|
+
ASSERT(twoObjects, 'a joint needs two different objects');
|
|
1083
1164
|
|
|
1084
1165
|
/** @property {Object} - The Box2d joint, 0 once it is destroyed, as it is when either object is */
|
|
1085
1166
|
this.box2dJoint = 0;
|
|
1086
|
-
if (!bothLive)
|
|
1167
|
+
if (!bothLive || !twoObjects)
|
|
1087
1168
|
{
|
|
1088
|
-
// one of its objects is gone, so it is made destroyed, as it would be had it gone after
|
|
1169
|
+
// one of its objects is gone, so it is made destroyed, as it would be had it gone after; a joint of an
|
|
1170
|
+
// object to itself, which Box2D stops for good on, is made destroyed too in a release build
|
|
1089
1171
|
box2d.instance.destroy(jointDef);
|
|
1090
1172
|
return;
|
|
1091
1173
|
}
|
|
@@ -1197,7 +1279,7 @@ class Box2dTargetJoint extends Box2dJoint
|
|
|
1197
1279
|
|
|
1198
1280
|
/** Sets the joint frequency in Hertz, above 0, Box2D stops for good on 0
|
|
1199
1281
|
* @param {number} hz */
|
|
1200
|
-
setFrequency(hz) { this.box2dJoint.SetFrequency(max(hz, 1e-3)); box2dWakeJoint(this.box2dJoint); }
|
|
1282
|
+
setFrequency(hz) { this.box2dJoint.SetFrequency(max(box2dFinite(hz, 0), 1e-3)); box2dWakeJoint(this.box2dJoint); }
|
|
1201
1283
|
|
|
1202
1284
|
/** Gets the joint frequency in Hertz
|
|
1203
1285
|
* @return {number} */
|
|
@@ -1260,11 +1342,11 @@ class Box2dDistanceJoint extends Box2dJoint
|
|
|
1260
1342
|
* @return {number} */
|
|
1261
1343
|
getFrequency() { return this.box2dJoint.GetFrequency(); }
|
|
1262
1344
|
|
|
1263
|
-
/** Set the
|
|
1345
|
+
/** Set how much the spring is damped, 0 for none and 1 to stop it bouncing
|
|
1264
1346
|
* @param {number} ratio */
|
|
1265
1347
|
setDampingRatio(ratio) { this.box2dJoint.SetDampingRatio(ratio); box2dWakeJoint(this.box2dJoint); }
|
|
1266
1348
|
|
|
1267
|
-
/** Get the
|
|
1349
|
+
/** Get how much the spring is damped, 0 for none and 1 to stop it bouncing
|
|
1268
1350
|
* @return {number} */
|
|
1269
1351
|
getDampingRatio() { return this.box2dJoint.GetDampingRatio(); }
|
|
1270
1352
|
}
|
|
@@ -1393,6 +1475,7 @@ class Box2dRevoluteJoint extends Box2dJoint
|
|
|
1393
1475
|
setLimits(min, max)
|
|
1394
1476
|
{
|
|
1395
1477
|
ASSERT(min <= max, 'the lower limit must not be above the upper one');
|
|
1478
|
+
min = box2dFinite(min, 0), max = box2dFinite(max, 0); // or on NaN, which passes the order check
|
|
1396
1479
|
if (min > max) [min, max] = [max, min]; // Box2D stops on them reversed
|
|
1397
1480
|
this.box2dJoint.SetLimits(-max, -min);
|
|
1398
1481
|
}
|
|
@@ -1417,7 +1500,7 @@ class Box2dRevoluteJoint extends Box2dJoint
|
|
|
1417
1500
|
* @param {number} torque */
|
|
1418
1501
|
setMaxMotorTorque(torque) { this.box2dJoint.SetMaxMotorTorque(torque); }
|
|
1419
1502
|
|
|
1420
|
-
/** Get the
|
|
1503
|
+
/** Get the most torque the motor can apply, a magnitude
|
|
1421
1504
|
* @return {number} */
|
|
1422
1505
|
getMaxMotorTorque() { return this.box2dJoint.GetMaxMotorTorque(); }
|
|
1423
1506
|
|
|
@@ -1432,6 +1515,8 @@ class Box2dRevoluteJoint extends Box2dJoint
|
|
|
1432
1515
|
* Box2D Pin Joint
|
|
1433
1516
|
* - Pins two objects together at a point, where they still turn freely, like a nail through two boards
|
|
1434
1517
|
* - A revolute joint at that point, so it holds exactly and its limits and motor work too
|
|
1518
|
+
* - new Box2dPinJoint(objectA, objectB, pos, collide): the point defaults to objectA's position, where a revolute
|
|
1519
|
+
* joint's anchor defaults to objectB's
|
|
1435
1520
|
* @extends Box2dRevoluteJoint
|
|
1436
1521
|
* @memberof Box2D
|
|
1437
1522
|
*/
|
|
@@ -1593,6 +1678,7 @@ class Box2dPrismaticJoint extends Box2dJoint
|
|
|
1593
1678
|
setLimits(min, max)
|
|
1594
1679
|
{
|
|
1595
1680
|
ASSERT(min <= max, 'the lower limit must not be above the upper one');
|
|
1681
|
+
min = box2dFinite(min, 0), max = box2dFinite(max, 0); // or on NaN, which passes the order check
|
|
1596
1682
|
if (min > max) [min, max] = [max, min]; // Box2D stops on them reversed
|
|
1597
1683
|
this.box2dJoint.SetLimits(min, max);
|
|
1598
1684
|
}
|
|
@@ -1605,11 +1691,11 @@ class Box2dPrismaticJoint extends Box2dJoint
|
|
|
1605
1691
|
* @param {boolean} [enable] */
|
|
1606
1692
|
enableMotor(enable=true) { this.box2dJoint.EnableMotor(enable); }
|
|
1607
1693
|
|
|
1608
|
-
/** Set the motor
|
|
1694
|
+
/** Set the speed the motor drives the bodies apart along the axis, in meters per second
|
|
1609
1695
|
* @param {number} speed */
|
|
1610
1696
|
setMotorSpeed(speed) { this.box2dJoint.SetMotorSpeed(speed); }
|
|
1611
1697
|
|
|
1612
|
-
/** Get the motor
|
|
1698
|
+
/** Get the speed the motor drives the bodies apart along the axis, in meters per second
|
|
1613
1699
|
* @return {number} */
|
|
1614
1700
|
getMotorSpeed() { return this.box2dJoint.GetMotorSpeed(); }
|
|
1615
1701
|
|
|
@@ -1701,7 +1787,7 @@ class Box2dWheelJoint extends Box2dJoint
|
|
|
1701
1787
|
* @param {number} torque */
|
|
1702
1788
|
setMaxMotorTorque(torque) { this.box2dJoint.SetMaxMotorTorque(torque); }
|
|
1703
1789
|
|
|
1704
|
-
/** Get the
|
|
1790
|
+
/** Get the most torque the wheel's motor can apply, a magnitude
|
|
1705
1791
|
* @return {number} */
|
|
1706
1792
|
getMaxMotorTorque() { return this.box2dJoint.GetMaxMotorTorque(); }
|
|
1707
1793
|
|
|
@@ -1718,11 +1804,11 @@ class Box2dWheelJoint extends Box2dJoint
|
|
|
1718
1804
|
* @return {number} */
|
|
1719
1805
|
getSpringFrequencyHz() { return this.box2dJoint.GetSpringFrequencyHz(); }
|
|
1720
1806
|
|
|
1721
|
-
/** Set the spring
|
|
1807
|
+
/** Set how much the suspension spring is damped, 0 for none and 1 to stop it bouncing
|
|
1722
1808
|
* @param {number} ratio */
|
|
1723
1809
|
setSpringDampingRatio(ratio) { this.box2dJoint.SetSpringDampingRatio(ratio); box2dWakeJoint(this.box2dJoint); }
|
|
1724
1810
|
|
|
1725
|
-
/** Get the spring
|
|
1811
|
+
/** Get how much the suspension spring is damped, 0 for none and 1 to stop it bouncing
|
|
1726
1812
|
* @return {number} */
|
|
1727
1813
|
getSpringDampingRatio() { return this.box2dJoint.GetSpringDampingRatio(); }
|
|
1728
1814
|
}
|
|
@@ -1780,21 +1866,13 @@ class Box2dWeldJoint extends Box2dJoint
|
|
|
1780
1866
|
* @return {number} */
|
|
1781
1867
|
getFrequency() { return this.box2dJoint.GetFrequency(); }
|
|
1782
1868
|
|
|
1783
|
-
/** Set the
|
|
1869
|
+
/** Set how much the weld's spring is damped, 0 for none and 1 to stop it bouncing
|
|
1784
1870
|
* @param {number} ratio */
|
|
1785
1871
|
setDampingRatio(ratio) { this.box2dJoint.SetDampingRatio(ratio); box2dWakeJoint(this.box2dJoint); }
|
|
1786
1872
|
|
|
1787
|
-
/** Get the
|
|
1873
|
+
/** Get how much the weld's spring is damped, 0 for none and 1 to stop it bouncing
|
|
1788
1874
|
* @return {number} */
|
|
1789
1875
|
getDampingRatio() { return this.box2dJoint.GetDampingRatio(); }
|
|
1790
|
-
|
|
1791
|
-
/** @deprecated since 1.20, use setDampingRatio
|
|
1792
|
-
* @param {number} ratio */
|
|
1793
|
-
setSpringDampingRatio(ratio) { this.setDampingRatio(ratio); }
|
|
1794
|
-
|
|
1795
|
-
/** @deprecated since 1.20, use getDampingRatio
|
|
1796
|
-
* @return {number} */
|
|
1797
|
-
getSpringDampingRatio() { return this.getDampingRatio(); }
|
|
1798
1876
|
}
|
|
1799
1877
|
|
|
1800
1878
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -1836,7 +1914,7 @@ class Box2dFrictionJoint extends Box2dJoint
|
|
|
1836
1914
|
|
|
1837
1915
|
/** Set the maximum friction force
|
|
1838
1916
|
* @param {number} force */
|
|
1839
|
-
setMaxForce(force) { this.box2dJoint.SetMaxForce(max(force, 0)); } // Box2D stops on a negative one
|
|
1917
|
+
setMaxForce(force) { this.box2dJoint.SetMaxForce(max(box2dFinite(force, 0), 0)); } // Box2D stops on a negative one
|
|
1840
1918
|
|
|
1841
1919
|
/** Get the maximum friction force
|
|
1842
1920
|
* @return {number} */
|
|
@@ -1844,7 +1922,7 @@ class Box2dFrictionJoint extends Box2dJoint
|
|
|
1844
1922
|
|
|
1845
1923
|
/** Set the maximum friction torque
|
|
1846
1924
|
* @param {number} torque */
|
|
1847
|
-
setMaxTorque(torque) { this.box2dJoint.SetMaxTorque(max(torque, 0)); } // Box2D stops on a negative one
|
|
1925
|
+
setMaxTorque(torque) { this.box2dJoint.SetMaxTorque(max(box2dFinite(torque, 0), 0)); } // Box2D stops on a negative one
|
|
1848
1926
|
|
|
1849
1927
|
/** Get the maximum friction torque
|
|
1850
1928
|
* @return {number} */
|
|
@@ -1885,7 +1963,7 @@ class Box2dPulleyJoint extends Box2dJoint
|
|
|
1885
1963
|
jointDef.set_localAnchorA(box2dTemp(localAnchorA));
|
|
1886
1964
|
jointDef.set_localAnchorB(box2dTemp(localAnchorB));
|
|
1887
1965
|
ASSERT(ratio, 'a pulley ratio can not be 0');
|
|
1888
|
-
jointDef.set_ratio(ratio);
|
|
1966
|
+
jointDef.set_ratio(box2dFinite(ratio, 1) || 1); // Box2D stops for good on 0
|
|
1889
1967
|
jointDef.set_lengthA(groundAnchorA.distance(anchorA));
|
|
1890
1968
|
jointDef.set_lengthB(groundAnchorB.distance(anchorB));
|
|
1891
1969
|
jointDef.set_collideConnected(collide);
|
|
@@ -1946,11 +2024,11 @@ class Box2dMotorJoint extends Box2dJoint
|
|
|
1946
2024
|
super(jointDef);
|
|
1947
2025
|
}
|
|
1948
2026
|
|
|
1949
|
-
/** Set the target linear offset, in frame A, in meters
|
|
2027
|
+
/** Set the target linear offset, in frame A, in meters
|
|
1950
2028
|
* @param {Vector2} offset */
|
|
1951
2029
|
setLinearOffset(offset) { this.box2dJoint.SetLinearOffset(box2dTemp(offset)); }
|
|
1952
2030
|
|
|
1953
|
-
/** Get the target linear offset, in frame A, in meters
|
|
2031
|
+
/** Get the target linear offset, in frame A, in meters
|
|
1954
2032
|
* @return {Vector2} */
|
|
1955
2033
|
getLinearOffset() { return box2d.vec2From(this.box2dJoint.GetLinearOffset()); }
|
|
1956
2034
|
|
|
@@ -1964,7 +2042,7 @@ class Box2dMotorJoint extends Box2dJoint
|
|
|
1964
2042
|
|
|
1965
2043
|
/** Set the maximum force
|
|
1966
2044
|
* @param {number} force */
|
|
1967
|
-
setMaxForce(force) { this.box2dJoint.SetMaxForce(max(force, 0)); box2dWakeJoint(this.box2dJoint); } // Box2D stops on a negative one
|
|
2045
|
+
setMaxForce(force) { this.box2dJoint.SetMaxForce(max(box2dFinite(force, 0), 0)); box2dWakeJoint(this.box2dJoint); } // Box2D stops on a negative one
|
|
1968
2046
|
|
|
1969
2047
|
/** Get the maximum force
|
|
1970
2048
|
* @return {number} */
|
|
@@ -1972,7 +2050,7 @@ class Box2dMotorJoint extends Box2dJoint
|
|
|
1972
2050
|
|
|
1973
2051
|
/** Set the maximum torque
|
|
1974
2052
|
* @param {number} torque */
|
|
1975
|
-
setMaxTorque(torque) { this.box2dJoint.SetMaxTorque(max(torque, 0)); box2dWakeJoint(this.box2dJoint); } // Box2D stops on a negative one
|
|
2053
|
+
setMaxTorque(torque) { this.box2dJoint.SetMaxTorque(max(box2dFinite(torque, 0), 0)); box2dWakeJoint(this.box2dJoint); } // Box2D stops on a negative one
|
|
1976
2054
|
|
|
1977
2055
|
/** Get the maximum torque
|
|
1978
2056
|
* @return {number} */
|
|
@@ -2322,15 +2400,17 @@ class Box2dPlugin
|
|
|
2322
2400
|
// helper functions
|
|
2323
2401
|
|
|
2324
2402
|
/** converts a box2d vec2 to a Vector2
|
|
2325
|
-
* @param {Object} v
|
|
2403
|
+
* @param {Object} v
|
|
2404
|
+
* @return {Vector2} */
|
|
2326
2405
|
vec2From(v)
|
|
2327
2406
|
{
|
|
2328
|
-
ASSERT(v instanceof box2d.instance.b2Vec2);
|
|
2407
|
+
ASSERT(v instanceof box2d.instance.b2Vec2, 'vec2From: expected a b2Vec2', v);
|
|
2329
2408
|
return new Vector2(v.get_x(), v.get_y());
|
|
2330
2409
|
}
|
|
2331
2410
|
|
|
2332
2411
|
/** converts a box2d vec2 pointer to a Vector2
|
|
2333
|
-
* @param {Object} vp
|
|
2412
|
+
* @param {Object} vp
|
|
2413
|
+
* @return {Vector2} */
|
|
2334
2414
|
vec2FromPointer(vp)
|
|
2335
2415
|
{
|
|
2336
2416
|
const v = box2d.instance.wrapPointer(vp, box2d.instance.b2Vec2);
|
|
@@ -2339,19 +2419,22 @@ class Box2dPlugin
|
|
|
2339
2419
|
|
|
2340
2420
|
/** converts a Vector2 to a new box2d vec2, which stays until destroyed with box2d.instance.destroy;
|
|
2341
2421
|
* the plugin itself passes Box2D reused ones, since Box2D copies every vector it is given
|
|
2342
|
-
* @param {Vector2} v
|
|
2422
|
+
* @param {Vector2} v
|
|
2423
|
+
* @return {Object} - A Box2D vector, its b2Vec2 */
|
|
2343
2424
|
vec2dTo(v)
|
|
2344
2425
|
{
|
|
2345
|
-
ASSERT(isVector2(v));
|
|
2426
|
+
ASSERT(isVector2(v), 'vec2dTo: expected a vec2', v);
|
|
2346
2427
|
return new box2d.instance.b2Vec2(v.x, v.y);
|
|
2347
2428
|
}
|
|
2348
2429
|
|
|
2349
2430
|
/** checks if a box2d object is null
|
|
2350
|
-
* @param {Object} o
|
|
2431
|
+
* @param {Object} o
|
|
2432
|
+
* @return {boolean} */
|
|
2351
2433
|
isNull(o) { return !box2d.instance.getPointer(o); }
|
|
2352
2434
|
|
|
2353
2435
|
/** casts a box2d object to a shape type
|
|
2354
|
-
* @param {Object} o
|
|
2436
|
+
* @param {Object} o
|
|
2437
|
+
* @return {Object} - The shape as its own Box2D type */
|
|
2355
2438
|
castShapeObject(o)
|
|
2356
2439
|
{
|
|
2357
2440
|
switch (o.GetType())
|
|
@@ -2370,7 +2453,8 @@ class Box2dPlugin
|
|
|
2370
2453
|
}
|
|
2371
2454
|
|
|
2372
2455
|
/** casts a box2d object to a joint type
|
|
2373
|
-
* @param {Object} o
|
|
2456
|
+
* @param {Object} o
|
|
2457
|
+
* @return {Object} - The joint as its own Box2D type */
|
|
2374
2458
|
castJointObject(o)
|
|
2375
2459
|
{
|
|
2376
2460
|
switch (o.GetType())
|
|
@@ -2436,6 +2520,7 @@ async function box2dInit()
|
|
|
2436
2520
|
{
|
|
2437
2521
|
if (o.body)
|
|
2438
2522
|
{
|
|
2523
|
+
debug && box2dCheckUnusedFields(o);
|
|
2439
2524
|
// moved in place, as the engine moves an EngineObject's pos, so what holds it follows the body;
|
|
2440
2525
|
// box2d uses reverse angle
|
|
2441
2526
|
const p = o.body.GetPosition();
|