Files
GDevelop/Extensions/Physics2Behavior/physics2runtimebehavior.js
2019-05-06 23:08:41 +01:00

3205 lines
95 KiB
JavaScript

gdjs.Physics2SharedData = function(runtimeScene, sharedData) {
this.gravityX = sharedData.gravityX;
this.gravityY = sharedData.gravityY;
this.scaleX =
sharedData.scaleX === 0 ? 100 : sharedData.scaleX;
this.scaleY =
sharedData.scaleY === 0 ? 100 : sharedData.scaleY;
this.invScaleX = 1 / this.scaleX;
this.invScaleY = 1 / this.scaleY;
this.timeStep = 1 / 60;
this.frameTime = 0;
this.stepped = false;
this.timeScale = 1;
this.world = new Box2D.b2World(
new Box2D.b2Vec2(this.gravityX, this.gravityY),
true
);
this.staticBody = this.world.CreateBody(new Box2D.b2BodyDef());
// Contact listener to keep track of current collisions
this.contactListener = new Box2D.JSContactListener();
this.contactListener.BeginContact = function(contactPtr) {
// Get the contact
var contact = Box2D.wrapPointer(contactPtr, Box2D.b2Contact);
// There is no body, return
if (
contact.GetFixtureA().GetBody() === null ||
contact.GetFixtureB().GetBody() === null
) {
return;
}
// Get associated behaviors
var behaviorA = contact.GetFixtureA().GetBody().gdjsAssociatedBehavior;
var behaviorB = contact.GetFixtureB().GetBody().gdjsAssociatedBehavior;
// Let each behavior know about the contact against the other
behaviorA.currentContacts.push(behaviorB);
behaviorB.currentContacts.push(behaviorA);
};
this.contactListener.EndContact = function(contactPtr) {
// Get the contact
var contact = Box2D.wrapPointer(contactPtr, Box2D.b2Contact);
// There is no body, return
if (
contact.GetFixtureA().GetBody() === null ||
contact.GetFixtureB().GetBody() === null
) {
return;
}
// Get associated behaviors
var behaviorA = contact.GetFixtureA().GetBody().gdjsAssociatedBehavior;
var behaviorB = contact.GetFixtureB().GetBody().gdjsAssociatedBehavior;
// Remove each other contact
var i = behaviorA.currentContacts.indexOf(behaviorB);
if (i !== -1) behaviorA.currentContacts.remove(i);
i = behaviorB.currentContacts.indexOf(behaviorA);
if (i !== -1) behaviorB.currentContacts.remove(i);
};
this.contactListener.PreSolve = function() {};
this.contactListener.PostSolve = function() {};
this.world.SetContactListener(this.contactListener);
this._nextJointId = 1; // Start with 1 so the user is safe from default variables value (0)
this.joints = {}; // (string)jointId -> (b2Joint)b2Joint
};
gdjs.Physics2SharedData.getSharedData = function(runtimeScene, behaviorName) {
// Create one if needed
if (!runtimeScene.physics2SharedData) {
var initialData = runtimeScene.getInitialSharedDataForBehavior(
behaviorName
);
runtimeScene.physics2SharedData = new gdjs.Physics2SharedData(
runtimeScene,
initialData
);
}
return runtimeScene.physics2SharedData;
};
gdjs.Physics2SharedData.prototype.step = function(deltaTime) {
this.frameTime += deltaTime;
if (this.frameTime >= this.timeStep) {
var numberOfSteps = Math.floor(this.frameTime / this.timeStep);
this.frameTime -= numberOfSteps * this.timeStep;
if (numberOfSteps > 5) numberOfSteps = 5;
for (var i = 0; i < numberOfSteps; i++) {
this.world.Step(this.timeStep * this.timeScale, 8, 10);
}
this.world.ClearForces();
}
this.stepped = true;
};
gdjs.Physics2SharedData.gdjsCallbackRuntimeSceneUnloaded = function(
runtimeScene
) {
if (
runtimeScene.physics2SharedData &&
runtimeScene.physics2SharedData.world
) {
Box2D.destroy(runtimeScene.physics2SharedData.world);
}
};
gdjs.Physics2SharedData.prototype.clearBodyJoints = function(body) {
// Iterate through all the joints
for (var jointId in this.joints) {
if (this.joints.hasOwnProperty(jointId)) {
// If the joint is attached to the body, delete it
if (
this.joints[jointId].GetBodyA() === body ||
this.joints[jointId].GetBodyB() === body
) {
this.removeJoint(jointId);
}
}
}
};
gdjs.Physics2SharedData.prototype.addJoint = function(joint) {
// Add the joint to the list
this.joints[this._nextJointId.toString(10)] = joint;
// Return the current joint id and then increase it
return this._nextJointId++;
};
gdjs.Physics2SharedData.prototype.getJoint = function(jointId) {
// Cast to string
jointId = jointId.toString(10);
// Get the joint
if (this.joints.hasOwnProperty(jointId)) {
return this.joints[jointId];
}
// Joint not found, return null
return null;
};
gdjs.Physics2SharedData.prototype.getJointId = function(joint) {
// Search the joint in the list and return the ID
for (var jointId in this.joints) {
if (this.joints.hasOwnProperty(jointId)) {
if (this.joints[jointId] === joint) {
return parseInt(jointId, 10);
}
}
}
// Joint not found, return 0
return 0;
};
gdjs.Physics2SharedData.prototype.removeJoint = function(jointId) {
// Cast to string
jointId = jointId.toString(10);
// Delete the joint
if (this.joints.hasOwnProperty(jointId)) {
var joint = this.joints[jointId];
// If we delete a joint attached to a gear joint, the gear will crash, so we must delete the gear joint first
// Search in our joints list gear joints attached to this one we want to remove
// The joint can be attached to a gear joint if it's revolute or prismatic only
if (
joint.GetType() === Box2D.e_revoluteJoint ||
joint.GetType() === Box2D.e_prismaticJoint
) {
for (var jId in this.joints) {
if (this.joints.hasOwnProperty(jId)) {
// Must check pointers becuase gears store non-casted joints (b2Joint)
if (
this.joints[jId].GetType() === Box2D.e_gearJoint &&
(Box2D.getPointer(this.joints[jId].GetJoint1()) ===
Box2D.getPointer(joint) ||
Box2D.getPointer(this.joints[jId].GetJoint2()) ===
Box2D.getPointer(joint))
) {
// We could pass it a string, but lets do it right
this.removeJoint(parseInt(jId, 10));
}
}
}
}
// Remove the joint
this.world.DestroyJoint(joint);
delete this.joints[jointId];
}
};
gdjs.Physics2RuntimeBehavior = function(runtimeScene, behaviorData, owner) {
gdjs.RuntimeBehavior.call(this, runtimeScene, behaviorData, owner);
this.bodyType = behaviorData.bodyType;
this.bullet = behaviorData.bullet;
this.fixedRotation = behaviorData.fixedRotation;
this.canSleep = behaviorData.canSleep;
this.shape = behaviorData.shape;
this.shapeDimensionA = behaviorData.shapeDimensionA;
this.shapeDimensionB = behaviorData.shapeDimensionB;
this.shapeOffsetX = behaviorData.shapeOffsetX;
this.shapeOffsetY = behaviorData.shapeOffsetY;
this.polygonOrigin = behaviorData.polygonOrigin;
this.polygon =
this.shape === 'Polygon'
? gdjs.Physics2RuntimeBehavior.getPolygon(behaviorData.vertices)
: null;
this.density = behaviorData.density;
this.friction = behaviorData.friction;
this.restitution = behaviorData.restitution;
this.linearDamping = behaviorData.linearDamping;
this.angularDamping = behaviorData.angularDamping;
this.gravityScale = behaviorData.gravityScale;
this.layers = behaviorData.layers;
this.masks = behaviorData.masks;
this.shapeScale = 1;
this.currentContacts = this.currentContacts || [];
this.currentContacts.length = 0;
this._body = null;
this._sharedData = gdjs.Physics2SharedData.getSharedData(
runtimeScene,
behaviorData.name
);
this._tempb2Vec2 = new Box2D.b2Vec2(); // Avoid creating new vectors all the time
this._tempb2Vec2Sec = new Box2D.b2Vec2(); // Sometimes two vectors are needed on the same function call
this._objectOldX = 0;
this._objectOldY = 0;
this._objectOldAngle = 0;
this._objectOldWidth = 0;
this._objectOldHeight = 0;
this._verticesBuffer = 0; // Stores a Box2D pointer of created vertices
};
gdjs.Physics2RuntimeBehavior.prototype = Object.create(
gdjs.RuntimeBehavior.prototype
);
gdjs.Physics2RuntimeBehavior.thisIsARuntimeBehaviorConstructor =
'Physics2::Physics2Behavior';
gdjs.Physics2RuntimeBehavior.prototype.b2Vec2 = function(x, y) {
this._tempb2Vec2.set_x(x);
this._tempb2Vec2.set_y(y);
return this._tempb2Vec2;
};
gdjs.Physics2RuntimeBehavior.prototype.b2Vec2Sec = function(x, y) {
this._tempb2Vec2Sec.set_x(x);
this._tempb2Vec2Sec.set_y(y);
return this._tempb2Vec2Sec;
};
gdjs.Physics2RuntimeBehavior.prototype.onDeActivate = function() {
if (this._body !== null) {
// When a body is deleted, Box2D removes automatically its joints, leaving an invalid pointer in our joints list
this._sharedData.clearBodyJoints(this._body);
// Delete the vertices
if (this._verticesBuffer) {
Box2D._free(this._verticesBuffer);
this._verticesBuffer = 0;
}
// Delete the body
this._sharedData.world.DestroyBody(this._body);
this._body = null;
}
};
gdjs.Physics2RuntimeBehavior.prototype.onOwnerRemovedFromScene = function() {
this.onDeActivate();
};
gdjs.Physics2RuntimeBehavior.getPolygon = function(verticesData) {
if (!verticesData) return null;
var polygon = new gdjs.Polygon();
var maxVertices = 8;
for (
var i = 0, len = verticesData.length;
i < Math.min(len, maxVertices);
i++
) {
polygon.vertices.push([verticesData[i].x, verticesData[i].y]);
}
return polygon;
};
gdjs.Physics2RuntimeBehavior.isPolygonConvex = function(polygon) {
if (!polygon.isConvex()) return false;
// Check for repeated vertices or check if all vertices are aligned (would crash Box2D)
var alignedX = true;
var alignedY = true;
for (i = 0; i < polygon.vertices.length - 1; ++i) {
for (var j = i + 1; j < polygon.vertices.length; ++j) {
if (
polygon.vertices[i][0] === polygon.vertices[j][0] &&
polygon.vertices[i][1] === polygon.vertices[j][1]
)
return false;
}
if (polygon.vertices[i][0] !== polygon.vertices[i + 1][0]) alignedX = false;
if (polygon.vertices[i][1] !== polygon.vertices[i + 1][1]) alignedY = false;
}
if (alignedX || alignedY) return false;
return true;
};
gdjs.Physics2RuntimeBehavior.prototype.createShape = function() {
// Get the scaled offset
var offsetX = this.shapeOffsetX
? this.shapeOffsetX * this.shapeScale * this._sharedData.invScaleX
: 0;
var offsetY = this.shapeOffsetY
? this.shapeOffsetY * this.shapeScale * this._sharedData.invScaleY
: 0;
// Generate the base shape
var shape;
if (this.shape === 'Circle') {
shape = new Box2D.b2CircleShape();
// Radius determined by the custom dimension
if (this.shapeDimensionA > 0) {
shape.set_m_radius(
this.shapeDimensionA * this.shapeScale * this._sharedData.invScaleX
);
}
// Average radius from width and height
else {
var radius =
(this.owner.getWidth() * this._sharedData.invScaleX +
this.owner.getHeight() * this._sharedData.invScaleY) /
4;
shape.set_m_radius(radius > 0 ? radius : 1);
}
// Set the offset
shape.set_m_p(this.b2Vec2(offsetX, offsetY));
} else if (this.shape === 'Polygon') {
shape = new Box2D.b2PolygonShape();
// Not convex, fall back to a box
if (
!this.polygon ||
!gdjs.Physics2RuntimeBehavior.isPolygonConvex(this.polygon)
) {
var width =
(this.owner.getWidth() > 0 ? this.owner.getWidth() : 1) *
this._sharedData.invScaleX;
var height =
(this.owner.getHeight() > 0 ? this.owner.getHeight() : 1) *
this._sharedData.invScaleY;
// Set the shape box
shape.SetAsBox(width / 2, height / 2, this.b2Vec2(offsetX, offsetY), 0);
} else {
var originOffsetX = 0;
var originOffsetY = 0;
if (this.polygonOrigin === 'Origin') {
originOffsetX =
(this.owner.getWidth() > 0 ? -this.owner.getWidth() / 2 : 0) +
(this.owner.getX() - this.owner.getDrawableX());
originOffsetY =
(this.owner.getHeight() > 0 ? -this.owner.getHeight() / 2 : 0) +
(this.owner.getY() - this.owner.getDrawableY());
} else if (this.polygonOrigin === 'TopLeft') {
originOffsetX =
this.owner.getWidth() > 0 ? -this.owner.getWidth() / 2 : 0;
originOffsetY =
this.owner.getHeight() > 0 ? -this.owner.getHeight() / 2 : 0;
}
// Generate vertices if not done already
if (!this._verticesBuffer) {
// Store the vertices using a memory allocation function
var buffer = Box2D._malloc(
this.polygon.vertices.length * 8,
'float',
Box2D.ALLOC_STACK
);
this._verticesBuffer = buffer;
}
// Overwrite the vertices stored in the buffer
var offset = 0;
for (var i = 0, len = this.polygon.vertices.length; i < len; i++) {
Box2D.HEAPF32[(this._verticesBuffer + offset) >> 2] =
(this.polygon.vertices[i][0] * this.shapeScale + originOffsetX) *
this._sharedData.invScaleX +
offsetX;
Box2D.HEAPF32[(this._verticesBuffer + (offset + 4)) >> 2] =
(this.polygon.vertices[i][1] * this.shapeScale + originOffsetY) *
this._sharedData.invScaleY +
offsetY;
offset += 8;
}
// Set the shape vertices
var b2Vertices = Box2D.wrapPointer(this._verticesBuffer, Box2D.b2Vec2);
shape.Set(b2Vertices, this.polygon.vertices.length);
}
} else if (this.shape === 'Edge') {
shape = new Box2D.b2EdgeShape();
// Length from the custom dimension or from the object width
var length =
(this.shapeDimensionA > 0
? this.shapeDimensionA * this.shapeScale
: this.owner.getWidth() > 0
? this.owner.getWidth()
: 1) * this._sharedData.invScaleX;
var height =
this.owner.getHeight() > 0
? this.owner.getHeight() * this._sharedData.invScaleY
: 0;
// Angle from custom dimension, otherwise is 0
var angle = this.shapeDimensionB ? gdjs.toRad(this.shapeDimensionB) : 0;
// Set the edge vertices from the length, the angle and the offset
shape.Set(
this.b2Vec2(
(-length / 2) * Math.cos(angle) + offsetX,
height / 2 - (length / 2) * Math.sin(angle) + offsetY
),
this.b2Vec2Sec(
(length / 2) * Math.cos(angle) + offsetX,
height / 2 + (length / 2) * Math.sin(angle) + offsetY
)
);
} else {
// Box
shape = new Box2D.b2PolygonShape();
// Width and height from custom dimensions or object size
var width =
(this.shapeDimensionA > 0
? this.shapeDimensionA * this.shapeScale
: this.owner.getWidth() > 0
? this.owner.getWidth()
: 1) * this._sharedData.invScaleX;
var height =
(this.shapeDimensionB > 0
? this.shapeDimensionB * this.shapeScale
: this.owner.getHeight() > 0
? this.owner.getHeight()
: 1) * this._sharedData.invScaleY;
// Set the shape box, the offset must be added here too
shape.SetAsBox(width / 2, height / 2, this.b2Vec2(offsetX, offsetY), 0);
}
// Generate filter data
var filter = new Box2D.b2Filter();
filter.set_categoryBits(this.layers);
filter.set_maskBits(this.masks);
// Generate the fixture definition
var fixDef = new Box2D.b2FixtureDef();
// Set fixture settings
fixDef.set_shape(shape);
fixDef.set_filter(filter);
if (this.density < 0) this.density = 0;
fixDef.set_density(this.density);
if (this.friction < 0) this.friction = 0;
fixDef.set_friction(this.friction);
if (this.restitution < 0) this.restitution = 0;
fixDef.set_restitution(this.restitution);
// Return the fixture
return fixDef;
};
gdjs.Physics2RuntimeBehavior.prototype.recreateShape = function() {
// If there is no body, set a new one
if (this._body === null) {
this.createBody();
return;
}
// Destroy the old shape
this._body.DestroyFixture(this._body.GetFixtureList());
this._body.CreateFixture(this.createShape());
// Update cached size
this._objectOldWidth = this.owner.getWidth();
this._objectOldHeight = this.owner.getHeight();
};
gdjs.Physics2RuntimeBehavior.prototype.getShapeScale = function() {
return this.shapeScale;
};
gdjs.Physics2RuntimeBehavior.prototype.setShapeScale = function(shapeScale) {
if (shapeScale !== this.shapeScale && shapeScale > 0) {
this.shapeScale = shapeScale;
this.recreateShape();
}
};
gdjs.Physics2RuntimeBehavior.prototype.getBody = function() {
// If there is no body, set a new one
if (this._body === null) this.createBody();
return this._body;
};
gdjs.Physics2RuntimeBehavior.prototype.createBody = function() {
// Generate the body definition
var bodyDef = new Box2D.b2BodyDef();
// Set the initial body transformation from the GD object
bodyDef.set_position(
this.b2Vec2(
(this.owner.getDrawableX() + this.owner.getWidth() / 2) *
this._sharedData.invScaleX,
(this.owner.getDrawableY() + this.owner.getHeight() / 2) *
this._sharedData.invScaleY
)
);
bodyDef.set_angle(gdjs.toRad(this.owner.getAngle()));
// Set body settings
bodyDef.set_type(
this.bodyType === 'Static'
? Box2D.b2_staticBody
: this.bodyType === 'Kinematic'
? Box2D.b2_kinematicBody
: Box2D.b2_dynamicBody
);
bodyDef.set_bullet(this.bullet);
bodyDef.set_fixedRotation(this.fixedRotation);
bodyDef.set_allowSleep(this.canSleep);
bodyDef.set_linearDamping(this.linearDamping);
bodyDef.set_angularDamping(this.angularDamping);
bodyDef.set_gravityScale(this.gravityScale);
// Create the body
this._body = this._sharedData.world.CreateBody(bodyDef);
this._body.CreateFixture(this.createShape());
this._body.gdjsAssociatedBehavior = this;
// Update cached size
this._objectOldWidth = this.owner.getWidth();
this._objectOldHeight = this.owner.getHeight();
};
gdjs.Physics2RuntimeBehavior.prototype.doStepPreEvents = function(
runtimeScene
) {
// Create a body if there is not one
if (this._body === null) {
this.createBody();
}
// Step the world if not done this frame yet
if (!this._sharedData.stepped) {
this._sharedData.step(
runtimeScene.getTimeManager().getElapsedTime() / 1000.0
);
}
// Copy transform from body to the GD object
this.owner.setX(
this._body.GetPosition().get_x() * this._sharedData.scaleX -
this.owner.getWidth() / 2 +
this.owner.getX() -
this.owner.getDrawableX()
);
this.owner.setY(
this._body.GetPosition().get_y() * this._sharedData.scaleY -
this.owner.getHeight() / 2 +
this.owner.getY() -
this.owner.getDrawableY()
);
this.owner.setAngle(gdjs.toDegrees(this._body.GetAngle()));
// Update cached transform
this._objectOldX = this.owner.getX();
this._objectOldY = this.owner.getY();
this._objectOldAngle = this.owner.getAngle();
};
gdjs.Physics2RuntimeBehavior.prototype.doStepPostEvents = function(
runtimeScene
) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// GD object size has changed, recreate shape
// The width has changed and there is no custom dimension A (box: width, circle: radius, edge: length) or
// The height has changed, the shape is not an edge (edges doesn't have height),
// it isn't a box with custom height or a circle with custom radius
if (
(this._objectOldWidth !== this.owner.getWidth() &&
this.shapeDimensionA <= 0) ||
(this._objectOldHeight !== this.owner.getHeight() &&
this.shape !== 'Edge' &&
!(this.shape === 'Box' && this.shapeDimensionB > 0) &&
!(this.shape === 'Ciecle' && this.shapeDimensionA > 0))
) {
this.recreateShape();
}
// GD object transform has changed, update body transform
if (
this._objectOldX !== this.owner.getX() ||
this._objectOldY !== this.owner.getY() ||
this._objectOldAngle !== this.owner.getAngle()
) {
var pos = this.b2Vec2(
(this.owner.getDrawableX() + this.owner.getWidth() / 2) *
this._sharedData.invScaleX,
(this.owner.getDrawableY() + this.owner.getHeight() / 2) *
this._sharedData.invScaleY
);
this._body.SetTransform(pos, gdjs.toRad(this.owner.getAngle()));
this._body.SetAwake(true);
}
// Reset world step to update next frame
this._sharedData.stepped = false;
};
gdjs.Physics2RuntimeBehavior.prototype.getGravityX = function() {
return this._sharedData.gravityX;
};
gdjs.Physics2RuntimeBehavior.prototype.getGravityY = function() {
return this._sharedData.gravityY;
};
gdjs.Physics2RuntimeBehavior.prototype.setGravity = function(x, y) {
// Check if there is no modification
if (this._sharedData.gravityX === x && this._sharedData.gravityY === y)
return;
// Change the gravity
this._sharedData.gravityX = x;
this._sharedData.gravityY = y;
this._sharedData.world.SetGravity(
this.b2Vec2(this._sharedData.gravityX, this._sharedData.gravityY)
);
};
gdjs.Physics2RuntimeBehavior.prototype.getTimeScale = function() {
// Get the time scale
return this._sharedData.timeScale;
};
gdjs.Physics2RuntimeBehavior.prototype.setTimeScale = function(timeScale) {
// Invalid value
if (timeScale < 0) return;
// Set the time scale
this._sharedData.timeScale = timeScale;
};
gdjs.Physics2RuntimeBehavior.setTimeScaleFromObject = function(
object,
behaviorName,
timeScale
) {
// Check if the object exist and has the behavior
if (object === null || !object.hasBehavior(behaviorName)) return;
// Set the time scale
object.getBehavior(behaviorName).setTimeScale(timeScale);
};
gdjs.Physics2RuntimeBehavior.prototype.isDynamic = function() {
return this.bodyType === 'Dynamic';
};
gdjs.Physics2RuntimeBehavior.prototype.setDynamic = function() {
// Check if there is no modification
if (this.bodyType === 'Dynamic') return;
// Change body type
this.bodyType = 'Dynamic';
// If there is no body, set a new one
if (this._body === null) {
this.createBody();
return;
}
// Update body type
this._body.SetType(Box2D.b2_dynamicBody);
this._body.SetAwake(true);
};
gdjs.Physics2RuntimeBehavior.prototype.isStatic = function() {
return this.bodyType === 'Static';
};
gdjs.Physics2RuntimeBehavior.prototype.setStatic = function() {
// Check if there is no modification
if (this.bodyType === 'Static') return;
// Change body type
this.bodyType = 'Static';
// If there is no body, set a new one
if (this._body === null) {
this.createBody();
return;
}
// Update body type
this._body.SetType(Box2D.b2_staticBody);
this._body.SetAwake(true);
};
gdjs.Physics2RuntimeBehavior.prototype.isKinematic = function() {
return this.bodyType === 'Kinematic';
};
gdjs.Physics2RuntimeBehavior.prototype.setKinematic = function() {
// Check if there is no modification
if (this.bodyType === 'Kinematic') return;
// Change body type
this.bodyType = 'Kinematic';
// If there is no body, set a new one
if (this._body === null) {
this.createBody();
return;
}
// Update body type
this._body.SetType(Box2D.b2_kinematicBody);
this._body.SetAwake(true);
};
gdjs.Physics2RuntimeBehavior.prototype.isBullet = function() {
return this.bullet;
};
gdjs.Physics2RuntimeBehavior.prototype.setBullet = function(enable) {
// Check if there is no modification
if (this.bullet === enable) return;
// Change bullet flag
this.bullet = enable;
// If there is no body, set a new one
if (this._body === null) {
this.createBody();
return;
}
// Update body bullet flag
this._body.SetBullet(this.bullet);
};
gdjs.Physics2RuntimeBehavior.prototype.hasFixedRotation = function() {
return this.fixedRotation;
};
gdjs.Physics2RuntimeBehavior.prototype.setFixedRotation = function(enable) {
this.fixedRotation = enable;
if (this._body === null) {
this.createBody();
return;
}
this._body.SetFixedRotation(this.fixedRotation);
};
gdjs.Physics2RuntimeBehavior.prototype.isSleepingAllowed = function() {
return this.canSleep;
};
gdjs.Physics2RuntimeBehavior.prototype.setSleepingAllowed = function(enable) {
this.canSleep = enable;
if (this._body === null) {
this.createBody();
return;
}
this._body.SetSleepingAllowed(this.canSleep);
};
gdjs.Physics2RuntimeBehavior.prototype.isSleeping = function() {
// If there is no body, set a new one
if (this._body === null) {
this.createBody();
}
// Get the body sleeping state
return !this._body.IsAwake();
};
gdjs.Physics2RuntimeBehavior.prototype.getDensity = function() {
return this.density;
};
gdjs.Physics2RuntimeBehavior.prototype.setDensity = function(density) {
// Non-negative values only
if (density < 0) density = 0;
// Check if there is no modification
if (this.density === density) return;
// Change density
this.density = density;
// If there is no body, set a new one
if (this._body === null) {
this.createBody();
return;
}
// Update the body density
this._body.GetFixtureList().SetDensity(this.density);
this._body.ResetMassData();
};
gdjs.Physics2RuntimeBehavior.prototype.getFriction = function() {
return this.friction;
};
gdjs.Physics2RuntimeBehavior.prototype.setFriction = function(friction) {
// Non-negative values only
if (friction < 0) friction = 0;
// Check if there is no modification
if (this.friction === friction) return;
// Change friction
this.friction = friction;
// If there is no body, set a new one
if (this._body === null) {
this.createBody();
return;
}
// Update the body friction
this._body.GetFixtureList().SetFriction(this.friction);
// Update contacts
var contact = this._body.GetContactList();
while (Box2D.getPointer(contact)) {
contact.get_contact().ResetFriction();
contact = contact.get_next();
}
};
gdjs.Physics2RuntimeBehavior.prototype.getRestitution = function() {
return this.restitution;
};
gdjs.Physics2RuntimeBehavior.prototype.setRestitution = function(restitution) {
// Non-negative values only
if (restitution < 0) restitution = 0;
// Check if there is no modification
if (this.restitution === restitution) return;
// Change restitution
this.restitution = restitution;
// If there is no body, set a new one
if (this._body === null) {
this.createBody();
return;
}
// Update the body restitution
this._body.GetFixtureList().SetRestitution(this.restitution);
// Update contacts
var contact = this._body.GetContactList();
while (Box2D.getPointer(contact)) {
contact.get_contact().ResetRestitution();
contact = contact.get_next();
}
};
gdjs.Physics2RuntimeBehavior.prototype.getLinearDamping = function() {
return this.linearDamping;
};
gdjs.Physics2RuntimeBehavior.prototype.setLinearDamping = function(
linearDamping
) {
// Check if there is no modification
if (this.linearDamping === linearDamping) return;
// Change linearDamping
this.linearDamping = linearDamping;
// If there is no body, set a new one
if (this._body === null) {
this.createBody();
return;
}
// Update the body linear damping
this._body.SetLinearDamping(this.linearDamping);
};
gdjs.Physics2RuntimeBehavior.prototype.getAngularDamping = function() {
return this.angularDamping;
};
gdjs.Physics2RuntimeBehavior.prototype.setAngularDamping = function(
angularDamping
) {
// Check if there is no modification
if (this.angularDamping === angularDamping) return;
// Change angularDamping
this.angularDamping = angularDamping;
// If there is no body, set a new one
if (this._body === null) {
this.createBody();
return;
}
// Update the body angular damping
this._body.SetAngularDamping(this.angularDamping);
};
gdjs.Physics2RuntimeBehavior.prototype.getGravityScale = function() {
return this.gravityScale;
};
gdjs.Physics2RuntimeBehavior.prototype.setGravityScale = function(
gravityScale
) {
// Check if there is no modification
if (this.gravityScale === gravityScale) return;
// Change the gravity scale
this.gravityScale = gravityScale;
// If there is no body, set a new one
if (this._body === null) {
this.createBody();
return;
}
// Update the body gravity scale
this._body.SetGravityScale(this.gravityScale);
};
gdjs.Physics2RuntimeBehavior.prototype.layerEnabled = function(layer) {
// Layer must be an integer
layer = Math.floor(layer);
// Layer must be in range [1, 16]
if (layer < 1 || layer > 16) return false;
return !!(this.layers & (1 << (layer - 1)));
};
gdjs.Physics2RuntimeBehavior.prototype.enableLayer = function(layer, enable) {
// Layer must be an integer
layer = Math.floor(layer);
// Layer must be in range [1, 16]
if (layer < 1 || layer > 16) return;
// Change the layers
if (enable) {
this.layers |= 1 << (layer - 1);
} else {
this.layers &= ~(1 << (layer - 1));
}
// If there is no body, set a new one
if (this._body === null) {
this.createBody();
return;
}
// Update the body layers
var filter = this._body.GetFixtureList().GetFilterData();
filter.set_categoryBits(this.layers);
this._body.GetFixtureList().SetFilterData(filter);
};
gdjs.Physics2RuntimeBehavior.prototype.maskEnabled = function(mask) {
// Mask must be an integer
mask = Math.floor(mask);
// Mask must be in range [1, 16]
if (mask < 1 || mask > 16) return false;
return !!(this.masks & (1 << (mask - 1)));
};
gdjs.Physics2RuntimeBehavior.prototype.enableMask = function(mask, enable) {
// Mask must be an integer
mask = Math.floor(mask);
// Mask must be in range [1, 16]
if (mask < 1 || mask > 16) return;
// Change the masks
if (enable) {
this.masks |= 1 << (mask - 1);
} else {
this.masks &= ~(1 << (mask - 1));
}
// If there is no body, set a new one
if (this._body === null) {
this.createBody();
return;
}
// Update the body masks
var filter = this._body.GetFixtureList().GetFilterData();
filter.set_maskBits(this.masks);
this._body.GetFixtureList().SetFilterData(filter);
};
gdjs.Physics2RuntimeBehavior.prototype.getLinearVelocityX = function() {
// If there is no body, set a new one
if (this._body === null) {
this.createBody();
return 0;
}
// Get the linear velocity on X
return this._body.GetLinearVelocity().get_x() * this._sharedData.scaleX;
};
gdjs.Physics2RuntimeBehavior.prototype.setLinearVelocityX = function(
linearVelocityX
) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// Set the linear velocity on X
this._body.SetLinearVelocity(
this.b2Vec2(
linearVelocityX * this._sharedData.invScaleX,
this._body.GetLinearVelocity().get_y()
)
);
};
gdjs.Physics2RuntimeBehavior.prototype.getLinearVelocityY = function() {
// If there is no body, set a new one
if (this._body === null) {
this.createBody();
return 0;
}
// Get the linear velocity on Y
return this._body.GetLinearVelocity().get_y() * this._sharedData.scaleY;
};
gdjs.Physics2RuntimeBehavior.prototype.setLinearVelocityY = function(
linearVelocityY
) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// Set the linear velocity on Y
this._body.SetLinearVelocity(
this.b2Vec2(
this._body.GetLinearVelocity().get_x(),
linearVelocityY * this._sharedData.invScaleY
)
);
};
gdjs.Physics2RuntimeBehavior.prototype.getLinearVelocityLength = function() {
// If there is no body, set a new one
if (this._body === null) {
this.createBody();
return 0;
}
// Get the linear velocity length
return this.b2Vec2(
this._body.GetLinearVelocity().get_x() * this._sharedData.scaleX,
this._body.GetLinearVelocity().get_y() * this._sharedData.scaleY
).Length();
};
gdjs.Physics2RuntimeBehavior.prototype.getAngularVelocity = function() {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// Get the angular velocity
return gdjs.toDegrees(this._body.GetAngularVelocity());
};
gdjs.Physics2RuntimeBehavior.prototype.setAngularVelocity = function(
angularVelocity
) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// Set the angular velocity
this._body.SetAngularVelocity(gdjs.toRad(angularVelocity));
};
gdjs.Physics2RuntimeBehavior.prototype.applyForce = function(
forceX,
forceY,
positionX,
positionY
) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// Wake up the object
this._body.SetAwake(true);
// Apply the force
this._body.ApplyForce(
this.b2Vec2(forceX, forceY),
this.b2Vec2Sec(
positionX * this._sharedData.invScaleX,
positionY * this._sharedData.invScaleY
)
);
};
gdjs.Physics2RuntimeBehavior.prototype.applyPolarForce = function(
angle,
length,
positionX,
positionY
) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// Wake up the object
this._body.SetAwake(true);
// Apply the force
angle = gdjs.toRad(angle);
this._body.ApplyForce(
this.b2Vec2(length * Math.cos(angle), length * Math.sin(angle)),
this.b2Vec2Sec(
positionX * this._sharedData.invScaleX,
positionY * this._sharedData.invScaleY
)
);
};
gdjs.Physics2RuntimeBehavior.prototype.applyForceTowardPosition = function(
length,
towardX,
towardY,
positionX,
positionY
) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// Wake up the object
this._body.SetAwake(true);
// Apply the force
var angle = Math.atan2(
towardY * this._sharedData.invScaleY - this._body.GetPosition().get_y(),
towardX * this._sharedData.invScaleX - this._body.GetPosition().get_x()
);
this._body.ApplyForce(
this.b2Vec2(length * Math.cos(angle), length * Math.sin(angle)),
this.b2Vec2Sec(
positionX * this._sharedData.invScaleX,
positionY * this._sharedData.invScaleY
)
);
};
gdjs.Physics2RuntimeBehavior.prototype.applyImpulse = function(
impulseX,
impulseY,
positionX,
positionY
) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// Wake up the object
this._body.SetAwake(true);
// Apply the impulse
this._body.ApplyLinearImpulse(
this.b2Vec2(impulseX, impulseY),
this.b2Vec2Sec(
positionX * this._sharedData.invScaleX,
positionY * this._sharedData.invScaleY
)
);
};
gdjs.Physics2RuntimeBehavior.prototype.applyPolarImpulse = function(
angle,
length,
positionX,
positionY
) {
// If there is no body, set a new one
if (this._body === null) his.createBody();
// Wake up the object
this._body.SetAwake(true);
// Apply the impulse
angle = gdjs.toRad(angle);
this._body.ApplyLinearImpulse(
this.b2Vec2(length * Math.cos(angle), length * Math.sin(angle)),
this.b2Vec2Sec(
positionX * this._sharedData.invScaleX,
positionY * this._sharedData.invScaleY
)
);
};
gdjs.Physics2RuntimeBehavior.prototype.applyImpulseTowardPosition = function(
length,
towardX,
towardY,
positionX,
positionY
) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// Wake up the object
this._body.SetAwake(true);
// Apply the impulse
var angle = Math.atan2(
towardY * this._sharedData.invScaleY - this._body.GetPosition().get_y(),
towardX * this._sharedData.invScaleX - this._body.GetPosition().get_x()
);
this._body.ApplyLinearImpulse(
this.b2Vec2(length * Math.cos(angle), length * Math.sin(angle)),
this.b2Vec2Sec(
positionX * this._sharedData.invScaleX,
positionY * this._sharedData.invScaleY
)
);
};
gdjs.Physics2RuntimeBehavior.prototype.applyTorque = function(torque) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// Wake up the object
this._body.SetAwake(true);
// Apply the torque
this._body.ApplyTorque(torque);
};
gdjs.Physics2RuntimeBehavior.prototype.applyAngularImpulse = function(
angularImpulse
) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// Wake up the object
this._body.SetAwake(true);
// Apply the angular impulse
this._body.ApplyAngularImpulse(angularImpulse);
};
gdjs.Physics2RuntimeBehavior.prototype.getMassCenterX = function() {
// If there is no body, set a new one
if (this._body === null) {
this.createBody();
}
// Get the mass center on X
return this._body.GetWorldCenter().get_x() * this._sharedData.scaleX;
};
gdjs.Physics2RuntimeBehavior.prototype.getMassCenterY = function() {
// If there is no body, set a new one
if (this._body === null) {
this.createBody();
}
// Get the mass center on Y
return this._body.GetWorldCenter().get_y() * this._sharedData.scaleY;
};
// Joints
gdjs.Physics2RuntimeBehavior.prototype.isJointFirstObject = function(jointId) {
// If there is no body, set a new one
if (this._body === null) {
this.createBody();
return false;
}
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found
if (joint === null) return false;
// Check the joint object
return joint.GetBodyA() === this._body;
};
gdjs.Physics2RuntimeBehavior.prototype.isJointSecondObject = function(jointId) {
// If there is no body, set a new one
if (this._body === null) {
this.createBody();
return false;
}
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found
if (joint === null) return false;
// Check the joint object
return joint.GetBodyB() === this._body;
};
gdjs.Physics2RuntimeBehavior.prototype.getJointFirstAnchorX = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found
if (joint === null) return 0;
// Get the joint anchor
return joint
.GetBodyA()
.GetWorldPoint(joint.GetLocalAnchorA())
.get_x();
};
gdjs.Physics2RuntimeBehavior.prototype.getJointFirstAnchorY = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found
if (joint === null) return 0;
// Get the joint anchor
return joint
.GetBodyA()
.GetWorldPoint(joint.GetLocalAnchorA())
.get_y();
};
gdjs.Physics2RuntimeBehavior.prototype.getJointSecondAnchorX = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found
if (joint === null) return 0;
// Get the joint anchor
return joint
.GetBodyB()
.GetWorldPoint(joint.GetLocalAnchorB())
.get_x();
};
gdjs.Physics2RuntimeBehavior.prototype.getJointSecondAnchorY = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found
if (joint === null) return 0;
// Get the joint anchor
return joint
.GetBodyB()
.GetWorldPoint(joint.GetLocalAnchorB())
.get_y();
};
gdjs.Physics2RuntimeBehavior.prototype.getJointReactionForce = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found
if (joint === null) return 0;
// Get the reaction force
return joint.GetReactionForce(1 / this._sharedData.timeStep).Length();
};
gdjs.Physics2RuntimeBehavior.prototype.getJointReactionTorque = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found
if (joint === null) return 0;
// Get the reaction torque
return joint.GetReactionTorque(1 / this._sharedData.timeStep);
};
gdjs.Physics2RuntimeBehavior.prototype.removeJoint = function(jointId) {
// Just let the sharedData to manage and delete the joint
this._sharedData.removeJoint(jointId);
};
// Distance joint
gdjs.Physics2RuntimeBehavior.prototype.addDistanceJoint = function(
x1,
y1,
other,
x2,
y2,
length,
frequency,
dampingRatio,
collideConnected,
variable
) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// If there is no second object or it doesn't share the behavior, return
if (other == null || !other.hasBehavior(this.name)) return;
// Get the second body
var otherBody = other.getBehavior(this.name).getBody();
// If the first and second objects/bodies are the same, return
if (this._body === otherBody) return;
// Set joint settings
var jointDef = new Box2D.b2DistanceJointDef();
jointDef.set_bodyA(this._body);
jointDef.set_localAnchorA(
this._body.GetLocalPoint(
this.b2Vec2(
x1 * this._sharedData.invScaleX,
y1 * this._sharedData.invScaleY
)
)
);
jointDef.set_bodyB(otherBody);
jointDef.set_localAnchorB(
otherBody.GetLocalPoint(
this.b2Vec2(
x2 * this._sharedData.invScaleX,
y2 * this._sharedData.invScaleY
)
)
);
jointDef.set_length(
length > 0
? length * this._sharedData.invScaleX
: this.b2Vec2(
(x2 - x1) * this._sharedData.invScaleX,
(y2 - y1) * this._sharedData.invScaleY
).Length()
);
jointDef.set_frequencyHz(frequency >= 0 ? frequency : 0);
jointDef.set_dampingRatio(dampingRatio >= 0 ? dampingRatio : 1);
jointDef.set_collideConnected(collideConnected);
// Create the joint and get the id
var jointId = this._sharedData.addJoint(
Box2D.castObject(
this._sharedData.world.CreateJoint(jointDef),
Box2D.b2DistanceJoint
)
);
// Store the id in the variable
variable.setNumber(jointId);
};
gdjs.Physics2RuntimeBehavior.prototype.getDistanceJointLength = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_distanceJoint) return 0;
// Get the joint length
return joint.GetLength() * this._sharedData.scaleX;
};
gdjs.Physics2RuntimeBehavior.prototype.setDistanceJointLength = function(
jointId,
length
) {
// Invalid value
if (length <= 0) return;
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_distanceJoint) return;
// Set the joint length
joint.SetLength(length * this._sharedData.invScaleX);
// Awake the bodies
joint.GetBodyA().SetAwake(true);
joint.GetBodyB().SetAwake(true);
};
gdjs.Physics2RuntimeBehavior.prototype.getDistanceJointFrequency = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_distanceJoint) return 0;
// Get the joint frequency
return joint.GetFrequency();
};
gdjs.Physics2RuntimeBehavior.prototype.setDistanceJointFrequency = function(
jointId,
frequency
) {
// Invalid value
if (frequency < 0) return;
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_distanceJoint) return;
// Set the joint frequency
joint.SetFrequency(frequency);
};
gdjs.Physics2RuntimeBehavior.prototype.getDistanceJointDampingRatio = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_distanceJoint) return 0;
// Get the joint damping ratio
return joint.GetDampingRatio();
};
gdjs.Physics2RuntimeBehavior.prototype.setDistanceJointDampingRatio = function(
jointId,
dampingRatio
) {
// Invalid value
if (dampingRatio < 0) return;
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_distanceJoint);
// Set the joint damping ratio
joint.SetDampingRatio(dampingRatio);
};
// Revolute joint
gdjs.Physics2RuntimeBehavior.prototype.addRevoluteJoint = function(
x,
y,
enableLimit,
referenceAngle,
lowerAngle,
upperAngle,
enableMotor,
motorSpeed,
maxMotorTorque,
variable
) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// Set joint settings
var jointDef = new Box2D.b2RevoluteJointDef();
jointDef.set_bodyA(this._sharedData.staticBody);
jointDef.set_localAnchorA(
this._sharedData.staticBody.GetLocalPoint(
this.b2Vec2(
x * this._sharedData.invScaleX,
y * this._sharedData.invScaleY
)
)
);
jointDef.set_bodyB(this._body);
jointDef.set_localAnchorB(
this._body.GetLocalPoint(
this.b2Vec2(
x * this._sharedData.invScaleX,
y * this._sharedData.invScaleY
)
)
);
jointDef.set_enableLimit(enableLimit);
jointDef.set_referenceAngle(gdjs.toRad(referenceAngle));
// Lower angle must be lower than upper angle
if (upperAngle < lowerAngle) {
var temp = lowerAngle;
lowerAngle = upperAngle;
upperAngle = temp;
}
jointDef.set_lowerAngle(gdjs.toRad(lowerAngle));
jointDef.set_upperAngle(gdjs.toRad(upperAngle));
jointDef.set_enableMotor(enableMotor);
jointDef.set_motorSpeed(gdjs.toRad(motorSpeed));
jointDef.set_maxMotorTorque(maxMotorTorque >= 0 ? maxMotorTorque : 0);
jointDef.set_collideConnected(false);
// Create the joint and get the id
var jointId = this._sharedData.addJoint(
Box2D.castObject(
this._sharedData.world.CreateJoint(jointDef),
Box2D.b2RevoluteJoint
)
);
// Store the id in the variable
variable.setNumber(jointId);
};
gdjs.Physics2RuntimeBehavior.prototype.addRevoluteJointBetweenTwoBodies = function(
x1,
y1,
other,
x2,
y2,
enableLimit,
referenceAngle,
lowerAngle,
upperAngle,
enableMotor,
motorSpeed,
maxMotorTorque,
collideConnected,
variable
) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// If there is no second object or it doesn't share the behavior, return
if (other == null || !other.hasBehavior(this.name)) return;
// Get the second body
var otherBody = other.getBehavior(this.name).getBody();
// If the first and second objects/bodies are the same, return
if (this._body === otherBody) return;
// Set joint settings
var jointDef = new Box2D.b2RevoluteJointDef();
jointDef.set_bodyA(this._body);
jointDef.set_localAnchorA(
this._body.GetLocalPoint(
this.b2Vec2(
x1 * this._sharedData.invScaleX,
y1 * this._sharedData.invScaleY
)
)
);
jointDef.set_bodyB(otherBody);
jointDef.set_localAnchorB(
otherBody.GetLocalPoint(
this.b2Vec2(
x2 * this._sharedData.invScaleX,
y2 * this._sharedData.invScaleY
)
)
);
jointDef.set_enableLimit(enableLimit);
jointDef.set_referenceAngle(gdjs.toRad(referenceAngle));
// Lower angle must be lower than upper angle
if (upperAngle < lowerAngle) {
var temp = lowerAngle;
lowerAngle = upperAngle;
upperAngle = temp;
}
jointDef.set_lowerAngle(gdjs.toRad(lowerAngle));
jointDef.set_upperAngle(gdjs.toRad(upperAngle));
jointDef.set_enableMotor(enableMotor);
jointDef.set_motorSpeed(gdjs.toRad(motorSpeed));
jointDef.set_maxMotorTorque(maxMotorTorque >= 0 ? maxMotorTorque : 0);
jointDef.set_collideConnected(collideConnected);
// Create the joint and get the id
var jointId = this._sharedData.addJoint(
Box2D.castObject(
this._sharedData.world.CreateJoint(jointDef),
Box2D.b2RevoluteJoint
)
);
// Store the id in the variable
variable.setNumber(jointId);
};
gdjs.Physics2RuntimeBehavior.prototype.getRevoluteJointReferenceAngle = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) return 0;
// Get the joint reference angle
return gdjs.toDegrees(joint.GetReferenceAngle());
};
gdjs.Physics2RuntimeBehavior.prototype.getRevoluteJointAngle = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) return 0;
// Get the joint current angle
return gdjs.toDegrees(joint.GetJointAngle());
};
gdjs.Physics2RuntimeBehavior.prototype.getRevoluteJointSpeed = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) return 0;
// Get the joint angular speed
return gdjs.toDegrees(joint.GetJointSpeed());
};
gdjs.Physics2RuntimeBehavior.prototype.isRevoluteJointLimitsEnabled = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) return false;
// Get the joint limits state
return joint.IsLimitEnabled();
};
gdjs.Physics2RuntimeBehavior.prototype.enableRevoluteJointLimits = function(
jointId,
enable
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) return;
// Set the joint limits state
joint.EnableLimit(enable);
};
gdjs.Physics2RuntimeBehavior.prototype.getRevoluteJointMinAngle = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) return 0;
// Get the joint lower angle
return gdjs.toDegrees(joint.GetLowerLimit());
};
gdjs.Physics2RuntimeBehavior.prototype.getRevoluteJointMaxAngle = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) return 0;
// Get the joint upper angle
return gdjs.toDegrees(joint.GetUpperLimit());
};
gdjs.Physics2RuntimeBehavior.prototype.setRevoluteJointLimits = function(
jointId,
lowerAngle,
upperAngle
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) return;
// Lower angle must be lower than upper angle
if (upperAngle < lowerAngle) {
var temp = lowerAngle;
lowerAngle = upperAngle;
upperAngle = temp;
}
// Set the joint limits
joint.SetLimits(gdjs.toRad(lowerAngle), gdjs.toRad(upperAngle));
};
gdjs.Physics2RuntimeBehavior.prototype.isRevoluteJointMotorEnabled = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) return false;
// Get the joint motor state
return joint.IsMotorEnabled();
};
gdjs.Physics2RuntimeBehavior.prototype.enableRevoluteJointMotor = function(
jointId,
enable
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) return;
// Set the joint motor state
joint.EnableMotor(enable);
};
gdjs.Physics2RuntimeBehavior.prototype.getRevoluteJointMotorSpeed = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) return 0;
// Get the joint motor speed
return gdjs.toDegrees(joint.GetMotorSpeed());
};
gdjs.Physics2RuntimeBehavior.prototype.setRevoluteJointMotorSpeed = function(
jointId,
speed
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) return;
// Set the joint motor speed
joint.SetMotorSpeed(gdjs.toRad(speed));
};
gdjs.Physics2RuntimeBehavior.prototype.getRevoluteJointMaxMotorTorque = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) return 0;
// Get the joint max motor
return joint.GetMaxMotorTorque();
};
gdjs.Physics2RuntimeBehavior.prototype.setRevoluteJointMaxMotorTorque = function(
jointId,
maxTorque
) {
// Invalid value
if (maxTorque < 0) return;
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) return;
// Set the joint max motor
joint.SetMaxMotorTorque(maxTorque);
};
gdjs.Physics2RuntimeBehavior.prototype.getRevoluteJointMotorTorque = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) return 0;
// Get the joint motor torque
return joint.GetMotorTorque(1 / this._sharedData.timeStep);
};
// Prismatic joint
gdjs.Physics2RuntimeBehavior.prototype.addPrismaticJoint = function(
x1,
y1,
other,
x2,
y2,
axisAngle,
referenceAngle,
enableLimit,
lowerTranslation,
upperTranslation,
enableMotor,
motorSpeed,
maxMotorForce,
collideConnected,
variable
) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// If there is no second object or it doesn't share the behavior, return
if (other == null || !other.hasBehavior(this.name)) return;
// Get the second body
var otherBody = other.getBehavior(this.name).getBody();
// If the first and second objects/bodies are the same, return
if (this._body === otherBody) return;
// Set joint settings
var jointDef = new Box2D.b2PrismaticJointDef();
jointDef.set_bodyA(this._body);
jointDef.set_localAnchorA(
this._body.GetLocalPoint(
this.b2Vec2(
x1 * this._sharedData.invScaleX,
y1 * this._sharedData.invScaleY
)
)
);
jointDef.set_bodyB(otherBody);
jointDef.set_localAnchorB(
otherBody.GetLocalPoint(
this.b2Vec2(
x2 * this._sharedData.invScaleX,
y2 * this._sharedData.invScaleY
)
)
);
axisAngle = gdjs.toRad(axisAngle) - this._body.GetAngle();
jointDef.set_localAxisA(
this.b2Vec2(Math.cos(axisAngle), Math.sin(axisAngle))
);
jointDef.set_referenceAngle(gdjs.toRad(referenceAngle));
jointDef.set_enableLimit(enableLimit);
// Lower translation must be lower than upper translation
if (upperTranslation < lowerTranslation) {
var temp = lowerTranslation;
lowerTranslation = upperTranslation;
upperTranslation = temp;
}
// The translation range must include zero
jointDef.set_lowerTranslation(
lowerTranslation < 0 ? lowerTranslation * this._sharedData.invScaleX : 0
);
jointDef.set_upperTranslation(
upperTranslation > 0 ? upperTranslation * this._sharedData.invScaleX : 0
);
jointDef.set_enableMotor(enableMotor);
jointDef.set_motorSpeed(motorSpeed * this._sharedData.invScaleX);
jointDef.set_maxMotorForce(maxMotorForce);
jointDef.set_collideConnected(collideConnected);
// Create the joint and get the id
var jointId = this._sharedData.addJoint(
Box2D.castObject(
this._sharedData.world.CreateJoint(jointDef),
Box2D.b2PrismaticJoint
)
);
// Store the id in the variable
variable.setNumber(jointId);
};
gdjs.Physics2RuntimeBehavior.prototype.getPrismaticJointAxisAngle = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) return 0;
// Get the joint axis angle
return gdjs.toDegrees(
Math.atan2(joint.GetLocalAxisA().get_y(), joint.GetLocalAxisA().get_x()) +
joint.GetBodyA().GetAngle()
);
};
gdjs.Physics2RuntimeBehavior.prototype.getPrismaticJointReferenceAngle = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) return 0;
// Get the joint reference angle
return gdjs.toDegrees(joint.GetReferenceAngle());
};
gdjs.Physics2RuntimeBehavior.prototype.getPrismaticJointTranslation = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) return 0;
// Get the joint current translation
return joint.GetJointTranslation() * this._sharedData.scaleX;
};
gdjs.Physics2RuntimeBehavior.prototype.getPrismaticJointSpeed = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) return 0;
// Get the joint speed
return joint.GetJointSpeed() * this._sharedData.scaleX;
};
gdjs.Physics2RuntimeBehavior.prototype.isPrismaticJointLimitsEnabled = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint)
return false;
// Get the joint limits state
return joint.IsLimitEnabled();
};
gdjs.Physics2RuntimeBehavior.prototype.enablePrismaticJointLimits = function(
jointId,
enable
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) return;
// Set the joint limits state
joint.EnableLimit(enable);
};
gdjs.Physics2RuntimeBehavior.prototype.getPrismaticJointMinTranslation = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) return 0;
// Get the joint lower limit
return joint.GetLowerLimit() * this._sharedData.scaleX;
};
gdjs.Physics2RuntimeBehavior.prototype.getPrismaticJointMaxTranslation = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) return 0;
// Get the joint upper angle
return joint.GetUpperLimit() * this._sharedData.scaleX;
};
gdjs.Physics2RuntimeBehavior.prototype.setPrismaticJointLimits = function(
jointId,
lowerTranslation,
upperTranslation
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) return;
// Lower translation must be lower than upper translation
if (upperTranslation < lowerTranslation) {
var temp = lowerTranslation;
lowerTranslation = upperTranslation;
upperTranslation = temp;
}
// The translation range must include zero
lowerTranslation = lowerTranslation < 0 ? lowerTranslation : 0;
upperTranslation = upperTranslation > 0 ? upperTranslation : 0;
// Set the joint limits
joint.SetLimits(
lowerTranslation * this._sharedData.invScaleX,
upperTranslation * this._sharedData.invScaleX
);
};
gdjs.Physics2RuntimeBehavior.prototype.isPrismaticJointMotorEnabled = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint)
return false;
// Get the joint motor state
return joint.IsMotorEnabled();
};
gdjs.Physics2RuntimeBehavior.prototype.enablePrismaticJointMotor = function(
jointId,
enable
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) return;
// Set the joint motor state
joint.EnableMotor(enable);
};
gdjs.Physics2RuntimeBehavior.prototype.getPrismaticJointMotorSpeed = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) return 0;
// Get the joint motor speed
return joint.GetMotorSpeed() * this._sharedData.scaleX;
};
gdjs.Physics2RuntimeBehavior.prototype.setPrismaticJointMotorSpeed = function(
jointId,
speed
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) return;
// Set the joint motor speed
joint.SetMotorSpeed(speed * this._sharedData.invScaleX);
};
gdjs.Physics2RuntimeBehavior.prototype.getPrismaticJointMaxMotorForce = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) return 0;
// Get the joint max motor force
return joint.GetMaxMotorForce();
};
gdjs.Physics2RuntimeBehavior.prototype.setPrismaticJointMaxMotorForce = function(
jointId,
maxForce
) {
// Invalid value
if (maxForce < 0) return;
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) return;
// Set the joint max motor force
joint.SetMaxMotorForce(maxForce);
};
gdjs.Physics2RuntimeBehavior.prototype.getPrismaticJointMotorForce = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) return 0;
// Get the joint motor torque
return joint.GetMotorForce(1 / this._sharedData.timeStep);
};
// Pulley joint
gdjs.Physics2RuntimeBehavior.prototype.addPulleyJoint = function(
x1,
y1,
other,
x2,
y2,
groundX1,
groundY1,
groundX2,
groundY2,
lengthA,
lengthB,
ratio,
collideConnected,
variable
) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// If there is no second object or it doesn't share the behavior, return
if (other == null || !other.hasBehavior(this.name)) return;
// Get the second body
var otherBody = other.getBehavior(this.name).getBody();
// If the first and second objects/bodies are the same, return
if (this._body === otherBody) return;
// Set joint settings
var jointDef = new Box2D.b2PulleyJointDef();
jointDef.set_bodyA(this._body);
jointDef.set_localAnchorA(
this._body.GetLocalPoint(
this.b2Vec2(
x1 * this._sharedData.invScaleX,
y1 * this._sharedData.invScaleY
)
)
);
jointDef.set_bodyB(otherBody);
jointDef.set_localAnchorB(
otherBody.GetLocalPoint(
this.b2Vec2(
x2 * this._sharedData.invScaleX,
y2 * this._sharedData.invScaleY
)
)
);
jointDef.set_groundAnchorA(
this.b2Vec2(
groundX1 * this._sharedData.invScaleX,
groundY1 * this._sharedData.invScaleY
)
);
jointDef.set_groundAnchorB(
this.b2Vec2(
groundX2 * this._sharedData.invScaleX,
groundY2 * this._sharedData.invScaleY
)
);
jointDef.set_lengthA(
lengthA > 0
? lengthA * this._sharedData.invScaleX
: this.b2Vec2(
(groundX1 - x1) * this._sharedData.invScaleX,
(groundY1 - y1) * this._sharedData.invScaleY
).Length()
);
jointDef.set_lengthB(
lengthB > 0
? lengthB * this._sharedData.invScaleX
: this.b2Vec2(
(groundX2 - x2) * this._sharedData.invScaleX,
(groundY2 - y2) * this._sharedData.invScaleY
).Length()
);
jointDef.set_ratio(ratio > 0 ? ratio : 1);
jointDef.set_collideConnected(collideConnected);
// Create the joint and get the id
var jointId = this._sharedData.addJoint(
Box2D.castObject(
this._sharedData.world.CreateJoint(jointDef),
Box2D.b2PulleyJoint
)
);
// Store the id in the variable
variable.setNumber(jointId);
};
gdjs.Physics2RuntimeBehavior.prototype.getPulleyJointFirstGroundAnchorX = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_pulleyJoint) return 0;
// Get the joint ground anchor
return joint.GetGroundAnchorA().get_x() * this._sharedData.scaleX;
};
gdjs.Physics2RuntimeBehavior.prototype.getPulleyJointFirstGroundAnchorY = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_pulleyJoint) return 0;
// Get the joint ground anchor
return joint.GetGroundAnchorA().get_y() * this._sharedData.scaleY;
};
gdjs.Physics2RuntimeBehavior.prototype.getPulleyJointSecondGroundAnchorX = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_pulleyJoint) return 0;
// Get the joint ground anchor
return joint.GetGroundAnchorB().get_x() * this._sharedData.scaleX;
};
gdjs.Physics2RuntimeBehavior.prototype.getPulleyJointSecondGroundAnchorY = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_pulleyJoint) return 0;
// Get the joint ground anchor
return joint.GetGroundAnchorB().get_y() * this._sharedData.scaleY;
};
gdjs.Physics2RuntimeBehavior.prototype.getPulleyJointFirstLength = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_pulleyJoint) return 0;
// Get the joint length
return joint.GetCurrentLengthA() * this._sharedData.scaleX;
};
gdjs.Physics2RuntimeBehavior.prototype.getPulleyJointSecondLength = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_pulleyJoint) return 0;
// Get the joint length
return joint.GetCurrentLengthB() * this._sharedData.scaleX;
};
gdjs.Physics2RuntimeBehavior.prototype.getPulleyJointRatio = function(jointId) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_pulleyJoint) return 0;
// Get the joint ratio
return joint.GetRatio();
};
// Gear joint
gdjs.Physics2RuntimeBehavior.prototype.addGearJoint = function(
jointId1,
jointId2,
ratio,
collideConnected,
variable
) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// Get the first joint
var joint1 = this._sharedData.getJoint(jointId1);
// Joint not found or has wrong type
if (
joint1 === null ||
(joint1.GetType() !== Box2D.e_revoluteJoint &&
joint1.GetType() !== Box2D.e_prismaticJoint)
)
return;
// Get the second joint
var joint2 = this._sharedData.getJoint(jointId2);
if (
joint2 === null ||
(joint2.GetType() !== Box2D.e_revoluteJoint &&
joint2.GetType() !== Box2D.e_prismaticJoint)
)
return;
// The joints are the same
if (joint1 === joint2) return;
// Set joint settings
var jointDef = new Box2D.b2GearJointDef();
// Set gear joint bodies is not necessary at first, as the gear get the bodies from the two child joints
// But we must pass two different bodies to bypass a test inherited from b2Joint
jointDef.set_bodyA(this._sharedData.staticBody);
jointDef.set_bodyB(this._body);
jointDef.set_joint1(joint1);
jointDef.set_joint2(joint2);
jointDef.set_ratio(ratio);
jointDef.set_collideConnected(collideConnected);
// Create the joint and get the id
var jointId = this._sharedData.addJoint(
Box2D.castObject(
this._sharedData.world.CreateJoint(jointDef),
Box2D.b2GearJoint
)
);
// Store the id in the variable
variable.setNumber(jointId);
};
gdjs.Physics2RuntimeBehavior.prototype.getGearJointFirstJoint = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_gearJoint) return 0;
// Get the joint first joint
return this._sharedData.getJointId(joint.GetJoint1());
};
gdjs.Physics2RuntimeBehavior.prototype.getGearJointSecondJoint = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_gearJoint) return 0;
// Get the joint second joint
return this._sharedData.getJointId(joint.GetJoint2());
};
gdjs.Physics2RuntimeBehavior.prototype.getGearJointRatio = function(jointId) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_gearJoint) return 0;
// Get the joint ratio
return joint.GetRatio();
};
gdjs.Physics2RuntimeBehavior.prototype.setGearJointRatio = function(
jointId,
ratio
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_gearJoint) return;
// Set the joint ratio
joint.SetRatio(ratio);
// Awake the bodies, the gear joint picks the dynamic bodies as first and second body (second bodies from the child joints)
joint.GetBodyA().SetAwake(true);
joint.GetBodyB().SetAwake(true);
};
// Mouse joint
gdjs.Physics2RuntimeBehavior.prototype.addMouseJoint = function(
targetX,
targetY,
maxForce,
frequency,
dampingRatio,
variable
) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// Set joint settings
var jointDef = new Box2D.b2MouseJointDef();
jointDef.set_bodyA(this._sharedData.staticBody);
jointDef.set_bodyB(this._body);
jointDef.set_target(
this.b2Vec2(
targetX * this._sharedData.invScaleX,
targetY * this._sharedData.invScaleY
)
);
jointDef.set_maxForce(maxForce >= 0 ? maxForce : 0);
jointDef.set_frequencyHz(frequency > 0 ? frequency : 1);
jointDef.set_dampingRatio(dampingRatio >= 0 ? dampingRatio : 0);
// Create the joint and get the id
var jointId = this._sharedData.addJoint(
Box2D.castObject(
this._sharedData.world.CreateJoint(jointDef),
Box2D.b2MouseJoint
)
);
// Store the id in the variable
variable.setNumber(jointId);
};
gdjs.Physics2RuntimeBehavior.prototype.getMouseJointTargetX = function(
jointId
) {
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) return 0;
// Get the joint target X
return joint.GetTarget().get_x() * this._sharedData.scaleX;
};
gdjs.Physics2RuntimeBehavior.prototype.getMouseJointTargetY = function(
jointId
) {
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) return 0;
// Get the joint target Y
return joint.GetTarget().get_y() * this._sharedData.scaleY;
};
gdjs.Physics2RuntimeBehavior.prototype.setMouseJointTarget = function(
jointId,
targetX,
targetY
) {
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) return;
// Set the joint target
joint.SetTarget(
this.b2Vec2(
targetX * this._sharedData.invScaleX,
targetY * this._sharedData.invScaleY
)
);
// Awake the body
joint.GetBodyB().SetAwake(true);
};
gdjs.Physics2RuntimeBehavior.prototype.getMouseJointMaxForce = function(
jointId
) {
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) return 0;
// Get the joint max force
return joint.GetMaxForce();
};
gdjs.Physics2RuntimeBehavior.prototype.setMouseJointMaxForce = function(
jointId,
maxForce
) {
// Invalid value
if (maxForce < 0) return;
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) return;
// Set the joint max force
joint.SetMaxForce(maxForce);
};
gdjs.Physics2RuntimeBehavior.prototype.getMouseJointFrequency = function(
jointId
) {
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) return 0;
// Get the joint frequency
return joint.GetFrequency();
};
gdjs.Physics2RuntimeBehavior.prototype.setMouseJointFrequency = function(
jointId,
frequency
) {
// Invalid value
if (frequency <= 0) return;
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) return;
// Set the joint frequency
joint.SetFrequency(frequency);
};
gdjs.Physics2RuntimeBehavior.prototype.getMouseJointDampingRatio = function(
jointId
) {
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) return 0;
// Get the joint damping ratio
return joint.GetDampingRatio();
};
gdjs.Physics2RuntimeBehavior.prototype.setMouseJointDampingRatio = function(
jointId,
dampingRatio
) {
// Invalid value
if (dampingRatio < 0) return;
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) return;
// Set the joint damping ratio
joint.SetDampingRatio(dampingRatio);
};
// Wheel joint
gdjs.Physics2RuntimeBehavior.prototype.addWheelJoint = function(
x1,
y1,
other,
x2,
y2,
axisAngle,
frequency,
dampingRatio,
enableMotor,
motorSpeed,
maxMotorTorque,
collideConnected,
variable
) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// If there is no second object or it doesn't share the behavior, return
if (other == null || !other.hasBehavior(this.name)) return;
// Get the second body
var otherBody = other.getBehavior(this.name).getBody();
// If the first and second objects/bodies are the same, return
if (this._body === otherBody) return;
// Set joint settings
var jointDef = new Box2D.b2WheelJointDef();
jointDef.set_bodyA(this._body);
jointDef.set_localAnchorA(
this._body.GetLocalPoint(
this.b2Vec2(
x1 * this._sharedData.invScaleX,
y1 * this._sharedData.invScaleY
)
)
);
jointDef.set_bodyB(otherBody);
jointDef.set_localAnchorB(
otherBody.GetLocalPoint(
this.b2Vec2(
x2 * this._sharedData.invScaleX,
y2 * this._sharedData.invScaleY
)
)
);
axisAngle = gdjs.toRad(axisAngle) - this._body.GetAngle();
jointDef.set_localAxisA(
this.b2Vec2(Math.cos(axisAngle), Math.sin(axisAngle))
);
jointDef.set_frequencyHz(frequency > 0 ? frequency : 1);
jointDef.set_dampingRatio(dampingRatio >= 0 ? dampingRatio : 0);
jointDef.set_enableMotor(enableMotor);
jointDef.set_motorSpeed(gdjs.toRad(motorSpeed));
jointDef.set_maxMotorTorque(maxMotorTorque);
jointDef.set_collideConnected(collideConnected);
// Create the joint and get the id
var jointId = this._sharedData.addJoint(
Box2D.castObject(
this._sharedData.world.CreateJoint(jointDef),
Box2D.b2WheelJoint
)
);
// Store the id in the variable
variable.setNumber(jointId);
};
gdjs.Physics2RuntimeBehavior.prototype.getWheelJointAxisAngle = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) return 0;
// Get the joint axis angle
return gdjs.toDegrees(
Math.atan2(joint.GetLocalAxisA().get_y(), joint.GetLocalAxisA().get_x()) +
joint.GetBodyA().GetAngle()
);
};
gdjs.Physics2RuntimeBehavior.prototype.getWheelJointTranslation = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) return 0;
// Get the joint current translation
return joint.GetJointTranslation() * this._sharedData.scaleX;
};
gdjs.Physics2RuntimeBehavior.prototype.getWheelJointSpeed = function(jointId) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) return 0;
// Get the joint speed
return gdjs.toDegrees(joint.GetJointSpeed());
};
gdjs.Physics2RuntimeBehavior.prototype.isWheelJointMotorEnabled = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) return false;
// Get the joint motor state
return joint.IsMotorEnabled();
};
gdjs.Physics2RuntimeBehavior.prototype.enableWheelJointMotor = function(
jointId,
enable
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) return;
// Set the joint motor state
joint.EnableMotor(enable);
};
gdjs.Physics2RuntimeBehavior.prototype.getWheelJointMotorSpeed = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) return 0;
// Get the joint motor speed
return gdjs.toDegrees(joint.GetMotorSpeed());
};
gdjs.Physics2RuntimeBehavior.prototype.setWheelJointMotorSpeed = function(
jointId,
speed
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) return;
// Set the joint motor speed
joint.SetMotorSpeed(gdjs.toRad(speed));
};
gdjs.Physics2RuntimeBehavior.prototype.getWheelJointMaxMotorTorque = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) return 0;
// Get the joint max motor torque
return joint.GetMaxMotorTorque();
};
gdjs.Physics2RuntimeBehavior.prototype.setWheelJointMaxMotorTorque = function(
jointId,
maxTorque
) {
// Invalid value
if (maxTorque < 0) return;
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) return;
// Set the joint max motor torque
joint.SetMaxMotorTorque(maxTorque);
};
gdjs.Physics2RuntimeBehavior.prototype.getWheelJointMotorTorque = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) return 0;
// Get the joint motor torque
return joint.GetMotorTorque(1 / this._sharedData.timeStep);
};
gdjs.Physics2RuntimeBehavior.prototype.getWheelJointFrequency = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) return 0;
// Get the joint frequency
return joint.GetSpringFrequencyHz();
};
gdjs.Physics2RuntimeBehavior.prototype.setWheelJointFrequency = function(
jointId,
frequency
) {
// Invalid value
if (frequency < 0) return;
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) return;
// Set the joint frequency
joint.SetSpringFrequencyHz(frequency);
};
gdjs.Physics2RuntimeBehavior.prototype.getWheelJointDampingRatio = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) return 0;
// Get the joint damping ratio
return joint.GetSpringDampingRatio();
};
gdjs.Physics2RuntimeBehavior.prototype.setWheelJointDampingRatio = function(
jointId,
dampingRatio
) {
// Invalid value
if (dampingRatio < 0) return;
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) return;
// Set the joint damping ratio
joint.SetSpringDampingRatio(dampingRatio);
};
// Weld joint
gdjs.Physics2RuntimeBehavior.prototype.addWeldJoint = function(
x1,
y1,
other,
x2,
y2,
referenceAngle,
frequency,
dampingRatio,
collideConnected,
variable
) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// If there is no second object or it doesn't share the behavior, return
if (other == null || !other.hasBehavior(this.name)) return;
// Get the second body
var otherBody = other.getBehavior(this.name).getBody();
// If the first and second objects/bodies are the same, return
if (this._body === otherBody) return;
// Set joint settings
var jointDef = new Box2D.b2WeldJointDef();
jointDef.set_bodyA(this._body);
jointDef.set_localAnchorA(
this._body.GetLocalPoint(
this.b2Vec2(
x1 * this._sharedData.invScaleX,
y1 * this._sharedData.invScaleY
)
)
);
jointDef.set_bodyB(otherBody);
jointDef.set_localAnchorB(
otherBody.GetLocalPoint(
this.b2Vec2(
x2 * this._sharedData.invScaleX,
y2 * this._sharedData.invScaleY
)
)
);
jointDef.set_referenceAngle(gdjs.toRad(referenceAngle));
jointDef.set_frequencyHz(frequency > 0 ? frequency : 1);
jointDef.set_dampingRatio(dampingRatio >= 0 ? dampingRatio : 0);
jointDef.set_collideConnected(collideConnected);
// Create the joint
var joint = Box2D.castObject(
this._sharedData.world.CreateJoint(jointDef),
Box2D.b2WeldJoint
);
// b2WeldJoint.GetReferenceAngle() is not binded, store it manually
joint.referenceAngle = jointDef.get_referenceAngle();
// Store the id in the variable
variable.setNumber(this._sharedData.addJoint(joint));
};
gdjs.Physics2RuntimeBehavior.prototype.getWeldJointReferenceAngle = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_weldJoint) return 0;
// b2WeldJoint.GetReferenceAngle() is not binded
// return gdjs.toDegrees(joint.GetReferenceAngle());
return gdjs.toDegrees(joint.referenceAngle);
};
gdjs.Physics2RuntimeBehavior.prototype.getWeldJointFrequency = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_weldJoint) return 0;
// Get the joint frequency
return joint.GetFrequency();
};
gdjs.Physics2RuntimeBehavior.prototype.setWeldJointFrequency = function(
jointId,
frequency
) {
// Invalid value
if (frequency < 0) return;
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_weldJoint) return;
// Set the joint frequency
joint.SetFrequency(frequency);
};
gdjs.Physics2RuntimeBehavior.prototype.getWeldJointDampingRatio = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_weldJoint) return 0;
// Get the joint damping ratio
return joint.GetDampingRatio();
};
gdjs.Physics2RuntimeBehavior.prototype.setWeldJointDampingRatio = function(
jointId,
dampingRatio
) {
// Invalid value
if (dampingRatio < 0) return;
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_weldJoint) return;
// Set the joint damping ratio
joint.SetDampingRatio(dampingRatio);
};
// Rope joint
gdjs.Physics2RuntimeBehavior.prototype.addRopeJoint = function(
x1,
y1,
other,
x2,
y2,
maxLength,
collideConnected,
variable
) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// If there is no second object or it doesn't share the behavior, return
if (other == null || !other.hasBehavior(this.name)) return;
// Get the second body
var otherBody = other.getBehavior(this.name).getBody();
// If the first and second objects/bodies are the same, return
if (this._body === otherBody) return;
// Set joint settings
var jointDef = new Box2D.b2RopeJointDef();
jointDef.set_bodyA(this._body);
jointDef.set_localAnchorA(
this._body.GetLocalPoint(
this.b2Vec2(
x1 * this._sharedData.invScaleX,
y1 * this._sharedData.invScaleY
)
)
);
jointDef.set_bodyB(otherBody);
jointDef.set_localAnchorB(
otherBody.GetLocalPoint(
this.b2Vec2(
x2 * this._sharedData.invScaleX,
y2 * this._sharedData.invScaleY
)
)
);
jointDef.set_maxLength(
maxLength > 0
? maxLength * this._sharedData.invScaleX
: this.b2Vec2(
(x2 - x1) * this._sharedData.invScaleX,
(y2 - y1) * this._sharedData.invScaleY
).Length()
);
jointDef.set_collideConnected(collideConnected);
// Create the joint and get the id
var jointId = this._sharedData.addJoint(
Box2D.castObject(
this._sharedData.world.CreateJoint(jointDef),
Box2D.b2RopeJoint
)
);
// Store the id in the variable
variable.setNumber(jointId);
};
gdjs.Physics2RuntimeBehavior.prototype.getRopeJointMaxLength = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_ropeJoint) return 0;
// Get the joint maximum length
return joint.GetMaxLength() * this._sharedData.scaleX;
};
gdjs.Physics2RuntimeBehavior.prototype.setRopeJointMaxLength = function(
jointId,
maxLength
) {
// Invalid value
if (maxLength < 0) return;
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_ropeJoint) return;
// Set the joint maximum length
joint.SetMaxLength(maxLength * this._sharedData.invScaleX);
// Awake the bodies
joint.GetBodyA().SetAwake(true);
joint.GetBodyB().SetAwake(true);
};
// Friction joint
gdjs.Physics2RuntimeBehavior.prototype.addFrictionJoint = function(
x1,
y1,
other,
x2,
y2,
maxForce,
maxTorque,
collideConnected,
variable
) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// If there is no second object or it doesn't share the behavior, return
if (other == null || !other.hasBehavior(this.name)) return;
// Get the second body
var otherBody = other.getBehavior(this.name).getBody();
// If the first and second objects/bodies are the same, return
if (this._body === otherBody) return;
// Set joint settings
var jointDef = new Box2D.b2FrictionJointDef();
jointDef.set_bodyA(this._body);
jointDef.set_localAnchorA(
this._body.GetLocalPoint(
this.b2Vec2(
x1 * this._sharedData.invScaleX,
y1 * this._sharedData.invScaleY
)
)
);
jointDef.set_bodyB(otherBody);
jointDef.set_localAnchorB(
otherBody.GetLocalPoint(
this.b2Vec2(
x2 * this._sharedData.invScaleX,
y2 * this._sharedData.invScaleY
)
)
);
jointDef.set_maxForce(maxForce >= 0 ? maxForce : 0);
jointDef.set_maxTorque(maxTorque >= 0 ? maxTorque : 0);
jointDef.set_collideConnected(collideConnected);
// Create the joint and get the id
var jointId = this._sharedData.addJoint(
Box2D.castObject(
this._sharedData.world.CreateJoint(jointDef),
Box2D.b2FrictionJoint
)
);
// Store the id in the variable
variable.setNumber(jointId);
};
gdjs.Physics2RuntimeBehavior.prototype.getFrictionJointMaxForce = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_frictionJoint) return 0;
// Get the joint maximum force
return joint.GetMaxForce();
};
gdjs.Physics2RuntimeBehavior.prototype.setFrictionJointMaxForce = function(
jointId,
maxForce
) {
// Invalid value
if (maxForce < 0) return;
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_frictionJoint) return;
// Set the joint maximum force
joint.SetMaxForce(maxForce);
};
gdjs.Physics2RuntimeBehavior.prototype.getFrictionJointMaxTorque = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_frictionJoint) return 0;
// Get the joint maximum torque
return joint.GetMaxTorque();
};
gdjs.Physics2RuntimeBehavior.prototype.setFrictionJointMaxTorque = function(
jointId,
maxTorque
) {
// Invalid value
if (maxTorque < 0) return;
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_frictionJoint) return;
// Set the joint maximum torque
joint.SetMaxTorque(maxTorque);
};
// Motor joint
gdjs.Physics2RuntimeBehavior.prototype.addMotorJoint = function(
other,
offsetX,
offsetY,
offsetAngle,
maxForce,
maxTorque,
correctionFactor,
collideConnected,
variable
) {
// If there is no body, set a new one
if (this._body === null) this.createBody();
// If there is no second object or it doesn't share the behavior, return
if (other == null || !other.hasBehavior(this.name)) return;
// Get the second body
var otherBody = other.getBehavior(this.name).getBody();
// If the first and second objects/bodies are the same, return
if (this._body === otherBody) return;
// Set joint settings
var jointDef = new Box2D.b2MotorJointDef();
jointDef.set_bodyA(this._body);
jointDef.set_bodyB(otherBody);
jointDef.set_linearOffset(
this.b2Vec2(
offsetX * this._sharedData.invScaleX,
offsetY * this._sharedData.invScaleY
)
);
jointDef.set_angularOffset(gdjs.toRad(offsetAngle));
jointDef.set_maxForce(maxForce >= 0 ? maxForce : 0);
jointDef.set_maxTorque(maxTorque >= 0 ? maxTorque : 0);
jointDef.set_correctionFactor(
correctionFactor < 0 ? 0 : correctionFactor > 1 ? 1 : correctionFactor
);
jointDef.set_collideConnected(collideConnected);
// Create the joint and get the id
var jointId = this._sharedData.addJoint(
Box2D.castObject(
this._sharedData.world.CreateJoint(jointDef),
Box2D.b2MotorJoint
)
);
// Store the id in the variable
variable.setNumber(jointId);
};
gdjs.Physics2RuntimeBehavior.prototype.getMotorJointOffsetX = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_motorJoint) return 0;
// Get the joint offset
return joint.GetLinearOffset().get_x() * this._sharedData.scaleX;
};
gdjs.Physics2RuntimeBehavior.prototype.getMotorJointOffsetY = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_motorJoint) return 0;
// Get the joint offset
return joint.GetLinearOffset().get_y() * this._sharedData.scaleY;
};
gdjs.Physics2RuntimeBehavior.prototype.setMotorJointOffset = function(
jointId,
offsetX,
offsetY
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_motorJoint) return;
// Set the joint offset
joint.SetLinearOffset(
this.b2Vec2(
offsetX * this._sharedData.invScaleX,
offsetY * this._sharedData.invScaleY
)
);
};
gdjs.Physics2RuntimeBehavior.prototype.getMotorJointAngularOffset = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_motorJoint) return 0;
// Get the joint angular offset
return gdjs.toDegrees(joint.GetAngularOffset());
};
gdjs.Physics2RuntimeBehavior.prototype.setMotorJointAngularOffset = function(
jointId,
offsetAngle
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_motorJoint) return;
// Set the joint angular offset
joint.SetAngularOffset(gdjs.toRad(offsetAngle));
};
gdjs.Physics2RuntimeBehavior.prototype.getMotorJointMaxForce = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_motorJoint) return 0;
// Get the joint maximum force
return joint.GetMaxForce();
};
gdjs.Physics2RuntimeBehavior.prototype.setMotorJointMaxForce = function(
jointId,
maxForce
) {
// Invalid value
if (maxForce < 0) return;
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_motorJoint) return;
// Set the joint maximum force
joint.SetMaxForce(maxForce);
};
gdjs.Physics2RuntimeBehavior.prototype.getMotorJointMaxTorque = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_motorJoint) return 0;
// Get the joint maximum torque
return joint.GetMaxTorque();
};
gdjs.Physics2RuntimeBehavior.prototype.setMotorJointMaxTorque = function(
jointId,
maxTorque
) {
// Invalid value
if (maxTorque < 0) return;
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_motorJoint) return;
// Set the joint maximum torque
joint.SetMaxTorque(maxTorque);
// Awake the bodies
joint.GetBodyA().SetAwake(true);
joint.GetBodyB().SetAwake(true);
};
gdjs.Physics2RuntimeBehavior.prototype.getMotorJointCorrectionFactor = function(
jointId
) {
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_motorJoint) return 0;
// Get the joint correction factor
return joint.GetCorrectionFactor();
};
gdjs.Physics2RuntimeBehavior.prototype.setMotorJointCorrectionFactor = function(
jointId,
correctionFactor
) {
// Invalid value
if (correctionFactor < 0 || correctionFactor > 1) return;
// Get the joint
var joint = this._sharedData.getJoint(jointId);
// Joint not found or has wrong type
if (joint === null || joint.GetType() !== Box2D.e_motorJoint) return;
// Set the joint correction factor
joint.SetCorrectionFactor(correctionFactor);
// Awake the bodies
joint.GetBodyA().SetAwake(true);
joint.GetBodyB().SetAwake(true);
};
// Collision
gdjs.Physics2RuntimeBehavior.collisionTest = function(
object1,
object2,
behaviorName
) {
// Check if the objects exist and share the behavior
if (object1 === null || !object1.hasBehavior(behaviorName)) return false;
if (object2 === null || !object2.hasBehavior(behaviorName)) return false;
// Test if the second object is in the list of contacts of the first one
var behavior1 = object1.getBehavior(behaviorName);
for (var i = 0, len = behavior1.currentContacts.length; i < len; ++i) {
if (behavior1.currentContacts[i].owner === object2) {
return true;
}
}
// No contact found
return false;
};