emeraldengine 3.0.0 → 3.1.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/README.md +1498 -1659
- package/dist/types/index.d.ts +4 -1
- package/dist/types/src/Animator.d.ts +1 -1
- package/dist/types/src/CollisionLayers.d.ts +2 -2
- package/dist/types/src/Color.d.ts +1 -0
- package/dist/types/src/Drawable.d.ts +1 -1
- package/dist/types/src/EmeraldDB.d.ts +2 -2
- package/dist/types/src/InstancedTexture.d.ts +17 -2
- package/dist/types/src/Material.d.ts +2 -2
- package/dist/types/src/MathUtils.d.ts +2 -1
- package/dist/types/src/ParticleEmitter.d.ts +1 -1
- package/dist/types/src/Physics.d.ts +148 -18
- package/dist/types/src/Scene.d.ts +1 -1
- package/dist/types/src/Shaders.d.ts +2 -2
- package/dist/types/src/Tilemap.d.ts +1 -1
- package/dist/types/src/UI.d.ts +1 -1
- package/dist/types/src/components/Behaviour.d.ts +2 -2
- package/dist/types/src/components/Collider.d.ts +7 -1
- package/dist/types/src/components/GameObject.d.ts +2 -2
- package/dist/types/src/components/PolygonCollider.d.ts +33 -0
- package/dist/types/src/components/RigidBody.d.ts +281 -8
- package/dist/types/src/importers/Aseprite.d.ts +2 -2
- package/dist/types/src/importers/ForgeLevel.d.ts +97 -0
- package/dist/types/src/importers/TiledMap.d.ts +1 -1
- package/dist/types/src/managers/EventManager.d.ts +1 -1
- package/dist/types/src/managers/Gamepad.d.ts +102 -0
- package/dist/types/src/managers/InputManager.d.ts +93 -2
- package/dist/types/src/managers/NetworkManager.d.ts +2 -2
- package/dist/types/src/managers/RenderStats.d.ts +1 -1
- package/dist/types/src/managers/TextureManager.d.ts +1 -1
- package/dist/types/src/physics/AABB.d.ts +92 -0
- package/dist/types/src/physics/Body.d.ts +435 -0
- package/dist/types/src/physics/BodyType.d.ts +6 -0
- package/dist/types/src/physics/BroadPhase.d.ts +210 -0
- package/dist/types/src/physics/Collision.d.ts +102 -0
- package/dist/types/src/physics/Contact.d.ts +206 -0
- package/dist/types/src/physics/ContactSolver.d.ts +108 -0
- package/dist/types/src/physics/Distance.d.ts +54 -0
- package/dist/types/src/physics/DistanceJoint.d.ts +90 -0
- package/dist/types/src/physics/Fixture.d.ts +221 -0
- package/dist/types/src/physics/Island.d.ts +52 -0
- package/dist/types/src/physics/Joint.d.ts +59 -0
- package/dist/types/src/physics/Math2D.d.ts +371 -0
- package/dist/types/src/physics/RevoluteJoint.d.ts +119 -0
- package/dist/types/src/physics/Settings.d.ts +22 -0
- package/dist/types/src/physics/Shapes.d.ts +207 -0
- package/dist/types/src/physics/TimeOfImpact.d.ts +22 -0
- package/dist/types/src/physics/World.d.ts +274 -0
- package/dist/types/src/physics/index.d.ts +34 -0
- package/index.js +6 -0
- package/package.json +2 -3
- package/src/Animator.js +1 -1
- package/src/CollisionLayers.js +3 -3
- package/src/Color.js +8 -0
- package/src/Drawable.js +1 -1
- package/src/Emerald.js +1 -1
- package/src/EmeraldDB.js +2 -2
- package/src/InstancedTexture.js +57 -9
- package/src/Material.js +2 -2
- package/src/MathUtils.js +2 -1
- package/src/ParticleEmitter.js +1 -1
- package/src/Physics.js +270 -60
- package/src/Scene.js +1 -1
- package/src/Shaders.js +20 -20
- package/src/Tilemap.js +1 -1
- package/src/UI.js +1 -1
- package/src/components/Behaviour.js +2 -2
- package/src/components/BoxCollider.js +7 -9
- package/src/components/BoxColliderDebug.js +3 -4
- package/src/components/CircleCollider.js +7 -9
- package/src/components/CircleColliderDebug.js +3 -2
- package/src/components/Collider.js +13 -3
- package/src/components/GameObject.js +2 -2
- package/src/components/PolygonCollider.js +55 -0
- package/src/components/RigidBody.js +441 -14
- package/src/importers/Aseprite.js +2 -2
- package/src/importers/ForgeLevel.js +581 -0
- package/src/importers/TiledMap.js +1 -1
- package/src/managers/EventManager.js +1 -1
- package/src/managers/Gamepad.js +126 -0
- package/src/managers/InputManager.js +129 -3
- package/src/managers/NetworkManager.js +2 -2
- package/src/managers/RenderStats.js +1 -1
- package/src/managers/TextureManager.js +1 -1
- package/src/physics/AABB.js +207 -0
- package/src/physics/Body.js +862 -0
- package/src/physics/BodyType.js +16 -0
- package/src/physics/BroadPhase.js +641 -0
- package/src/physics/Collision.js +534 -0
- package/src/physics/Contact.js +500 -0
- package/src/physics/ContactSolver.js +526 -0
- package/src/physics/Distance.js +403 -0
- package/src/physics/DistanceJoint.js +227 -0
- package/src/physics/Fixture.js +346 -0
- package/src/physics/Island.js +203 -0
- package/src/physics/Joint.js +78 -0
- package/src/physics/Math2D.js +573 -0
- package/src/physics/RevoluteJoint.js +278 -0
- package/src/physics/Settings.js +78 -0
- package/src/physics/Shapes.js +549 -0
- package/src/physics/TimeOfImpact.js +87 -0
- package/src/physics/World.js +731 -0
- package/src/physics/index.js +79 -0
|
@@ -14,11 +14,12 @@ class CircleColliderDebug {
|
|
|
14
14
|
this.physics = this.rigidbody.physics;
|
|
15
15
|
this.scale = this.physics.getScale();
|
|
16
16
|
this.color = color || new Color(255, 0, 0, 255);
|
|
17
|
+
const body = this.rigidbody.getBody();
|
|
17
18
|
this.gameObject = new GameObject(
|
|
18
19
|
"CircleColliderDebug",
|
|
19
20
|
new Vector3(
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
body.getPosition().x * this.scale,
|
|
22
|
+
body.getPosition().y * this.scale,
|
|
22
23
|
100
|
|
23
24
|
),
|
|
24
25
|
this.rigidbody.getAngle(),
|
|
@@ -23,19 +23,29 @@ class Collider {
|
|
|
23
23
|
* @method syncDebugShape
|
|
24
24
|
* @description Mirrors a transform onto the debug shape, but only if one has
|
|
25
25
|
* already been created. Never forces lazy creation.
|
|
26
|
+
*
|
|
27
|
+
* The rigidbody's spawn offset is added back, because the collider sits at
|
|
28
|
+
* `transform + offset` while the transform tracks the renderable. Without it
|
|
29
|
+
* the debug shape would drift away from the collider it is supposed to be
|
|
30
|
+
* showing on any body built with an offset.
|
|
31
|
+
*
|
|
26
32
|
* @param {Transform} transform - The source transform
|
|
27
33
|
*/
|
|
28
34
|
syncDebugShape(transform) {
|
|
29
35
|
if (!this._debugShape) return;
|
|
30
36
|
const t = this._debugShape.gameObject.transform;
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
const offset =
|
|
38
|
+
this.rigidbody && typeof this.rigidbody.getOffset === "function"
|
|
39
|
+
? this.rigidbody.getOffset()
|
|
40
|
+
: null;
|
|
41
|
+
t.position.x = transform.position.x + (offset ? offset.x : 0);
|
|
42
|
+
t.position.y = transform.position.y + (offset ? offset.y : 0);
|
|
33
43
|
t.rotation = transform.rotation;
|
|
34
44
|
}
|
|
35
45
|
|
|
36
46
|
/**
|
|
37
47
|
* @method setFilter
|
|
38
|
-
* @description Sets the raw
|
|
48
|
+
* @description Sets the raw collision filter on this collider's
|
|
39
49
|
* fixture. Two fixtures collide only when each one's category bit is present
|
|
40
50
|
* in the other's mask. Subclasses must have created `this.collider`
|
|
41
51
|
* (the fixture) first.
|
|
@@ -45,7 +45,7 @@ class GameObject {
|
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
47
|
* @method setScreenSpace
|
|
48
|
-
* @description When true, the object ignores the camera (fixed on screen)
|
|
48
|
+
* @description When true, the object ignores the camera (fixed on screen),
|
|
49
49
|
* useful for HUD/UI. Position is then in pixels from the viewport center.
|
|
50
50
|
* Note: not supported for InstancedTexture-based objects.
|
|
51
51
|
* @param {boolean} value
|
|
@@ -223,7 +223,7 @@ class GameObject {
|
|
|
223
223
|
* @description Permanently tears the object down: disposes every Drawable's
|
|
224
224
|
* GPU resources, destroys physics bodies, and runs Behaviour.onDestroy().
|
|
225
225
|
* Use it (or Scene.remove(obj, { dispose: true })) when an object will not
|
|
226
|
-
* be re-added
|
|
226
|
+
* be re-added: plain Scene.remove() keeps GPU resources alive for re-use.
|
|
227
227
|
* Safe to call twice.
|
|
228
228
|
*/
|
|
229
229
|
destroy() {
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { PolygonShape } from "../physics/index.js";
|
|
2
|
+
import Collider from "./Collider.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @class PolygonCollider
|
|
6
|
+
* @extends Collider
|
|
7
|
+
* @description A convex-polygon fixture, for collision shapes a box or
|
|
8
|
+
* circle can't approximate, like ramps, wedges, or arbitrary tile outlines (see
|
|
9
|
+
* {@link ForgeLevel}). Points outside the convex hull of what you pass are
|
|
10
|
+
* dropped automatically; a concave shape needs more than one collider.
|
|
11
|
+
* @param {Rigidbody} rigidbody - The rigidbody to attach the collider to
|
|
12
|
+
* @param {Array<{x:number,y:number}>} points - Local-space points, in
|
|
13
|
+
* physics units, in any order
|
|
14
|
+
* @param {number} density - The density of the collider
|
|
15
|
+
* @param {number} friction - The friction of the collider
|
|
16
|
+
* @param {number} restitution - The restitution of the collider
|
|
17
|
+
* @param {boolean} [isSensor=false] - Whether the collider is a sensor
|
|
18
|
+
* @param {GameObject} [parentObject=null] - The parent object of the collider
|
|
19
|
+
* @param {Object} [filter=null] - Collision filter spec, see {@link Collider#setFilter}
|
|
20
|
+
*/
|
|
21
|
+
class PolygonCollider extends Collider {
|
|
22
|
+
constructor(
|
|
23
|
+
rigidbody,
|
|
24
|
+
points,
|
|
25
|
+
density,
|
|
26
|
+
friction,
|
|
27
|
+
restitution,
|
|
28
|
+
isSensor = false,
|
|
29
|
+
parentObject = null,
|
|
30
|
+
filter = null
|
|
31
|
+
) {
|
|
32
|
+
super(rigidbody, isSensor, parentObject);
|
|
33
|
+
this.collider = rigidbody.createFixture(new PolygonShape(points), {
|
|
34
|
+
density: density,
|
|
35
|
+
friction: friction,
|
|
36
|
+
restitution: restitution,
|
|
37
|
+
isSensor: isSensor,
|
|
38
|
+
});
|
|
39
|
+
this.points = points;
|
|
40
|
+
this.rigidbody.setCollider(this);
|
|
41
|
+
this.name = "PolygonCollider" + this.id;
|
|
42
|
+
this._applyFilterSpec(filter);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @method getPoints
|
|
47
|
+
* @description Returns the local-space points this collider was built from
|
|
48
|
+
* @returns {Array<{x:number,y:number}>}
|
|
49
|
+
*/
|
|
50
|
+
getPoints() {
|
|
51
|
+
return this.points;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export default PolygonCollider;
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Vec2 } from "../physics/index.js";
|
|
2
2
|
import IDManager from "../managers/IDManager.js";
|
|
3
3
|
import { Vector2 } from "../Physics.js";
|
|
4
4
|
import Collider from "./Collider.js";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @class RigidBody
|
|
8
|
+
* @description The game-facing physics body: everything you can do to a body
|
|
9
|
+
* (move it, push it, spin it, sleep it, query its mass) is a method on this
|
|
10
|
+
* class directly, in world/pixel units. There is no separate lower-level
|
|
11
|
+
* body object you need to fetch first. `getBody()` still returns the raw,
|
|
12
|
+
* physics-unit {@link Body} underneath for the rare case you need it (writing
|
|
13
|
+
* a custom joint, say), but nothing in ordinary use requires it.
|
|
8
14
|
* @param {Physics} physics - The physics engine
|
|
9
15
|
* @param {string | "static" | "dynamic" | "kinematic"} type - The type of rigidbody
|
|
10
16
|
* @param {Vector2} position - The position of the rigidbody
|
|
@@ -26,7 +32,7 @@ class RigidBody {
|
|
|
26
32
|
this.type = type;
|
|
27
33
|
this.body = physics.world.createBody({
|
|
28
34
|
type: type,
|
|
29
|
-
position: new
|
|
35
|
+
position: new Vec2(
|
|
30
36
|
(position.x + offset.x) / physics.scale,
|
|
31
37
|
(position.y + offset.y) / physics.scale
|
|
32
38
|
),
|
|
@@ -37,6 +43,8 @@ class RigidBody {
|
|
|
37
43
|
this.collider = null;
|
|
38
44
|
this.id = IDManager.generateUniqueID();
|
|
39
45
|
this.name = "RigidBody" + this.id;
|
|
46
|
+
/** Freely usable by your own code; see {@link RigidBody#getUserData}. */
|
|
47
|
+
this.userData = null;
|
|
40
48
|
|
|
41
49
|
this.body.setUserData(this);
|
|
42
50
|
}
|
|
@@ -48,13 +56,41 @@ class RigidBody {
|
|
|
48
56
|
*/
|
|
49
57
|
updatePosition(position) {
|
|
50
58
|
this.body.setPosition(
|
|
51
|
-
new
|
|
59
|
+
new Vec2(
|
|
52
60
|
(position.x + this.offset.x) / this.physics.scale,
|
|
53
61
|
(position.y + this.offset.y) / this.physics.scale
|
|
54
62
|
)
|
|
55
63
|
);
|
|
56
64
|
}
|
|
57
65
|
|
|
66
|
+
/**
|
|
67
|
+
* @method setPosition
|
|
68
|
+
* @description Alias of {@link RigidBody#updatePosition}, named to match
|
|
69
|
+
* `setRotation`/`setTransform`.
|
|
70
|
+
* @param {Vector2} position - The new position, in world (pixel) units
|
|
71
|
+
*/
|
|
72
|
+
setPosition(position) {
|
|
73
|
+
this.updatePosition(position);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @method setTransform
|
|
78
|
+
* @description Teleports the body to a new position and angle in one move
|
|
79
|
+
* (no velocity implied), and wakes it so contacts at the new spot are seen
|
|
80
|
+
* on the very next step.
|
|
81
|
+
* @param {Vector2} position - World (pixel) units
|
|
82
|
+
* @param {number} angle - Radians
|
|
83
|
+
*/
|
|
84
|
+
setTransform(position, angle) {
|
|
85
|
+
this.body.setTransform(
|
|
86
|
+
new Vec2(
|
|
87
|
+
(position.x + this.offset.x) / this.physics.scale,
|
|
88
|
+
(position.y + this.offset.y) / this.physics.scale
|
|
89
|
+
),
|
|
90
|
+
angle
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
58
94
|
/**
|
|
59
95
|
* @method getWorldX
|
|
60
96
|
* @description The single source of truth for body(physics) -> world(pixel)
|
|
@@ -111,6 +147,29 @@ class RigidBody {
|
|
|
111
147
|
}
|
|
112
148
|
}
|
|
113
149
|
|
|
150
|
+
/**
|
|
151
|
+
* @method createFixture
|
|
152
|
+
* @description Attaches a shape directly, bypassing the Collider component
|
|
153
|
+
* classes ({@link BoxCollider}, {@link CircleCollider}, {@link PolygonCollider})
|
|
154
|
+
* that normally build one for you. `shape` is a physics-unit shape (e.g. from
|
|
155
|
+
* `Box()`/`Circle()`/`new PolygonShape()`), not pixels.
|
|
156
|
+
* @param {Shape} shape
|
|
157
|
+
* @param {Object|number} [def] - `{ density, friction, restitution, isSensor, ... }`
|
|
158
|
+
* @returns {Fixture}
|
|
159
|
+
*/
|
|
160
|
+
createFixture(shape, def = {}) {
|
|
161
|
+
return this.body.createFixture(shape, def);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* @method destroyFixture
|
|
166
|
+
* @description Removes a fixture created with {@link RigidBody#createFixture}.
|
|
167
|
+
* @param {Fixture} fixture
|
|
168
|
+
*/
|
|
169
|
+
destroyFixture(fixture) {
|
|
170
|
+
this.body.destroyFixture(fixture);
|
|
171
|
+
}
|
|
172
|
+
|
|
114
173
|
/**
|
|
115
174
|
* @method setRotation
|
|
116
175
|
* @description Sets the rotation of the rigidbody
|
|
@@ -129,7 +188,7 @@ class RigidBody {
|
|
|
129
188
|
*/
|
|
130
189
|
setLinearVelocity(vx, vy) {
|
|
131
190
|
this.body.setLinearVelocity(
|
|
132
|
-
new
|
|
191
|
+
new Vec2(vx / this.physics.scale, vy / this.physics.scale)
|
|
133
192
|
);
|
|
134
193
|
}
|
|
135
194
|
|
|
@@ -143,20 +202,115 @@ class RigidBody {
|
|
|
143
202
|
return { x: v.x * this.physics.scale, y: v.y * this.physics.scale };
|
|
144
203
|
}
|
|
145
204
|
|
|
205
|
+
/**
|
|
206
|
+
* @method getLinearVelocityFromWorldPoint
|
|
207
|
+
* @description The velocity (world units/sec) of the material point of this
|
|
208
|
+
* body currently at `worldPoint`: linear velocity plus the contribution
|
|
209
|
+
* from spin. Useful for e.g. where a spinning platform's edge is moving.
|
|
210
|
+
* @param {Object} worldPoint - World (pixel) units
|
|
211
|
+
* @returns {Vector2}
|
|
212
|
+
*/
|
|
213
|
+
getLinearVelocityFromWorldPoint(worldPoint) {
|
|
214
|
+
const scale = this.physics.scale;
|
|
215
|
+
const v = this.body.getLinearVelocityFromWorldPoint(
|
|
216
|
+
new Vec2(worldPoint.x / scale, worldPoint.y / scale)
|
|
217
|
+
);
|
|
218
|
+
return new Vector2(v.x * scale, v.y * scale);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* @method setAngularVelocity
|
|
223
|
+
* @description Sets the body's spin, in radians per second.
|
|
224
|
+
* @param {number} omega
|
|
225
|
+
*/
|
|
226
|
+
setAngularVelocity(omega) {
|
|
227
|
+
this.body.setAngularVelocity(omega);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* @method getAngularVelocity
|
|
232
|
+
* @description Returns the body's spin, in radians per second.
|
|
233
|
+
* @returns {number}
|
|
234
|
+
*/
|
|
235
|
+
getAngularVelocity() {
|
|
236
|
+
return this.body.getAngularVelocity();
|
|
237
|
+
}
|
|
238
|
+
|
|
146
239
|
/**
|
|
147
240
|
* @method applyImpulse
|
|
148
|
-
* @description Applies
|
|
241
|
+
* @description Applies an instantaneous change in momentum (world units).
|
|
242
|
+
* This is what a jump or a knockback should use, since (unlike a force) it
|
|
243
|
+
* takes effect immediately rather than accumulating over the step.
|
|
149
244
|
* @param {number} ix
|
|
150
245
|
* @param {number} iy
|
|
246
|
+
* @param {Object} [point] - World (pixel) point to apply it at; defaults to
|
|
247
|
+
* the center of mass (no torque)
|
|
248
|
+
* @param {boolean} [wake=true]
|
|
151
249
|
*/
|
|
152
|
-
applyImpulse(ix, iy) {
|
|
250
|
+
applyImpulse(ix, iy, point = null, wake = true) {
|
|
251
|
+
const scale = this.physics.scale;
|
|
153
252
|
this.body.applyLinearImpulse(
|
|
154
|
-
new
|
|
155
|
-
|
|
156
|
-
|
|
253
|
+
new Vec2(ix / scale, iy / scale),
|
|
254
|
+
point
|
|
255
|
+
? new Vec2(point.x / scale, point.y / scale)
|
|
256
|
+
: this.body.getWorldCenter(),
|
|
257
|
+
wake
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* @method applyAngularImpulse
|
|
263
|
+
* @description Applies an instantaneous change in angular momentum.
|
|
264
|
+
* @param {number} impulse
|
|
265
|
+
* @param {boolean} [wake=true]
|
|
266
|
+
*/
|
|
267
|
+
applyAngularImpulse(impulse, wake = true) {
|
|
268
|
+
this.body.applyAngularImpulse(impulse, wake);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* @method applyForce
|
|
273
|
+
* @description Applies a force (world units) at a world point. Forces
|
|
274
|
+
* accumulate and are cleared at the end of every step, so this belongs in
|
|
275
|
+
* your update loop, unlike an impulse.
|
|
276
|
+
* @param {number} fx
|
|
277
|
+
* @param {number} fy
|
|
278
|
+
* @param {Object} [point] - World (pixel) point; defaults to the center of
|
|
279
|
+
* mass (no torque)
|
|
280
|
+
* @param {boolean} [wake=true]
|
|
281
|
+
*/
|
|
282
|
+
applyForce(fx, fy, point = null, wake = true) {
|
|
283
|
+
const scale = this.physics.scale;
|
|
284
|
+
this.body.applyForce(
|
|
285
|
+
new Vec2(fx / scale, fy / scale),
|
|
286
|
+
point ? new Vec2(point.x / scale, point.y / scale) : null,
|
|
287
|
+
wake
|
|
157
288
|
);
|
|
158
289
|
}
|
|
159
290
|
|
|
291
|
+
/**
|
|
292
|
+
* @method applyForceToCenter
|
|
293
|
+
* @description Applies a force (world units) at the center of mass: no
|
|
294
|
+
* torque, unlike {@link RigidBody#applyForce} with a point.
|
|
295
|
+
* @param {number} fx
|
|
296
|
+
* @param {number} fy
|
|
297
|
+
* @param {boolean} [wake=true]
|
|
298
|
+
*/
|
|
299
|
+
applyForceToCenter(fx, fy, wake = true) {
|
|
300
|
+
const scale = this.physics.scale;
|
|
301
|
+
this.body.applyForceToCenter(new Vec2(fx / scale, fy / scale), wake);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* @method applyTorque
|
|
306
|
+
* @description Applies a torque about the center of mass.
|
|
307
|
+
* @param {number} torque
|
|
308
|
+
* @param {boolean} [wake=true]
|
|
309
|
+
*/
|
|
310
|
+
applyTorque(torque, wake = true) {
|
|
311
|
+
this.body.applyTorque(torque, wake);
|
|
312
|
+
}
|
|
313
|
+
|
|
160
314
|
/**
|
|
161
315
|
* @method setAwake
|
|
162
316
|
* @description Wakes or sleeps the body.
|
|
@@ -166,13 +320,74 @@ class RigidBody {
|
|
|
166
320
|
this.body.setAwake(awake);
|
|
167
321
|
}
|
|
168
322
|
|
|
323
|
+
/**
|
|
324
|
+
* @method isAwake
|
|
325
|
+
* @description Whether the body is currently simulated.
|
|
326
|
+
* @returns {boolean}
|
|
327
|
+
*/
|
|
328
|
+
isAwake() {
|
|
329
|
+
return this.body.isAwake();
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* @method setSleepingAllowed
|
|
334
|
+
* @description Allows or forbids this body from ever sleeping.
|
|
335
|
+
* @param {boolean} flag
|
|
336
|
+
*/
|
|
337
|
+
setSleepingAllowed(flag) {
|
|
338
|
+
this.body.setSleepingAllowed(flag);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* @method isSleepingAllowed
|
|
343
|
+
* @returns {boolean}
|
|
344
|
+
*/
|
|
345
|
+
isSleepingAllowed() {
|
|
346
|
+
return this.body.isSleepingAllowed();
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* @method setActive
|
|
351
|
+
* @description Adds or removes the body from collision detection without
|
|
352
|
+
* destroying it.
|
|
353
|
+
* @param {boolean} flag
|
|
354
|
+
*/
|
|
355
|
+
setActive(flag) {
|
|
356
|
+
this.body.setActive(flag);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* @method isActive
|
|
361
|
+
* @returns {boolean}
|
|
362
|
+
*/
|
|
363
|
+
isActive() {
|
|
364
|
+
return this.body.isActive();
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* @method setFixedRotation
|
|
369
|
+
* @description Locks or unlocks the body's rotation at runtime.
|
|
370
|
+
* @param {boolean} flag
|
|
371
|
+
*/
|
|
372
|
+
setFixedRotation(flag) {
|
|
373
|
+
this.body.setFixedRotation(flag);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* @method isFixedRotation
|
|
378
|
+
* @returns {boolean}
|
|
379
|
+
*/
|
|
380
|
+
isFixedRotation() {
|
|
381
|
+
return this.body.isFixedRotation();
|
|
382
|
+
}
|
|
383
|
+
|
|
169
384
|
/**
|
|
170
385
|
* @method setContinuous
|
|
171
386
|
* @description Enables continuous collision detection (CCD) for this body by
|
|
172
387
|
* marking it a "bullet". Fast-moving bodies (e.g. a dash, a projectile, a
|
|
173
388
|
* player falling at high speed) otherwise sweep so far in a single fixed step
|
|
174
|
-
* that they tunnel straight through thin static geometry; with CCD on,
|
|
175
|
-
*
|
|
389
|
+
* that they tunnel straight through thin static geometry; with CCD on, the
|
|
390
|
+
* engine sweeps the body against static geometry so it stops at the wall
|
|
176
391
|
* instead of teleporting past it. Costs more per step, so reserve it for the
|
|
177
392
|
* handful of bodies that actually move fast.
|
|
178
393
|
* @param {boolean} [enabled=true]
|
|
@@ -192,6 +407,202 @@ class RigidBody {
|
|
|
192
407
|
return this.body.isBullet();
|
|
193
408
|
}
|
|
194
409
|
|
|
410
|
+
/**
|
|
411
|
+
* @method setLinearDamping
|
|
412
|
+
* @description Sets the drag applied to linear motion each step.
|
|
413
|
+
* @param {number} damping
|
|
414
|
+
*/
|
|
415
|
+
setLinearDamping(damping) {
|
|
416
|
+
this.body.setLinearDamping(damping);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* @method getLinearDamping
|
|
421
|
+
* @returns {number}
|
|
422
|
+
*/
|
|
423
|
+
getLinearDamping() {
|
|
424
|
+
return this.body.getLinearDamping();
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* @method setAngularDamping
|
|
429
|
+
* @description Sets the drag applied to rotation each step.
|
|
430
|
+
* @param {number} damping
|
|
431
|
+
*/
|
|
432
|
+
setAngularDamping(damping) {
|
|
433
|
+
this.body.setAngularDamping(damping);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* @method getAngularDamping
|
|
438
|
+
* @returns {number}
|
|
439
|
+
*/
|
|
440
|
+
getAngularDamping() {
|
|
441
|
+
return this.body.getAngularDamping();
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* @method setGravityScale
|
|
446
|
+
* @description Scales how strongly gravity pulls on this body (0 disables
|
|
447
|
+
* it, 2 makes it twice as heavy-feeling).
|
|
448
|
+
* @param {number} scale
|
|
449
|
+
*/
|
|
450
|
+
setGravityScale(scale) {
|
|
451
|
+
this.body.setGravityScale(scale);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* @method getGravityScale
|
|
456
|
+
* @returns {number}
|
|
457
|
+
*/
|
|
458
|
+
getGravityScale() {
|
|
459
|
+
return this.body.getGravityScale();
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* @method getMass
|
|
464
|
+
* @description Returns the body's mass, in physics units (derived from its
|
|
465
|
+
* fixtures' shapes and densities, unaffected by the pixel scale).
|
|
466
|
+
* @returns {number}
|
|
467
|
+
*/
|
|
468
|
+
getMass() {
|
|
469
|
+
return this.body.getMass();
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* @method getInertia
|
|
474
|
+
* @description Returns the body's rotational inertia about its center of
|
|
475
|
+
* mass, in physics units.
|
|
476
|
+
* @returns {number}
|
|
477
|
+
*/
|
|
478
|
+
getInertia() {
|
|
479
|
+
return this.body.getInertia();
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* @method resetMassData
|
|
484
|
+
* @description Re-derives mass/center/inertia from the body's current
|
|
485
|
+
* fixtures. Call this after changing a fixture's density at runtime.
|
|
486
|
+
*/
|
|
487
|
+
resetMassData() {
|
|
488
|
+
this.body.resetMassData();
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* @method setMassData
|
|
493
|
+
* @description Overrides the computed mass properties directly.
|
|
494
|
+
* @param {Object} massData - `{ mass, center, I }`; `center` is a world
|
|
495
|
+
* (pixel) offset from the body's origin
|
|
496
|
+
*/
|
|
497
|
+
setMassData(massData) {
|
|
498
|
+
const scale = this.physics.scale;
|
|
499
|
+
const center = massData.center || { x: 0, y: 0 };
|
|
500
|
+
this.body.setMassData({
|
|
501
|
+
mass: massData.mass,
|
|
502
|
+
center: new Vec2(center.x / scale, center.y / scale),
|
|
503
|
+
I: massData.I,
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* @method getWorldPoint
|
|
509
|
+
* @description Converts a point local to this body into world (pixel) space.
|
|
510
|
+
* @param {Object} localPoint - World-unit offset from the body's origin
|
|
511
|
+
* @returns {Vector2}
|
|
512
|
+
*/
|
|
513
|
+
getWorldPoint(localPoint) {
|
|
514
|
+
const scale = this.physics.scale;
|
|
515
|
+
const p = this.body.getWorldPoint(
|
|
516
|
+
new Vec2(localPoint.x / scale, localPoint.y / scale)
|
|
517
|
+
);
|
|
518
|
+
return new Vector2(p.x * scale, p.y * scale);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* @method getLocalPoint
|
|
523
|
+
* @description Converts a world (pixel) point into this body's local frame.
|
|
524
|
+
* @param {Object} worldPoint - World (pixel) units
|
|
525
|
+
* @returns {Vector2}
|
|
526
|
+
*/
|
|
527
|
+
getLocalPoint(worldPoint) {
|
|
528
|
+
const scale = this.physics.scale;
|
|
529
|
+
const p = this.body.getLocalPoint(
|
|
530
|
+
new Vec2(worldPoint.x / scale, worldPoint.y / scale)
|
|
531
|
+
);
|
|
532
|
+
return new Vector2(p.x * scale, p.y * scale);
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* @method getWorldVector
|
|
537
|
+
* @description Rotates a local direction (not a point, unaffected by the
|
|
538
|
+
* body's position) into world space.
|
|
539
|
+
* @param {Object} localVector
|
|
540
|
+
* @returns {Vector2}
|
|
541
|
+
*/
|
|
542
|
+
getWorldVector(localVector) {
|
|
543
|
+
const scale = this.physics.scale;
|
|
544
|
+
const v = this.body.getWorldVector(
|
|
545
|
+
new Vec2(localVector.x / scale, localVector.y / scale)
|
|
546
|
+
);
|
|
547
|
+
return new Vector2(v.x * scale, v.y * scale);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* @method getLocalVector
|
|
552
|
+
* @description Rotates a world direction into this body's local frame.
|
|
553
|
+
* @param {Object} worldVector
|
|
554
|
+
* @returns {Vector2}
|
|
555
|
+
*/
|
|
556
|
+
getLocalVector(worldVector) {
|
|
557
|
+
const scale = this.physics.scale;
|
|
558
|
+
const v = this.body.getLocalVector(
|
|
559
|
+
new Vec2(worldVector.x / scale, worldVector.y / scale)
|
|
560
|
+
);
|
|
561
|
+
return new Vector2(v.x * scale, v.y * scale);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* @method getContactList
|
|
566
|
+
* @description Returns the raw physics contacts this body currently takes
|
|
567
|
+
* part in. Each contact's `fixtureA`/`fixtureB` point at physics-unit
|
|
568
|
+
* fixtures/bodies, not RigidBody wrappers. Walk `fixture.body.getUserData()`
|
|
569
|
+
* to get back to the owning RigidBody.
|
|
570
|
+
* @returns {Array<Contact>}
|
|
571
|
+
*/
|
|
572
|
+
getContactList() {
|
|
573
|
+
return this.body.getContactList();
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* @method getWorld
|
|
578
|
+
* @description Returns the raw physics {@link World} this body lives in.
|
|
579
|
+
* @returns {World}
|
|
580
|
+
*/
|
|
581
|
+
getWorld() {
|
|
582
|
+
return this.body.getWorld();
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* @method getUserData
|
|
587
|
+
* @description Returns whatever you last passed to
|
|
588
|
+
* {@link RigidBody#setUserData}. This is separate from the underlying
|
|
589
|
+
* physics body's own userData slot, which the engine itself uses internally
|
|
590
|
+
* to route collisions back to this RigidBody, so setting it here can never
|
|
591
|
+
* break that.
|
|
592
|
+
* @returns {*}
|
|
593
|
+
*/
|
|
594
|
+
getUserData() {
|
|
595
|
+
return this.userData;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* @method setUserData
|
|
600
|
+
* @param {*} data
|
|
601
|
+
*/
|
|
602
|
+
setUserData(data) {
|
|
603
|
+
this.userData = data;
|
|
604
|
+
}
|
|
605
|
+
|
|
195
606
|
/**
|
|
196
607
|
* @method getPosition
|
|
197
608
|
* @description Returns the live world-space position of the body (kept in sync
|
|
@@ -232,8 +643,11 @@ class RigidBody {
|
|
|
232
643
|
|
|
233
644
|
/**
|
|
234
645
|
* @method getBody
|
|
235
|
-
* @description Returns the
|
|
236
|
-
*
|
|
646
|
+
* @description Returns the underlying, physics-unit {@link Body}. Nothing in
|
|
647
|
+
* ordinary use needs this: every common operation is a method on RigidBody
|
|
648
|
+
* itself, in world/pixel units, but it's here for advanced cases (writing a
|
|
649
|
+
* custom joint or solver hook) that need the raw physics object.
|
|
650
|
+
* @returns {Body} - The body of the rigidbody
|
|
237
651
|
*/
|
|
238
652
|
getBody() {
|
|
239
653
|
return this.body;
|
|
@@ -263,7 +677,7 @@ class RigidBody {
|
|
|
263
677
|
*/
|
|
264
678
|
detachCollider(collider) {
|
|
265
679
|
if (collider && collider.getCollider()) {
|
|
266
|
-
this.
|
|
680
|
+
this.destroyFixture(collider.getCollider());
|
|
267
681
|
this.collider = null;
|
|
268
682
|
}
|
|
269
683
|
}
|
|
@@ -285,6 +699,19 @@ class RigidBody {
|
|
|
285
699
|
getType() {
|
|
286
700
|
return this.type;
|
|
287
701
|
}
|
|
702
|
+
|
|
703
|
+
/**
|
|
704
|
+
* @method setType
|
|
705
|
+
* @description Changes the body type at runtime (e.g. turning a kinematic
|
|
706
|
+
* moving platform into a dynamic one when it breaks apart). Resets
|
|
707
|
+
* velocities and re-derives mass; existing contacts are dropped so they
|
|
708
|
+
* rebuild against the new type.
|
|
709
|
+
* @param {string | "static" | "dynamic" | "kinematic"} type
|
|
710
|
+
*/
|
|
711
|
+
setType(type) {
|
|
712
|
+
this.type = type;
|
|
713
|
+
this.body.setType(type);
|
|
714
|
+
}
|
|
288
715
|
}
|
|
289
716
|
|
|
290
717
|
export default RigidBody;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @description Imports sprite-sheet metadata exported from Aseprite
|
|
4
4
|
* (File ▸ Export Sprite Sheet, with "JSON Data" on) and turns its frame tags
|
|
5
5
|
* into engine animation clips. Works with both the Hash and Array JSON layouts.
|
|
6
|
-
* Pure parsing
|
|
6
|
+
* Pure parsing: pass it the already-parsed JSON object.
|
|
7
7
|
*
|
|
8
8
|
* Assumes the sheet is a uniform grid in frame order (the common case), so the
|
|
9
9
|
* frame indices line up with the engine's Texture/Animator frame numbering.
|
|
@@ -86,7 +86,7 @@ class Aseprite {
|
|
|
86
86
|
* @method toClips
|
|
87
87
|
* @description Builds clip descriptors from the sheet's frame tags. Each clip
|
|
88
88
|
* is `{ name, frames, speed }` where `frames` are frame indices and `speed`
|
|
89
|
-
* is the average frame duration (ms)
|
|
89
|
+
* is the average frame duration (ms), the per-clip speed the Animator uses.
|
|
90
90
|
* If the sheet has no tags, a single "default" clip spanning all frames is
|
|
91
91
|
* returned.
|
|
92
92
|
* @param {Object} sheet - Parsed Aseprite JSON
|