gdcore-tools 2.0.0-gd-v5.5.242-autobuild → 2.0.0-gd-v5.5.243-autobuild
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/dist/Runtime/AsyncTasksManager.js +2 -2
- package/dist/Runtime/AsyncTasksManager.js.map +2 -2
- package/dist/Runtime/CustomRuntimeObject.js +1 -1
- package/dist/Runtime/CustomRuntimeObject.js.map +2 -2
- package/dist/Runtime/Extensions/3D/A_RuntimeObject3D.js +1 -1
- package/dist/Runtime/Extensions/3D/A_RuntimeObject3D.js.map +2 -2
- package/dist/Runtime/Extensions/3D/Cube3DRuntimeObject.js +1 -1
- package/dist/Runtime/Extensions/3D/Cube3DRuntimeObject.js.map +2 -2
- package/dist/Runtime/Extensions/3D/CustomRuntimeObject3D.js +1 -1
- package/dist/Runtime/Extensions/3D/CustomRuntimeObject3D.js.map +2 -2
- package/dist/Runtime/Extensions/3D/JsExtension.js +5 -0
- package/dist/Runtime/Extensions/3D/Model3DRuntimeObject.js +1 -1
- package/dist/Runtime/Extensions/3D/Model3DRuntimeObject.js.map +2 -2
- package/dist/Runtime/Extensions/3D/Model3DRuntimeObject3DRenderer.js +1 -1
- package/dist/Runtime/Extensions/3D/Model3DRuntimeObject3DRenderer.js.map +2 -2
- package/dist/Runtime/Extensions/BBText/bbtextruntimeobject.js +1 -1
- package/dist/Runtime/Extensions/BBText/bbtextruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/BitmapText/bitmaptextruntimeobject.js +1 -1
- package/dist/Runtime/Extensions/BitmapText/bitmaptextruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/DebuggerTools/JsExtension.js +3 -1
- package/dist/Runtime/Extensions/DestroyOutsideBehavior/destroyoutsideruntimebehavior.js +1 -1
- package/dist/Runtime/Extensions/DestroyOutsideBehavior/destroyoutsideruntimebehavior.js.map +2 -2
- package/dist/Runtime/Extensions/Lighting/lightruntimeobject.js +1 -1
- package/dist/Runtime/Extensions/Lighting/lightruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/Multiplayer/messageManager.js +1 -1
- package/dist/Runtime/Extensions/Multiplayer/messageManager.js.map +2 -2
- package/dist/Runtime/Extensions/Multiplayer/multiplayerobjectruntimebehavior.js +1 -1
- package/dist/Runtime/Extensions/Multiplayer/multiplayerobjectruntimebehavior.js.map +2 -2
- package/dist/Runtime/Extensions/PanelSpriteObject/panelspriteruntimeobject.js +1 -1
- package/dist/Runtime/Extensions/PanelSpriteObject/panelspriteruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/ParticleSystem/particleemitterobject.js +1 -1
- package/dist/Runtime/Extensions/ParticleSystem/particleemitterobject.js.map +2 -2
- package/dist/Runtime/Extensions/PathfindingBehavior/pathfindingruntimebehavior.js +1 -1
- package/dist/Runtime/Extensions/PathfindingBehavior/pathfindingruntimebehavior.js.map +2 -2
- package/dist/Runtime/Extensions/Physics2Behavior/physics2runtimebehavior.js +1 -1
- package/dist/Runtime/Extensions/Physics2Behavior/physics2runtimebehavior.js.map +2 -2
- package/dist/Runtime/Extensions/Physics3DBehavior/Physics3DRuntimeBehavior.js +1 -1
- package/dist/Runtime/Extensions/Physics3DBehavior/Physics3DRuntimeBehavior.js.map +2 -2
- package/dist/Runtime/Extensions/Physics3DBehavior/PhysicsCar3DRuntimeBehavior.js +1 -1
- package/dist/Runtime/Extensions/Physics3DBehavior/PhysicsCar3DRuntimeBehavior.js.map +2 -2
- package/dist/Runtime/Extensions/Physics3DBehavior/PhysicsCharacter3DRuntimeBehavior.js +1 -1
- package/dist/Runtime/Extensions/Physics3DBehavior/PhysicsCharacter3DRuntimeBehavior.js.map +2 -2
- package/dist/Runtime/Extensions/PlatformBehavior/platformerobjectruntimebehavior.js +1 -1
- package/dist/Runtime/Extensions/PlatformBehavior/platformerobjectruntimebehavior.js.map +2 -2
- package/dist/Runtime/Extensions/PlatformBehavior/platformruntimebehavior.js +1 -1
- package/dist/Runtime/Extensions/PlatformBehavior/platformruntimebehavior.js.map +2 -2
- package/dist/Runtime/Extensions/PrimitiveDrawing/shapepainterruntimeobject.js +1 -1
- package/dist/Runtime/Extensions/PrimitiveDrawing/shapepainterruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/SaveState/JsExtension.js +488 -0
- package/dist/Runtime/Extensions/SaveState/SaveConfigurationRuntimeBehavior.js +2 -0
- package/dist/Runtime/Extensions/SaveState/SaveConfigurationRuntimeBehavior.js.map +7 -0
- package/dist/Runtime/Extensions/SaveState/SaveStateTools.js +2 -0
- package/dist/Runtime/Extensions/SaveState/SaveStateTools.js.map +7 -0
- package/dist/Runtime/Extensions/Spine/spineruntimeobject.js +1 -1
- package/dist/Runtime/Extensions/Spine/spineruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/TextInput/textinputruntimeobject.js +1 -1
- package/dist/Runtime/Extensions/TextInput/textinputruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/TextObject/textruntimeobject.js +1 -1
- package/dist/Runtime/Extensions/TextObject/textruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/TileMap/helper/dts/model/TileMapModel.d.ts +4 -4
- package/dist/Runtime/Extensions/TileMap/simpletilemapruntimeobject.js +1 -1
- package/dist/Runtime/Extensions/TileMap/simpletilemapruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/TileMap/tilemapcollisionmaskruntimeobject.js +1 -1
- package/dist/Runtime/Extensions/TileMap/tilemapcollisionmaskruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/TileMap/tilemapruntimeobject-pixi-renderer.js +1 -1
- package/dist/Runtime/Extensions/TileMap/tilemapruntimeobject-pixi-renderer.js.map +2 -2
- package/dist/Runtime/Extensions/TileMap/tilemapruntimeobject.js +1 -1
- package/dist/Runtime/Extensions/TileMap/tilemapruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/TiledSpriteObject/tiledspriteruntimeobject.js +1 -1
- package/dist/Runtime/Extensions/TiledSpriteObject/tiledspriteruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/TopDownMovementBehavior/topdownmovementruntimebehavior.js +1 -1
- package/dist/Runtime/Extensions/TopDownMovementBehavior/topdownmovementruntimebehavior.js.map +2 -2
- package/dist/Runtime/Extensions/TweenBehavior/TweenManager.js +2 -2
- package/dist/Runtime/Extensions/TweenBehavior/TweenManager.js.map +2 -2
- package/dist/Runtime/Extensions/TweenBehavior/tweenruntimebehavior.js +1 -1
- package/dist/Runtime/Extensions/TweenBehavior/tweenruntimebehavior.js.map +2 -2
- package/dist/Runtime/Extensions/TweenBehavior/tweentools.js +1 -1
- package/dist/Runtime/Extensions/TweenBehavior/tweentools.js.map +2 -2
- package/dist/Runtime/Extensions/Video/videoruntimeobject.js +1 -1
- package/dist/Runtime/Extensions/Video/videoruntimeobject.js.map +2 -2
- package/dist/Runtime/RuntimeInstanceContainer.js +1 -1
- package/dist/Runtime/RuntimeInstanceContainer.js.map +2 -2
- package/dist/Runtime/RuntimeLayer.js +1 -1
- package/dist/Runtime/RuntimeLayer.js.map +2 -2
- package/dist/Runtime/debugger-client/hot-reloader.js +1 -1
- package/dist/Runtime/debugger-client/hot-reloader.js.map +2 -2
- package/dist/Runtime/events-tools/objecttools.js +1 -1
- package/dist/Runtime/events-tools/objecttools.js.map +2 -2
- package/dist/Runtime/events-tools/runtimescenetools.js +1 -1
- package/dist/Runtime/events-tools/runtimescenetools.js.map +2 -2
- package/dist/Runtime/gd.js +1 -1
- package/dist/Runtime/gd.js.map +2 -2
- package/dist/Runtime/howler-sound-manager/howler-sound-manager.js +1 -1
- package/dist/Runtime/howler-sound-manager/howler-sound-manager.js.map +2 -2
- package/dist/Runtime/indexeddb.js +2 -0
- package/dist/Runtime/indexeddb.js.map +7 -0
- package/dist/Runtime/oncetriggers.js +1 -1
- package/dist/Runtime/oncetriggers.js.map +2 -2
- package/dist/Runtime/runtimebehavior.js +1 -1
- package/dist/Runtime/runtimebehavior.js.map +2 -2
- package/dist/Runtime/runtimegame.js +1 -1
- package/dist/Runtime/runtimegame.js.map +2 -2
- package/dist/Runtime/runtimeobject.js +1 -1
- package/dist/Runtime/runtimeobject.js.map +2 -2
- package/dist/Runtime/runtimescene.js +1 -1
- package/dist/Runtime/runtimescene.js.map +2 -2
- package/dist/Runtime/scenestack.js +1 -1
- package/dist/Runtime/scenestack.js.map +2 -2
- package/dist/Runtime/spriteruntimeobject.js +1 -1
- package/dist/Runtime/spriteruntimeobject.js.map +2 -2
- package/dist/Runtime/timemanager.js +1 -1
- package/dist/Runtime/timemanager.js.map +2 -2
- package/dist/Runtime/timer.js +1 -1
- package/dist/Runtime/timer.js.map +2 -2
- package/dist/Runtime/types/global-types.d.ts +29 -0
- package/dist/Runtime/types/project-data.d.ts +144 -3
- package/dist/Runtime/types/save-state.d.ts +9 -0
- package/dist/Runtime/variable.js +1 -1
- package/dist/Runtime/variable.js.map +2 -2
- package/dist/Runtime/variablescontainer.js +1 -1
- package/dist/Runtime/variablescontainer.js.map +2 -2
- package/dist/lib/libGD.cjs +1 -1
- package/dist/lib/libGD.wasm +0 -0
- package/dist/loaders.cjs +1 -1
- package/gd.d.ts +1 -0
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../GDevelop/Extensions/Physics2Behavior/physics2runtimebehavior.ts"],
|
|
4
|
-
"sourcesContent": ["namespace Box2D {\n export interface b2Body {\n gdjsAssociatedBehavior: gdjs.Physics2RuntimeBehavior | null;\n }\n}\nnamespace gdjs {\n export interface RuntimeScene {\n physics2SharedData: gdjs.Physics2SharedData | null;\n }\n interface Physics2NetworkSyncDataType {\n tpx: number | undefined;\n tpy: number | undefined;\n tqa: number | undefined;\n lvx: number | undefined;\n lvy: number | undefined;\n av: number | undefined;\n aw: boolean | undefined;\n layers: number;\n masks: number;\n }\n\n export interface Physics2NetworkSyncData extends BehaviorNetworkSyncData {\n props: Physics2NetworkSyncDataType;\n }\n export class Physics2SharedData {\n gravityX: float;\n gravityY: float;\n worldScale: float;\n worldInvScale: float;\n /** @deprecated Use `worldScale` instead */\n scaleX: float;\n /** @deprecated Use `worldScale` instead */\n scaleY: float;\n /** @deprecated Use `worldInvScale` instead */\n invScaleX: float;\n /** @deprecated Use `worldInvScale` instead */\n invScaleY: float;\n\n timeStep: float;\n frameTime: float = 0;\n stepped: boolean = false;\n timeScale: float = 1;\n\n world: Box2D.b2World;\n staticBody: Box2D.b2Body;\n /** Contact listener to keep track of current collisions */\n contactListener: Box2D.JSContactListener;\n _nextJointId: number = 1;\n /** Start with 1 so the user is safe from default variables value (0) */\n joints: { [key: string]: Box2D.b2Joint } = {};\n /** Avoid creating new vectors all the time */\n _tempb2Vec2 = new Box2D.b2Vec2(0, 0);\n /** Sometimes two vectors are needed on the same function call */\n _tempb2Vec2Sec = new Box2D.b2Vec2(0, 0);\n\n /**\n * List of physics behavior in the runtimeScene. It should be updated\n * when a new physics object is created (constructor), on destruction (onDestroy),\n * on behavior activation (onActivate) and on behavior deactivation (onDeActivate).\n */\n _registeredBehaviors: Set<Physics2RuntimeBehavior>;\n\n constructor(instanceContainer: gdjs.RuntimeInstanceContainer, sharedData) {\n this._registeredBehaviors = new Set();\n this.gravityX = sharedData.gravityX;\n this.gravityY = sharedData.gravityY;\n this.scaleX = sharedData.scaleX || 100;\n this.scaleY = sharedData.scaleY || 100;\n this.invScaleX = 1 / this.scaleX;\n this.invScaleY = 1 / this.scaleY;\n this.worldScale =\n sharedData.worldScale || Math.sqrt(this.scaleX * this.scaleY);\n this.worldInvScale = 1 / this.worldScale;\n this.timeStep = 1 / 60;\n this.world = new Box2D.b2World(this.b2Vec2(this.gravityX, this.gravityY));\n this.world.SetAutoClearForces(false);\n this.staticBody = this.world.CreateBody(new Box2D.b2BodyDef());\n this.contactListener = new Box2D.JSContactListener();\n this.contactListener.BeginContact = function (contactPtr) {\n // Get the contact\n const contact = Box2D.wrapPointer(\n contactPtr as number,\n Box2D.b2Contact\n );\n\n // There is no body, return\n if (\n contact.GetFixtureA().GetBody() === null ||\n contact.GetFixtureB().GetBody() === null\n ) {\n return;\n }\n\n // Get associated behaviors\n const behaviorA = contact\n .GetFixtureA()\n .GetBody().gdjsAssociatedBehavior;\n const behaviorB = contact\n .GetFixtureB()\n .GetBody().gdjsAssociatedBehavior;\n\n if (!behaviorA || !behaviorB) {\n return;\n }\n\n behaviorA.onContactBegin(behaviorB);\n behaviorB.onContactBegin(behaviorA);\n };\n this.contactListener.EndContact = function (contactPtr) {\n // Get the contact\n const contact = Box2D.wrapPointer(\n contactPtr as number,\n Box2D.b2Contact\n );\n\n // There is no body, return\n if (\n contact.GetFixtureA().GetBody() === null ||\n contact.GetFixtureB().GetBody() === null\n ) {\n return;\n }\n\n // Get associated behaviors\n const behaviorA = contact.GetFixtureA().GetBody()\n .gdjsAssociatedBehavior as Physics2RuntimeBehavior | null;\n const behaviorB = contact.GetFixtureB().GetBody()\n .gdjsAssociatedBehavior as Physics2RuntimeBehavior | null;\n\n if (!behaviorA || !behaviorB) {\n return;\n }\n\n behaviorA.onContactEnd(behaviorB);\n behaviorB.onContactEnd(behaviorA);\n };\n this.contactListener.PreSolve = function () {};\n this.contactListener.PostSolve = function () {};\n this.world.SetContactListener(this.contactListener);\n }\n\n b2Vec2(x: float, y: float): Box2D.b2Vec2 {\n const tempb2Vec2 = this._tempb2Vec2;\n tempb2Vec2.set_x(x);\n tempb2Vec2.set_y(y);\n return tempb2Vec2;\n }\n\n // (string)jointId -> (b2Joint)b2Joint\n static getSharedData(\n runtimeScene: gdjs.RuntimeScene,\n behaviorName: string\n ): gdjs.Physics2SharedData {\n // Create one if needed\n if (!runtimeScene.physics2SharedData) {\n const initialData =\n runtimeScene.getInitialSharedDataForBehavior(behaviorName);\n runtimeScene.physics2SharedData = new gdjs.Physics2SharedData(\n runtimeScene,\n initialData\n );\n }\n return runtimeScene.physics2SharedData;\n }\n\n /**\n * Add a physics object to the list of existing object.\n */\n addToBehaviorsList(physicsBehavior: gdjs.Physics2RuntimeBehavior): void {\n this._registeredBehaviors.add(physicsBehavior);\n }\n\n /**\n * Remove a physics object to the list of existing object.\n */\n removeFromBehaviorsList(\n physicsBehavior: gdjs.Physics2RuntimeBehavior\n ): void {\n this._registeredBehaviors.delete(physicsBehavior);\n }\n\n step(deltaTime: float): void {\n // Reset started and ended contacts array for all physics instances.\n for (const physicsBehavior of this._registeredBehaviors) {\n physicsBehavior.contactsStartedThisFrame.length = 0;\n physicsBehavior.contactsEndedThisFrame.length = 0;\n }\n for (const physicsBehavior of this._registeredBehaviors) {\n physicsBehavior.updateBodyFromObject();\n }\n\n this.frameTime += deltaTime;\n // `frameTime` can take negative values.\n // It's better to be a bit early rather than skipping a frame and being\n // a lot more late.\n let numberOfSteps = Math.max(\n 0,\n Math.round(this.frameTime / this.timeStep)\n );\n this.frameTime -= numberOfSteps * this.timeStep;\n if (numberOfSteps > 5) {\n numberOfSteps = 5;\n }\n for (let i = 0; i < numberOfSteps; i++) {\n this.world.Step(this.timeStep * this.timeScale, 8, 10);\n }\n this.world.ClearForces();\n this.stepped = true;\n\n // It's important that updateBodyFromObject and updateObjectFromBody are\n // called at the same time because other behavior may move the object in\n // their doStepPreEvents.\n for (const physicsBehavior of this._registeredBehaviors) {\n physicsBehavior.updateObjectFromBody();\n }\n }\n\n clearBodyJoints(body: Box2D.b2Body): void {\n // Iterate through all the joints\n for (const jointId in this.joints) {\n if (this.joints.hasOwnProperty(jointId)) {\n // If the joint is attached to the body, delete it\n if (\n this.joints[jointId].GetBodyA() === body ||\n this.joints[jointId].GetBodyB() === body\n ) {\n this.removeJoint(jointId);\n }\n }\n }\n }\n\n addJoint(joint: Box2D.b2Joint): integer {\n // Add the joint to the list\n this.joints[this._nextJointId.toString(10)] = joint;\n\n // Return the current joint id and then increase it\n return this._nextJointId++;\n }\n\n getJoint(jointId: integer | string): Box2D.b2Joint | null {\n // Cast to string\n jointId = jointId.toString(10);\n\n // Get the joint\n if (this.joints.hasOwnProperty(jointId)) {\n return this.joints[jointId];\n }\n\n // Joint not found, return null\n return null;\n }\n\n getJointId(joint: Box2D.b2Joint): integer {\n // Search the joint in the list and return the ID\n for (const jointId in this.joints) {\n if (this.joints.hasOwnProperty(jointId)) {\n if (this.joints[jointId] === joint) {\n return parseInt(jointId, 10);\n }\n }\n }\n\n // Joint not found, return 0\n return 0;\n }\n\n removeJoint(jointId: integer | string) {\n // Cast to string\n jointId = jointId.toString(10);\n\n // Delete the joint\n if (this.joints.hasOwnProperty(jointId)) {\n const joint = this.joints[jointId];\n\n // If we delete a joint attached to a gear joint, the gear will crash, so we must delete the gear joint first\n // Search in our joints list gear joints attached to this one we want to remove\n // The joint can be attached to a gear joint if it's revolute or prismatic only\n if (\n joint.GetType() === Box2D.e_revoluteJoint ||\n joint.GetType() === Box2D.e_prismaticJoint\n ) {\n for (const jId in this.joints) {\n if (this.joints.hasOwnProperty(jId)) {\n // Must check pointers because gears store non-casted joints (b2Joint)\n if (\n this.joints[jId].GetType() === Box2D.e_gearJoint &&\n (Box2D.getPointer(\n (this.joints[jId] as Box2D.b2GearJoint).GetJoint1()\n ) === Box2D.getPointer(joint) ||\n Box2D.getPointer(\n (this.joints[jId] as Box2D.b2GearJoint).GetJoint2()\n ) === Box2D.getPointer(joint))\n ) {\n // We could pass it a string, but lets do it right\n this.removeJoint(parseInt(jId, 10));\n }\n }\n }\n }\n\n // Remove the joint\n this.world.DestroyJoint(joint);\n delete this.joints[jointId];\n }\n }\n }\n gdjs.registerRuntimeSceneUnloadedCallback(function (runtimeScene) {\n const physics2SharedData = runtimeScene.physics2SharedData;\n if (physics2SharedData && physics2SharedData.world) {\n Box2D.destroy(physics2SharedData.world);\n Box2D.destroy(physics2SharedData._tempb2Vec2);\n Box2D.destroy(physics2SharedData._tempb2Vec2Sec);\n }\n });\n\n export class Physics2RuntimeBehavior extends gdjs.RuntimeBehavior {\n bodyType: string;\n bullet: boolean;\n fixedRotation: boolean;\n canSleep: boolean;\n shape: string;\n shapeDimensionA: any;\n shapeDimensionB: any;\n shapeOffsetX: float;\n shapeOffsetY: float;\n polygonOrigin: string;\n polygon: gdjs.Polygon | null;\n density: float;\n friction: float;\n restitution: float;\n linearDamping: float;\n angularDamping: float;\n gravityScale: float;\n layers: integer;\n masks: integer;\n shapeScale: number = 1;\n\n /**\n * Array containing the beginning of contacts reported by onContactBegin. Each contact\n * should be unique to avoid recording glitches where the object loses and regain\n * contact between two frames. The array is updated each time the method\n * onContactBegin is called by the listener, which is only called when stepping\n * the world i.e. in the first preEvent called by a physics behavior. This array is\n * cleared just before stepping the world.\n */\n contactsStartedThisFrame: Array<Physics2RuntimeBehavior>;\n\n /**\n * Array containing the end of contacts reported by onContactEnd. The array is updated\n * each time the method onContactEnd is called by the listener, which can be called at\n * any time. This array is cleared just before stepping the world.\n */\n contactsEndedThisFrame: Array<Physics2RuntimeBehavior>;\n\n /**\n * Array containing the exact current contacts with the objects. It is updated\n * each time the methods onContactBegin and onContactEnd are called by the contact\n * listener.\n */\n currentContacts: Array<Physics2RuntimeBehavior>;\n destroyedDuringFrameLogic: boolean;\n _body: Box2D.b2Body | null = null;\n\n /**\n * sharedData is a reference to the shared data of the scene, that registers\n * every physics behavior that is created so that collisions can be cleared\n * before stepping the world.\n */\n _sharedData: Physics2SharedData;\n\n _objectOldX: number = 0;\n _objectOldY: number = 0;\n _objectOldAngle: float = 0;\n _objectOldWidth: float = 0;\n _objectOldHeight: float = 0;\n _verticesBuffer: integer = 0;\n\n constructor(\n instanceContainer: gdjs.RuntimeInstanceContainer,\n behaviorData,\n owner: gdjs.RuntimeObject\n ) {\n super(instanceContainer, behaviorData, owner);\n this.bodyType = behaviorData.bodyType;\n this.bullet = behaviorData.bullet;\n this.fixedRotation = behaviorData.fixedRotation;\n this.canSleep = behaviorData.canSleep;\n this.shape = behaviorData.shape;\n this.shapeDimensionA = behaviorData.shapeDimensionA;\n this.shapeDimensionB = behaviorData.shapeDimensionB;\n this.shapeOffsetX = behaviorData.shapeOffsetX;\n this.shapeOffsetY = behaviorData.shapeOffsetY;\n this.polygonOrigin = behaviorData.polygonOrigin;\n this.polygon =\n this.shape === 'Polygon'\n ? Physics2RuntimeBehavior.getPolygon(behaviorData.vertices)\n : null;\n this.density = behaviorData.density;\n this.friction = behaviorData.friction;\n this.restitution = behaviorData.restitution;\n this.linearDamping = Math.max(0, behaviorData.linearDamping);\n this.angularDamping = Math.max(0, behaviorData.angularDamping);\n this.gravityScale = behaviorData.gravityScale;\n this.layers = behaviorData.layers;\n this.masks = behaviorData.masks;\n this.contactsStartedThisFrame = [];\n this.contactsEndedThisFrame = [];\n this.currentContacts = [];\n this.currentContacts.length = 0;\n this.destroyedDuringFrameLogic = false;\n this._sharedData = Physics2SharedData.getSharedData(\n instanceContainer.getScene(),\n behaviorData.name\n );\n this._sharedData.addToBehaviorsList(this);\n }\n\n // Stores a Box2D pointer of created vertices\n b2Vec2(x: float, y: float): Box2D.b2Vec2 {\n const tempb2Vec2 = this._sharedData._tempb2Vec2;\n tempb2Vec2.set_x(x);\n tempb2Vec2.set_y(y);\n return tempb2Vec2;\n }\n\n b2Vec2Sec(x: float, y: float): Box2D.b2Vec2 {\n const tempb2Vec2Sec = this._sharedData._tempb2Vec2Sec;\n tempb2Vec2Sec.set_x(x);\n tempb2Vec2Sec.set_y(y);\n return tempb2Vec2Sec;\n }\n\n updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {\n if (oldBehaviorData.bullet !== newBehaviorData.bullet) {\n this.setBullet(newBehaviorData.bullet);\n }\n if (oldBehaviorData.fixedRotation !== newBehaviorData.fixedRotation) {\n this.setFixedRotation(newBehaviorData.fixedRotation);\n }\n if (oldBehaviorData.canSleep !== newBehaviorData.canSleep) {\n this.setSleepingAllowed(newBehaviorData.canSleep);\n }\n if (oldBehaviorData.shapeDimensionA !== newBehaviorData.shapeDimensionA) {\n this.shapeDimensionA = newBehaviorData.shapeDimensionA;\n this.recreateShape();\n }\n if (oldBehaviorData.shapeDimensionB !== newBehaviorData.shapeDimensionB) {\n this.shapeDimensionB = newBehaviorData.shapeDimensionB;\n this.recreateShape();\n }\n if (oldBehaviorData.shapeOffsetX !== newBehaviorData.shapeOffsetX) {\n this.shapeOffsetX = newBehaviorData.shapeOffsetX;\n this.recreateShape();\n }\n if (oldBehaviorData.shapeOffsetY !== newBehaviorData.shapeOffsetY) {\n this.shapeOffsetY = newBehaviorData.shapeOffsetY;\n this.recreateShape();\n }\n if (oldBehaviorData.polygonOrigin !== newBehaviorData.polygonOrigin) {\n this.polygonOrigin = newBehaviorData.polygonOrigin;\n this.recreateShape();\n }\n if (oldBehaviorData.density !== newBehaviorData.density) {\n this.setDensity(newBehaviorData.density);\n }\n if (oldBehaviorData.friction !== newBehaviorData.friction) {\n this.setFriction(newBehaviorData.friction);\n }\n if (oldBehaviorData.restitution !== newBehaviorData.restitution) {\n this.setRestitution(newBehaviorData.restitution);\n }\n if (oldBehaviorData.linearDamping !== newBehaviorData.linearDamping) {\n this.setLinearDamping(newBehaviorData.linearDamping);\n }\n if (oldBehaviorData.angularDamping !== newBehaviorData.angularDamping) {\n this.setAngularDamping(newBehaviorData.angularDamping);\n }\n if (oldBehaviorData.gravityScale !== newBehaviorData.gravityScale) {\n this.setGravityScale(newBehaviorData.gravityScale);\n }\n\n // TODO: make these properties updatable.\n if (oldBehaviorData.layers !== newBehaviorData.layers) {\n return false;\n }\n if (oldBehaviorData.masks !== newBehaviorData.masks) {\n return false;\n }\n if (oldBehaviorData.vertices !== newBehaviorData.vertices) {\n return false;\n }\n if (oldBehaviorData.bodyType !== newBehaviorData.bodyType) {\n return false;\n }\n if (oldBehaviorData.shape !== newBehaviorData.shape) {\n return false;\n }\n return true;\n }\n\n getNetworkSyncData(): Physics2NetworkSyncData {\n const bodyProps = this._body\n ? {\n tpx: this._body.GetTransform().get_p().get_x(),\n tpy: this._body.GetTransform().get_p().get_y(),\n tqa: this._body.GetTransform().get_q().GetAngle(),\n lvx: this._body.GetLinearVelocity().get_x(),\n lvy: this._body.GetLinearVelocity().get_y(),\n av: this._body.GetAngularVelocity(),\n aw: this._body.IsAwake(),\n }\n : {\n tpx: undefined,\n tpy: undefined,\n tqa: undefined,\n lvx: undefined,\n lvy: undefined,\n av: undefined,\n aw: undefined,\n };\n return {\n ...super.getNetworkSyncData(),\n props: {\n ...bodyProps,\n layers: this.layers,\n masks: this.masks,\n },\n };\n }\n\n updateFromNetworkSyncData(networkSyncData: Physics2NetworkSyncData) {\n super.updateFromNetworkSyncData(networkSyncData);\n\n const behaviorSpecificProps = networkSyncData.props;\n if (\n behaviorSpecificProps.tpx !== undefined &&\n behaviorSpecificProps.tpy !== undefined &&\n behaviorSpecificProps.tqa !== undefined\n ) {\n if (this._body) {\n this._body.SetTransform(\n this.b2Vec2(behaviorSpecificProps.tpx, behaviorSpecificProps.tpy),\n behaviorSpecificProps.tqa\n );\n }\n }\n\n if (\n behaviorSpecificProps.lvx !== undefined &&\n behaviorSpecificProps.lvy !== undefined\n ) {\n if (this._body) {\n this._body.SetLinearVelocity(\n this.b2Vec2(behaviorSpecificProps.lvx, behaviorSpecificProps.lvy)\n );\n }\n }\n\n if (behaviorSpecificProps.av !== undefined) {\n if (this._body) {\n this._body.SetAngularVelocity(behaviorSpecificProps.av);\n }\n }\n\n if (behaviorSpecificProps.aw !== undefined) {\n if (this._body) {\n this._body.SetAwake(behaviorSpecificProps.aw);\n }\n }\n\n if (behaviorSpecificProps.layers !== undefined) {\n this.layers = behaviorSpecificProps.layers;\n }\n\n if (behaviorSpecificProps.masks !== undefined) {\n this.masks = behaviorSpecificProps.masks;\n }\n }\n\n onDeActivate() {\n this._sharedData.removeFromBehaviorsList(this);\n if (this._body !== null) {\n // When a body is deleted, Box2D removes automatically its joints, leaving an invalid pointer in our joints list\n this._sharedData.clearBodyJoints(this._body);\n\n // Delete the vertices\n if (this._verticesBuffer) {\n Box2D._free(this._verticesBuffer);\n this._verticesBuffer = 0;\n }\n\n // Delete the body\n this._sharedData.world.DestroyBody(this._body);\n this._body = null;\n }\n this.contactsEndedThisFrame.length = 0;\n this.contactsStartedThisFrame.length = 0;\n this.currentContacts.length = 0;\n }\n\n onActivate() {\n this._sharedData.addToBehaviorsList(this);\n\n this.contactsEndedThisFrame.length = 0;\n this.contactsStartedThisFrame.length = 0;\n this.currentContacts.length = 0;\n this.updateBodyFromObject();\n }\n\n onDestroy() {\n this.destroyedDuringFrameLogic = true;\n this.onDeActivate();\n }\n\n static getPolygon(verticesData: Box2D.b2Vec2[]): gdjs.Polygon | null {\n if (!verticesData) {\n return null;\n }\n const polygon = new gdjs.Polygon();\n const maxVertices = 8;\n for (\n let i = 0, len = verticesData.length;\n i < Math.min(len, maxVertices);\n i++\n ) {\n polygon.vertices.push([verticesData[i].x, verticesData[i].y]);\n }\n return polygon;\n }\n\n static isPolygonConvex(polygon: gdjs.Polygon): boolean {\n if (!polygon.isConvex()) {\n return false;\n }\n\n // Check for repeated vertices or check if all vertices are aligned (would crash Box2D)\n let alignedX = true;\n let alignedY = true;\n for (let i = 0; i < polygon.vertices.length - 1; ++i) {\n for (let j = i + 1; j < polygon.vertices.length; ++j) {\n if (\n polygon.vertices[i][0] === polygon.vertices[j][0] &&\n polygon.vertices[i][1] === polygon.vertices[j][1]\n ) {\n return false;\n }\n }\n if (polygon.vertices[i][0] !== polygon.vertices[i + 1][0]) {\n alignedX = false;\n }\n if (polygon.vertices[i][1] !== polygon.vertices[i + 1][1]) {\n alignedY = false;\n }\n }\n if (alignedX || alignedY) {\n return false;\n }\n return true;\n }\n\n createShape(): Box2D.b2FixtureDef {\n // Get the scaled offset\n const offsetX = this.shapeOffsetX\n ? this.shapeOffsetX * this.shapeScale * this._sharedData.worldInvScale\n : 0;\n const offsetY = this.shapeOffsetY\n ? this.shapeOffsetY * this.shapeScale * this._sharedData.worldInvScale\n : 0;\n\n // Generate the base shape\n let shape;\n if (this.shape === 'Circle') {\n shape = new Box2D.b2CircleShape();\n\n // Radius determined by the custom dimension\n // Average radius from width and height\n if (this.shapeDimensionA > 0) {\n shape.set_m_radius(\n Math.max(0.1, this.shapeDimensionA) *\n this.shapeScale *\n this._sharedData.worldInvScale\n );\n } else {\n const radius =\n (Math.max(0.1, this.owner.getWidth()) *\n this._sharedData.worldInvScale +\n Math.max(0.1, this.owner.getHeight()) *\n this._sharedData.worldInvScale) /\n 4;\n shape.set_m_radius(radius);\n }\n\n // Set the offset\n shape.set_m_p(this.b2Vec2(offsetX, offsetY));\n } else {\n if (this.shape === 'Polygon') {\n shape = new Box2D.b2PolygonShape();\n\n // Not convex, fall back to a box\n if (\n !this.polygon ||\n !Physics2RuntimeBehavior.isPolygonConvex(this.polygon)\n ) {\n const width =\n Math.max(0.1, this.owner.getWidth()) *\n this._sharedData.worldInvScale;\n const height =\n Math.max(0.1, this.owner.getHeight()) *\n this._sharedData.worldInvScale;\n\n // Set the shape box\n shape.SetAsBox(\n width / 2,\n height / 2,\n this.b2Vec2(offsetX, offsetY),\n 0\n );\n } else {\n let originOffsetX = 0;\n let originOffsetY = 0;\n if (this.polygonOrigin === 'Origin') {\n originOffsetX =\n (this.owner.getWidth() > 0 ? -this.owner.getWidth() / 2 : 0) +\n (this.owner.getX() - this.owner.getDrawableX());\n originOffsetY =\n (this.owner.getHeight() > 0 ? -this.owner.getHeight() / 2 : 0) +\n (this.owner.getY() - this.owner.getDrawableY());\n } else {\n if (this.polygonOrigin === 'TopLeft') {\n originOffsetX =\n this.owner.getWidth() > 0 ? -this.owner.getWidth() / 2 : 0;\n originOffsetY =\n this.owner.getHeight() > 0 ? -this.owner.getHeight() / 2 : 0;\n }\n }\n\n // Generate vertices if not done already\n if (!this._verticesBuffer) {\n // Store the vertices using a memory allocation function\n const buffer = Box2D._malloc(\n this.polygon.vertices.length * 8,\n 'float',\n Box2D.ALLOC_STACK\n );\n this._verticesBuffer = buffer;\n }\n\n // Overwrite the vertices stored in the buffer\n let offset = 0;\n for (let i = 0, len = this.polygon.vertices.length; i < len; i++) {\n Box2D.HEAPF32[(this._verticesBuffer + offset) >> 2] =\n (this.polygon.vertices[i][0] * this.shapeScale +\n originOffsetX) *\n this._sharedData.worldInvScale +\n offsetX;\n Box2D.HEAPF32[(this._verticesBuffer + (offset + 4)) >> 2] =\n (this.polygon.vertices[i][1] * this.shapeScale +\n originOffsetY) *\n this._sharedData.worldInvScale +\n offsetY;\n offset += 8;\n }\n\n // Set the shape vertices\n const b2Vertices = Box2D.wrapPointer(\n this._verticesBuffer,\n Box2D.b2Vec2\n );\n shape.Set(b2Vertices, this.polygon.vertices.length);\n }\n } else {\n if (this.shape === 'Edge') {\n shape = new Box2D.b2EdgeShape();\n\n // Length from the custom dimension or from the object width\n const length =\n (this.shapeDimensionA > 0\n ? Math.max(0.1, this.shapeDimensionA * this.shapeScale)\n : Math.max(0.1, this.owner.getWidth())) *\n this._sharedData.worldInvScale;\n const height =\n Math.max(0.1, this.owner.getHeight()) *\n this._sharedData.worldInvScale;\n\n // Angle from custom dimension, otherwise is 0\n const angle = this.shapeDimensionB\n ? gdjs.toRad(this.shapeDimensionB)\n : 0;\n\n // Set the edge vertices from the length, the angle and the offset\n shape.Set(\n this.b2Vec2(\n (-length / 2) * Math.cos(angle) + offsetX,\n height / 2 - (length / 2) * Math.sin(angle) + offsetY\n ),\n this.b2Vec2Sec(\n (length / 2) * Math.cos(angle) + offsetX,\n height / 2 + (length / 2) * Math.sin(angle) + offsetY\n )\n );\n } else {\n // Box\n shape = new Box2D.b2PolygonShape();\n\n // Width and height from custom dimensions or object size\n const width =\n (this.shapeDimensionA > 0\n ? Math.max(0.1, this.shapeDimensionA * this.shapeScale)\n : Math.max(0.1, this.owner.getWidth())) *\n this._sharedData.worldInvScale;\n const height =\n (this.shapeDimensionB > 0\n ? Math.max(0.1, this.shapeDimensionB * this.shapeScale)\n : Math.max(0.1, this.owner.getHeight())) *\n this._sharedData.worldInvScale;\n\n // Set the shape box, the offset must be added here too\n shape.SetAsBox(\n width / 2,\n height / 2,\n this.b2Vec2(offsetX, offsetY),\n 0\n );\n }\n }\n }\n\n // Generate filter data\n const filter = new Box2D.b2Filter();\n filter.set_categoryBits(this.layers);\n filter.set_maskBits(this.masks);\n\n // Generate the fixture definition\n const fixDef = new Box2D.b2FixtureDef();\n\n // Set fixture settings\n fixDef.set_shape(shape);\n fixDef.set_filter(filter);\n if (this.density < 0) {\n this.density = 0;\n }\n fixDef.set_density(this.density);\n if (this.friction < 0) {\n this.friction = 0;\n }\n fixDef.set_friction(this.friction);\n if (this.restitution < 0) {\n this.restitution = 0;\n }\n fixDef.set_restitution(this.restitution);\n\n // Return the fixture\n return fixDef;\n }\n\n recreateShape(): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Destroy the old shape\n body.DestroyFixture(body.GetFixtureList());\n body.CreateFixture(this.createShape());\n\n // Update cached size\n this._objectOldWidth = this.owner.getWidth();\n this._objectOldHeight = this.owner.getHeight();\n }\n\n getShapeScale(): float {\n return this.shapeScale;\n }\n\n setShapeScale(shapeScale: float): void {\n if (shapeScale !== this.shapeScale && shapeScale > 0) {\n this.shapeScale = shapeScale;\n this.recreateShape();\n }\n }\n\n getBody(): Box2D.b2Body {\n // If there is no body, set a new one\n if (this._body === null) {\n this.createBody();\n }\n return this._body!;\n }\n\n createBody(): boolean {\n if (!this.activated() || this.destroyedDuringFrameLogic) return false;\n // Generate the body definition\n const bodyDef = new Box2D.b2BodyDef();\n\n const x =\n (this.owner.getDrawableX() + this.owner.getWidth() / 2) *\n this._sharedData.worldInvScale;\n const y =\n (this.owner.getDrawableY() + this.owner.getHeight() / 2) *\n this._sharedData.worldInvScale;\n\n // Set the initial body transformation from the GD object\n bodyDef.set_position(\n this.b2Vec2(Number.isFinite(x) ? x : 0, Number.isFinite(y) ? y : 0)\n );\n const angle = gdjs.toRad(this.owner.getAngle());\n if (Number.isFinite(angle)) {\n bodyDef.set_angle(angle);\n }\n\n // Set body settings\n bodyDef.set_type(\n this.bodyType === 'Static'\n ? Box2D.b2_staticBody\n : this.bodyType === 'Kinematic'\n ? Box2D.b2_kinematicBody\n : Box2D.b2_dynamicBody\n );\n bodyDef.set_bullet(this.bullet);\n bodyDef.set_fixedRotation(this.fixedRotation);\n bodyDef.set_allowSleep(this.canSleep);\n bodyDef.set_linearDamping(this.linearDamping);\n bodyDef.set_angularDamping(this.angularDamping);\n bodyDef.set_gravityScale(this.gravityScale);\n\n // Create the body\n this._body = this._sharedData.world.CreateBody(bodyDef);\n this._body.CreateFixture(this.createShape());\n this._body.gdjsAssociatedBehavior = this;\n\n // Update cached size\n this._objectOldWidth = this.owner.getWidth();\n this._objectOldHeight = this.owner.getHeight();\n return true;\n }\n\n doStepPreEvents(instanceContainer: gdjs.RuntimeInstanceContainer) {\n // Step the world if not done this frame yet.\n // Don't step at the first frame to allow events to handle overlapping objects.\n if (\n !this._sharedData.stepped &&\n !instanceContainer.getScene().getTimeManager().isFirstFrame()\n ) {\n this._sharedData.step(\n instanceContainer.getScene().getTimeManager().getElapsedTime() /\n 1000.0\n );\n }\n }\n\n doStepPostEvents(instanceContainer: gdjs.RuntimeInstanceContainer) {\n // Reset world step to update next frame\n this._sharedData.stepped = false;\n }\n\n onObjectHotReloaded() {\n this.updateBodyFromObject();\n }\n\n updateObjectFromBody() {\n // Copy transform from body to the GD object.\n // The body is null when the behavior was either deactivated or the object deleted.\n // It would be useless to try to recreate it as updateBodyFromObject already does it.\n // If the body is null, we just don't do anything\n // (but still run the physics simulation - this is independent).\n if (this._body !== null && !this.isStatic() && this._body.IsAwake()) {\n this.owner.setX(\n this._body.GetPosition().get_x() * this._sharedData.worldScale -\n this.owner.getWidth() / 2 +\n this.owner.getX() -\n this.owner.getDrawableX()\n );\n this.owner.setY(\n this._body.GetPosition().get_y() * this._sharedData.worldScale -\n this.owner.getHeight() / 2 +\n this.owner.getY() -\n this.owner.getDrawableY()\n );\n this.owner.setAngle(gdjs.toDegrees(this._body.GetAngle()));\n }\n\n // Update cached transform.\n this._objectOldX = this.owner.getX();\n this._objectOldY = this.owner.getY();\n this._objectOldAngle = this.owner.getAngle();\n }\n\n updateBodyFromObject() {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // The object size has changed, recreate the shape.\n // The width has changed and there is no custom dimension A (box: width, circle: radius, edge: length) or\n // The height has changed, the shape is not an edge (edges doesn't have height),\n // it isn't a box with custom height or a circle with custom radius\n if (\n (this._objectOldWidth !== this.owner.getWidth() &&\n this.shapeDimensionA <= 0) ||\n (this._objectOldHeight !== this.owner.getHeight() &&\n this.shape !== 'Edge' &&\n !(this.shape === 'Box' && this.shapeDimensionB > 0) &&\n !(this.shape === 'Circle' && this.shapeDimensionA > 0))\n ) {\n this.recreateShape();\n }\n\n // The object object transform has changed, update body transform:\n if (\n this._objectOldX !== this.owner.getX() ||\n this._objectOldY !== this.owner.getY() ||\n this._objectOldAngle !== this.owner.getAngle()\n ) {\n const x =\n (this.owner.getDrawableX() + this.owner.getWidth() / 2) *\n this._sharedData.worldInvScale;\n const y =\n (this.owner.getDrawableY() + this.owner.getHeight() / 2) *\n this._sharedData.worldInvScale;\n const pos = this.b2Vec2(\n Number.isFinite(x) ? x : body.GetPosition().x,\n Number.isFinite(y) ? y : body.GetPosition().y\n );\n const angle = gdjs.toRad(this.owner.getAngle());\n body.SetTransform(\n pos,\n Number.isFinite(angle) ? angle : body.GetAngle()\n );\n body.SetAwake(true);\n }\n }\n\n getWorldScale(): float {\n return this._sharedData.worldScale;\n }\n\n getGravityX(): float {\n return this._sharedData.gravityX;\n }\n\n getGravityY(): float {\n return this._sharedData.gravityY;\n }\n\n setGravity(x: float, y: float): void {\n // Check if there is no modification\n if (this._sharedData.gravityX === x && this._sharedData.gravityY === y) {\n return;\n }\n\n // Change the gravity\n this._sharedData.gravityX = x;\n this._sharedData.gravityY = y;\n this._sharedData.world.SetGravity(\n this.b2Vec2(this._sharedData.gravityX, this._sharedData.gravityY)\n );\n }\n\n getTimeScale(): float {\n // Get the time scale\n return this._sharedData.timeScale;\n }\n\n setTimeScale(timeScale: float): void {\n // Invalid value\n if (timeScale < 0) {\n return;\n }\n\n // Set the time scale\n this._sharedData.timeScale = timeScale;\n }\n\n static setTimeScaleFromObject(object, behaviorName, timeScale) {\n // Check if the object exist and has the behavior\n if (object === null || !object.hasBehavior(behaviorName)) {\n return;\n }\n\n // Set the time scale\n object.getBehavior(behaviorName).setTimeScale(timeScale);\n }\n\n isDynamic(): boolean {\n return this.bodyType === 'Dynamic';\n }\n\n setDynamic(): void {\n // Check if there is no modification\n if (this.bodyType === 'Dynamic') {\n return;\n }\n\n // Change body type\n this.bodyType = 'Dynamic';\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update body type\n body.SetType(Box2D.b2_dynamicBody);\n body.SetAwake(true);\n }\n\n isStatic(): boolean {\n return this.bodyType === 'Static';\n }\n\n setStatic(): void {\n // Check if there is no modification\n if (this.bodyType === 'Static') {\n return;\n }\n\n // Change body type\n this.bodyType = 'Static';\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update body type\n body.SetType(Box2D.b2_staticBody);\n body.SetAwake(true);\n }\n\n isKinematic(): boolean {\n return this.bodyType === 'Kinematic';\n }\n\n setKinematic(): void {\n // Check if there is no modification\n if (this.bodyType === 'Kinematic') {\n return;\n }\n\n // Change body type\n this.bodyType = 'Kinematic';\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update body type\n body.SetType(Box2D.b2_kinematicBody);\n body.SetAwake(true);\n }\n\n isBullet(): boolean {\n return this.bullet;\n }\n\n setBullet(enable: boolean): void {\n // Check if there is no modification\n if (this.bullet === enable) {\n return;\n }\n\n // Change bullet flag\n this.bullet = enable;\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update body bullet flag\n body.SetBullet(this.bullet);\n }\n\n hasFixedRotation(): boolean {\n return this.fixedRotation;\n }\n\n setFixedRotation(enable: boolean): void {\n this.fixedRotation = enable;\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n body.SetFixedRotation(this.fixedRotation);\n }\n\n isSleepingAllowed(): boolean {\n return this.canSleep;\n }\n\n setSleepingAllowed(enable: boolean): void {\n this.canSleep = enable;\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n body.SetSleepingAllowed(this.canSleep);\n }\n\n isSleeping(): boolean {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return true;\n }\n const body = this._body!;\n\n // Get the body sleeping state\n return !body.IsAwake();\n }\n\n getDensity() {\n return this.density;\n }\n\n setDensity(density: float): void {\n // Non-negative values only\n if (density < 0) {\n density = 0;\n }\n\n // Check if there is no modification\n if (this.density === density) {\n return;\n }\n\n // Change density\n this.density = density;\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update the body density\n body.GetFixtureList().SetDensity(this.density);\n body.ResetMassData();\n }\n\n getFriction(): float {\n return this.friction;\n }\n\n setFriction(friction): void {\n // Non-negative values only\n if (friction < 0) {\n friction = 0;\n }\n\n // Check if there is no modification\n if (this.friction === friction) {\n return;\n }\n\n // Change friction\n this.friction = friction;\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update the body friction\n body.GetFixtureList().SetFriction(this.friction);\n\n // Update contacts\n let contact = body.GetContactList();\n while (Box2D.getPointer(contact)) {\n contact.get_contact().ResetFriction();\n contact = contact.get_next();\n }\n }\n\n getRestitution(): float {\n return this.restitution;\n }\n\n setRestitution(restitution: float): void {\n // Non-negative values only\n if (restitution < 0) {\n restitution = 0;\n }\n\n // Check if there is no modification\n if (this.restitution === restitution) {\n return;\n }\n\n // Change restitution\n this.restitution = restitution;\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update the body restitution\n body.GetFixtureList().SetRestitution(this.restitution);\n\n // Update contacts\n let contact = body.GetContactList();\n while (Box2D.getPointer(contact)) {\n contact.get_contact().ResetRestitution();\n contact = contact.get_next();\n }\n }\n\n getLinearDamping(): float {\n return this.linearDamping;\n }\n\n setLinearDamping(linearDamping: float): void {\n // Non-negative values only\n if (linearDamping < 0) {\n linearDamping = 0;\n }\n\n // Check if there is no modification\n if (this.linearDamping === linearDamping) {\n return;\n }\n\n // Change linearDamping\n this.linearDamping = linearDamping;\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update the body linear damping\n body.SetLinearDamping(this.linearDamping);\n }\n\n getAngularDamping(): float {\n return this.angularDamping;\n }\n\n setAngularDamping(angularDamping: float): void {\n // Non-negative values only\n if (angularDamping < 0) {\n angularDamping = 0;\n }\n\n // Check if there is no modification\n if (this.angularDamping === angularDamping) {\n return;\n }\n\n // Change angularDamping\n this.angularDamping = angularDamping;\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update the body angular damping\n body.SetAngularDamping(this.angularDamping);\n }\n\n getGravityScale(): float {\n return this.gravityScale;\n }\n\n setGravityScale(gravityScale: float): void {\n // Check if there is no modification\n if (this.gravityScale === gravityScale) {\n return;\n }\n\n // Change the gravity scale\n this.gravityScale = gravityScale;\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update the body gravity scale\n body.SetGravityScale(this.gravityScale);\n }\n\n layerEnabled(layer: integer) {\n // Layer must be an integer\n layer = Math.floor(layer);\n\n // Layer must be in range [1, 16]\n if (layer < 1 || layer > 16) {\n return false;\n }\n return !!(this.layers & (1 << (layer - 1)));\n }\n\n enableLayer(layer: integer, enable: boolean): void {\n // Layer must be an integer\n layer = Math.floor(layer);\n\n // Layer must be in range [1, 16]\n if (layer < 1 || layer > 16) {\n return;\n }\n\n // Change the layers\n if (enable) {\n this.layers |= 1 << (layer - 1);\n } else {\n this.layers &= ~(1 << (layer - 1));\n }\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update the body layers\n const filter = body.GetFixtureList().GetFilterData();\n filter.set_categoryBits(this.layers);\n body.GetFixtureList().SetFilterData(filter);\n }\n\n maskEnabled(mask: integer): boolean {\n // Mask must be an integer\n mask = Math.floor(mask);\n\n // Mask must be in range [1, 16]\n if (mask < 1 || mask > 16) {\n return false;\n }\n return !!(this.masks & (1 << (mask - 1)));\n }\n\n enableMask(mask: integer, enable: boolean): void {\n // Mask must be an integer\n mask = Math.floor(mask);\n\n // Mask must be in range [1, 16]\n if (mask < 1 || mask > 16) {\n return;\n }\n\n // Change the masks\n if (enable) {\n this.masks |= 1 << (mask - 1);\n } else {\n this.masks &= ~(1 << (mask - 1));\n }\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update the body masks\n const filter = body.GetFixtureList().GetFilterData();\n filter.set_maskBits(this.masks);\n body.GetFixtureList().SetFilterData(filter);\n }\n\n getLinearVelocityX(): float {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return 0;\n }\n const body = this._body!;\n\n // Get the linear velocity on X\n return body.GetLinearVelocity().get_x() * this._sharedData.worldScale;\n }\n\n setLinearVelocityX(linearVelocityX: float): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Set the linear velocity on X\n body.SetLinearVelocity(\n this.b2Vec2(\n linearVelocityX * this._sharedData.worldInvScale,\n body.GetLinearVelocity().get_y()\n )\n );\n }\n\n getLinearVelocityY(): float {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return 0;\n }\n const body = this._body!;\n\n // Get the linear velocity on Y\n return body.GetLinearVelocity().get_y() * this._sharedData.worldScale;\n }\n\n setLinearVelocityY(linearVelocityY: float): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Set the linear velocity on Y\n body.SetLinearVelocity(\n this.b2Vec2(\n body.GetLinearVelocity().get_x(),\n linearVelocityY * this._sharedData.worldInvScale\n )\n );\n }\n\n getLinearVelocityLength(): float {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return 0;\n }\n const body = this._body!;\n\n // Get the linear velocity length\n return this.b2Vec2(\n body.GetLinearVelocity().get_x() * this._sharedData.worldScale,\n body.GetLinearVelocity().get_y() * this._sharedData.worldScale\n ).Length();\n }\n\n getLinearVelocityAngle(): float {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return 0;\n }\n const body = this._body!;\n\n // Get the linear velocity angle\n return gdjs.toDegrees(\n Math.atan2(\n body.GetLinearVelocity().get_y() * this._sharedData.worldScale,\n body.GetLinearVelocity().get_x() * this._sharedData.worldScale\n )\n );\n }\n\n setLinearVelocityAngle(angle: float, linearVelocity: float): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Set the linear velocity toward an angle\n angle = gdjs.toRad(angle);\n body.SetLinearVelocity(\n this.b2Vec2(\n linearVelocity * Math.cos(angle) * this._sharedData.worldInvScale,\n linearVelocity * Math.sin(angle) * this._sharedData.worldInvScale\n )\n );\n }\n\n isLinearVelocityAngleAround(degreeAngle: float, tolerance: float) {\n return (\n Math.abs(\n gdjs.evtTools.common.angleDifference(\n this.getLinearVelocityAngle(),\n degreeAngle\n )\n ) <= tolerance\n );\n }\n\n getAngularVelocity(): float {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return 0;\n }\n const body = this._body!;\n\n // Get the angular velocity\n return gdjs.toDegrees(body.GetAngularVelocity());\n }\n\n setAngularVelocity(angularVelocity: float): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Set the angular velocity\n body.SetAngularVelocity(gdjs.toRad(angularVelocity));\n }\n\n applyForce(\n forceX: float,\n forceY: float,\n positionX: float,\n positionY: float\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Wake up the object\n body.SetAwake(true);\n\n // Apply the force\n body.ApplyForce(\n this.b2Vec2(forceX, forceY),\n this.b2Vec2Sec(\n positionX * this._sharedData.worldInvScale,\n positionY * this._sharedData.worldInvScale\n ),\n // TODO Should let Box2d awake the object itself.\n false\n );\n }\n\n applyPolarForce(\n angle: float,\n length: float,\n positionX: float,\n positionY: float\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Wake up the object\n body.SetAwake(true);\n\n // Apply the force\n angle = gdjs.toRad(angle);\n body.ApplyForce(\n this.b2Vec2(length * Math.cos(angle), length * Math.sin(angle)),\n this.b2Vec2Sec(\n positionX * this._sharedData.worldInvScale,\n positionY * this._sharedData.worldInvScale\n ),\n // TODO Should let Box2d awake the object itself.\n false\n );\n }\n\n applyForceTowardPosition(\n length: float,\n towardX: float,\n towardY: float,\n positionX: float,\n positionY: float\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Wake up the object\n body.SetAwake(true);\n\n // TODO Optimize this using a unit vector instead of trigonometry.\n // Apply the force\n const angle = Math.atan2(\n towardY * this._sharedData.worldInvScale - body.GetPosition().get_y(),\n towardX * this._sharedData.worldInvScale - body.GetPosition().get_x()\n );\n body.ApplyForce(\n this.b2Vec2(length * Math.cos(angle), length * Math.sin(angle)),\n this.b2Vec2Sec(\n positionX * this._sharedData.worldInvScale,\n positionY * this._sharedData.worldInvScale\n ),\n // TODO Should let Box2d awake the object itself.\n false\n );\n }\n\n applyImpulse(\n impulseX: float,\n impulseY: float,\n positionX: float,\n positionY: float\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Wake up the object\n body.SetAwake(true);\n\n // Apply the impulse\n body.ApplyLinearImpulse(\n this.b2Vec2(impulseX, impulseY),\n this.b2Vec2Sec(\n positionX * this._sharedData.worldInvScale,\n positionY * this._sharedData.worldInvScale\n ),\n // TODO Should let Box2d awake the object itself.\n false\n );\n }\n\n applyPolarImpulse(\n angle: float,\n length: float,\n positionX: float,\n positionY: float\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Wake up the object\n body.SetAwake(true);\n\n // Apply the impulse\n angle = gdjs.toRad(angle);\n body.ApplyLinearImpulse(\n this.b2Vec2(length * Math.cos(angle), length * Math.sin(angle)),\n this.b2Vec2Sec(\n positionX * this._sharedData.worldInvScale,\n positionY * this._sharedData.worldInvScale\n ),\n // TODO Should let Box2d awake the object itself.\n false\n );\n }\n\n applyImpulseTowardPosition(\n length: float,\n towardX: float,\n towardY: float,\n positionX: float,\n positionY: float\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Wake up the object\n body.SetAwake(true);\n\n // TODO Optimize this using a unit vector instead of trigonometry.\n // Apply the impulse\n const angle = Math.atan2(\n towardY * this._sharedData.worldInvScale - body.GetPosition().get_y(),\n towardX * this._sharedData.worldInvScale - body.GetPosition().get_x()\n );\n body.ApplyLinearImpulse(\n this.b2Vec2(length * Math.cos(angle), length * Math.sin(angle)),\n this.b2Vec2Sec(\n positionX * this._sharedData.worldInvScale,\n positionY * this._sharedData.worldInvScale\n ),\n // TODO Should let Box2d awake the object itself.\n false\n );\n }\n\n applyTorque(torque: float): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Wake up the object\n body.SetAwake(true);\n\n // Apply the torque\n body.ApplyTorque(\n torque,\n // TODO Should let Box2d awake the object itself.\n false\n );\n }\n\n applyAngularImpulse(angularImpulse: float): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Wake up the object\n body.SetAwake(true);\n\n // Apply the angular impulse\n body.ApplyAngularImpulse(\n angularImpulse,\n // TODO Should let Box2d awake the object itself.\n false\n );\n }\n\n getMass(): float {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return 0;\n }\n const body = this._body!;\n\n // Wake up the object\n body.SetAwake(true);\n\n return body.GetMass();\n }\n\n getInertia(): float {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return 0;\n }\n const body = this._body!;\n\n // Wake up the object\n body.SetAwake(true);\n\n return body.GetInertia();\n }\n\n getMassCenterX(): float {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return 0;\n }\n const body = this._body!;\n\n // Get the mass center on X\n return body.GetWorldCenter().get_x() * this._sharedData.worldScale;\n }\n\n getMassCenterY(): float {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return 0;\n }\n const body = this._body!;\n\n // Get the mass center on Y\n return body.GetWorldCenter().get_y() * this._sharedData.worldScale;\n }\n\n // Joints\n isJointFirstObject(jointId: integer | string): boolean {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return false;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId);\n\n // Joint not found\n if (joint === null) {\n return false;\n }\n\n // Check the joint object\n return joint.GetBodyA() === this._body;\n }\n\n isJointSecondObject(jointId: integer | string): boolean {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return false;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId);\n\n // Joint not found\n if (joint === null) {\n return false;\n }\n\n // Check the joint object\n return joint.GetBodyB() === this._body;\n }\n\n getJointFirstAnchorX(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId);\n\n // Joint not found\n if (joint === null) {\n return 0;\n }\n\n // Get the joint anchor\n // @ts-ignore GetLocalAnchorA is implemented by any joint but is not in the interface.\n return joint.GetBodyA().GetWorldPoint(joint.GetLocalAnchorA()).get_x();\n }\n\n getJointFirstAnchorY(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId);\n\n // Joint not found\n if (joint === null) {\n return 0;\n }\n\n // Get the joint anchor\n // @ts-ignore GetLocalAnchorA is implemented by any joint but is not in the interface.\n return joint.GetBodyA().GetWorldPoint(joint.GetLocalAnchorA()).get_y();\n }\n\n getJointSecondAnchorX(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId);\n\n // Joint not found\n if (joint === null) {\n return 0;\n }\n\n // Get the joint anchor\n // @ts-ignore GetLocalAnchorA is implemented by any joint but is not in the interface.\n return joint.GetBodyB().GetWorldPoint(joint.GetLocalAnchorB()).get_x();\n }\n\n getJointSecondAnchorY(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId);\n\n // Joint not found\n if (joint === null) {\n return 0;\n }\n\n // Get the joint anchor\n // @ts-ignore GetLocalAnchorA is implemented by any joint but is not in the interface.\n return joint.GetBodyB().GetWorldPoint(joint.GetLocalAnchorB()).get_y();\n }\n\n getJointReactionForce(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId);\n\n // Joint not found\n if (joint === null) {\n return 0;\n }\n\n // Get the reaction force\n return joint.GetReactionForce(1 / this._sharedData.timeStep).Length();\n }\n\n getJointReactionTorque(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId);\n\n // Joint not found\n if (joint === null) {\n return 0;\n }\n\n // Get the reaction torque\n return joint.GetReactionTorque(1 / this._sharedData.timeStep);\n }\n\n removeJoint(jointId: integer | string): void {\n // Just let the sharedData to manage and delete the joint\n this._sharedData.removeJoint(jointId);\n }\n\n // Distance joint\n addDistanceJoint(\n x1: float,\n y1: float,\n other: gdjs.RuntimeObject | null,\n x2: float,\n y2: float,\n length: float,\n frequency: float,\n dampingRatio: float,\n collideConnected: boolean,\n variable: gdjs.Variable\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // If there is no second object or it doesn't share the behavior, return\n if (other == null || !other.hasBehavior(this.name)) {\n return;\n }\n\n // Get the second body\n const otherBody = (\n other.getBehavior(this.name) as gdjs.Physics2RuntimeBehavior\n ).getBody();\n\n // If the first and second objects/bodies are the same, return\n if (this._body === otherBody) {\n return;\n }\n\n // Set joint settings\n const jointDef = new Box2D.b2DistanceJointDef();\n jointDef.set_bodyA(body);\n jointDef.set_localAnchorA(\n body.GetLocalPoint(\n this.b2Vec2(\n x1 * this._sharedData.worldInvScale,\n y1 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_bodyB(otherBody);\n jointDef.set_localAnchorB(\n otherBody.GetLocalPoint(\n this.b2Vec2(\n x2 * this._sharedData.worldInvScale,\n y2 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_length(\n length > 0\n ? length * this._sharedData.worldInvScale\n : this.b2Vec2(\n (x2 - x1) * this._sharedData.worldInvScale,\n (y2 - y1) * this._sharedData.worldInvScale\n ).Length()\n );\n jointDef.set_frequencyHz(frequency >= 0 ? frequency : 0);\n jointDef.set_dampingRatio(dampingRatio >= 0 ? dampingRatio : 1);\n jointDef.set_collideConnected(collideConnected);\n\n // Create the joint and get the id\n const jointId = this._sharedData.addJoint(\n Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2DistanceJoint\n )\n );\n\n // Store the id in the variable\n variable.setNumber(jointId);\n }\n\n getDistanceJointLength(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2DistanceJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_distanceJoint) {\n return 0;\n }\n\n // Get the joint length\n return joint.GetLength() * this._sharedData.worldScale;\n }\n\n setDistanceJointLength(jointId: integer | string, length: float): void {\n // Invalid value\n if (length <= 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2DistanceJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_distanceJoint) {\n return;\n }\n\n // Set the joint length\n joint.SetLength(length * this._sharedData.worldInvScale);\n\n // Awake the bodies\n joint.GetBodyA().SetAwake(true);\n joint.GetBodyB().SetAwake(true);\n }\n\n getDistanceJointFrequency(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2DistanceJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_distanceJoint) {\n return 0;\n }\n\n // Get the joint frequency\n return joint.GetFrequency();\n }\n\n setDistanceJointFrequency(\n jointId: integer | string,\n frequency: float\n ): void {\n // Invalid value\n if (frequency < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2DistanceJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_distanceJoint) {\n return;\n }\n\n // Set the joint frequency\n joint.SetFrequency(frequency);\n }\n\n getDistanceJointDampingRatio(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2DistanceJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_distanceJoint) {\n return 0;\n }\n\n // Get the joint damping ratio\n return joint.GetDampingRatio();\n }\n\n setDistanceJointDampingRatio(\n jointId: integer | string,\n dampingRatio: float\n ): void {\n // Invalid value\n if (dampingRatio < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2DistanceJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_distanceJoint) {\n }\n\n // Set the joint damping ratio\n joint.SetDampingRatio(dampingRatio);\n }\n\n // Revolute joint\n addRevoluteJoint(\n x: float,\n y: float,\n enableLimit: boolean,\n referenceAngle: float,\n lowerAngle: float,\n upperAngle: float,\n enableMotor: boolean,\n motorSpeed: float,\n maxMotorTorque: float,\n variable: gdjs.Variable\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Set joint settings\n const jointDef = new Box2D.b2RevoluteJointDef();\n jointDef.set_bodyA(this._sharedData.staticBody);\n jointDef.set_localAnchorA(\n this._sharedData.staticBody.GetLocalPoint(\n this.b2Vec2(\n x * this._sharedData.worldInvScale,\n y * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_bodyB(body);\n jointDef.set_localAnchorB(\n body.GetLocalPoint(\n this.b2Vec2(\n x * this._sharedData.worldInvScale,\n y * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_enableLimit(enableLimit);\n jointDef.set_referenceAngle(gdjs.toRad(referenceAngle));\n\n // Lower angle must be lower than upper angle\n if (upperAngle < lowerAngle) {\n const temp = lowerAngle;\n lowerAngle = upperAngle;\n upperAngle = temp;\n }\n jointDef.set_lowerAngle(gdjs.toRad(lowerAngle));\n jointDef.set_upperAngle(gdjs.toRad(upperAngle));\n jointDef.set_enableMotor(enableMotor);\n jointDef.set_motorSpeed(gdjs.toRad(motorSpeed));\n jointDef.set_maxMotorTorque(maxMotorTorque >= 0 ? maxMotorTorque : 0);\n jointDef.set_collideConnected(false);\n\n // Create the joint and get the id\n const jointId = this._sharedData.addJoint(\n Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2RevoluteJoint\n )\n );\n\n // Store the id in the variable\n variable.setNumber(jointId);\n }\n\n addRevoluteJointBetweenTwoBodies(\n x1: float,\n y1: float,\n other: gdjs.RuntimeObject | null,\n x2: float,\n y2: float,\n enableLimit: boolean,\n referenceAngle: float,\n lowerAngle: float,\n upperAngle: float,\n enableMotor: boolean,\n motorSpeed: float,\n maxMotorTorque: float,\n collideConnected: boolean,\n variable: gdjs.Variable\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n\n // If there is no second object or it doesn't share the behavior, return\n if (other == null || !other.hasBehavior(this.name)) {\n return;\n }\n\n // Get the second body\n const otherBody = (\n other.getBehavior(this.name) as gdjs.Physics2RuntimeBehavior\n ).getBody();\n\n // If the first and second objects/bodies are the same, return\n if (this._body === otherBody) {\n return;\n }\n const body = this._body!;\n\n // Set joint settings\n const jointDef = new Box2D.b2RevoluteJointDef();\n jointDef.set_bodyA(body);\n jointDef.set_localAnchorA(\n body.GetLocalPoint(\n this.b2Vec2(\n x1 * this._sharedData.worldInvScale,\n y1 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_bodyB(otherBody);\n jointDef.set_localAnchorB(\n otherBody.GetLocalPoint(\n this.b2Vec2(\n x2 * this._sharedData.worldInvScale,\n y2 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_enableLimit(enableLimit);\n jointDef.set_referenceAngle(gdjs.toRad(referenceAngle));\n\n // Lower angle must be lower than upper angle\n if (upperAngle < lowerAngle) {\n const temp = lowerAngle;\n lowerAngle = upperAngle;\n upperAngle = temp;\n }\n jointDef.set_lowerAngle(gdjs.toRad(lowerAngle));\n jointDef.set_upperAngle(gdjs.toRad(upperAngle));\n jointDef.set_enableMotor(enableMotor);\n jointDef.set_motorSpeed(gdjs.toRad(motorSpeed));\n jointDef.set_maxMotorTorque(maxMotorTorque >= 0 ? maxMotorTorque : 0);\n jointDef.set_collideConnected(collideConnected);\n\n // Create the joint and get the id\n const jointId = this._sharedData.addJoint(\n Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2RevoluteJoint\n )\n );\n\n // Store the id in the variable\n variable.setNumber(jointId);\n }\n\n getRevoluteJointReferenceAngle(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return 0;\n }\n\n // Get the joint reference angle\n return gdjs.toDegrees(joint.GetReferenceAngle());\n }\n\n getRevoluteJointAngle(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return 0;\n }\n\n // Get the joint current angle\n return gdjs.toDegrees(joint.GetJointAngle());\n }\n\n getRevoluteJointSpeed(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return 0;\n }\n\n // Get the joint angular speed\n return gdjs.toDegrees(joint.GetJointSpeed());\n }\n\n isRevoluteJointLimitsEnabled(jointId: integer | string): boolean {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return false;\n }\n\n // Get the joint limits state\n return joint.IsLimitEnabled();\n }\n\n enableRevoluteJointLimits(\n jointId: integer | string,\n enable: boolean\n ): void {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return;\n }\n\n // Set the joint limits state\n joint.EnableLimit(enable);\n }\n\n getRevoluteJointMinAngle(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return 0;\n }\n\n // Get the joint lower angle\n return gdjs.toDegrees(joint.GetLowerLimit());\n }\n\n getRevoluteJointMaxAngle(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return 0;\n }\n\n // Get the joint upper angle\n return gdjs.toDegrees(joint.GetUpperLimit());\n }\n\n setRevoluteJointLimits(\n jointId: integer | string,\n lowerAngle: float,\n upperAngle: float\n ): void {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return;\n }\n\n // Lower angle must be lower than upper angle\n if (upperAngle < lowerAngle) {\n const temp = lowerAngle;\n lowerAngle = upperAngle;\n upperAngle = temp;\n }\n\n // Set the joint limits\n joint.SetLimits(gdjs.toRad(lowerAngle), gdjs.toRad(upperAngle));\n }\n\n isRevoluteJointMotorEnabled(jointId: integer | string): boolean {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return false;\n }\n\n // Get the joint motor state\n return joint.IsMotorEnabled();\n }\n\n enableRevoluteJointMotor(jointId: integer | string, enable): void {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return;\n }\n\n // Set the joint motor state\n joint.EnableMotor(enable);\n }\n\n getRevoluteJointMotorSpeed(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return 0;\n }\n\n // Get the joint motor speed\n return gdjs.toDegrees(joint.GetMotorSpeed());\n }\n\n setRevoluteJointMotorSpeed(jointId: integer | string, speed): void {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return;\n }\n\n // Set the joint motor speed\n joint.SetMotorSpeed(gdjs.toRad(speed));\n }\n\n getRevoluteJointMaxMotorTorque(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return 0;\n }\n\n // Get the joint max motor\n return joint.GetMaxMotorTorque();\n }\n\n setRevoluteJointMaxMotorTorque(jointId: integer | string, maxTorque): void {\n // Invalid value\n if (maxTorque < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return;\n }\n\n // Set the joint max motor\n joint.SetMaxMotorTorque(maxTorque);\n }\n\n getRevoluteJointMotorTorque(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return 0;\n }\n\n // Get the joint motor torque\n return joint.GetMotorTorque(1 / this._sharedData.timeStep);\n }\n\n // Prismatic joint\n addPrismaticJoint(\n x1: float,\n y1: float,\n other: gdjs.RuntimeObject | null,\n x2: float,\n y2: float,\n axisAngle: float,\n referenceAngle: float,\n enableLimit: boolean,\n lowerTranslation: float,\n upperTranslation: float,\n enableMotor: boolean,\n motorSpeed: float,\n maxMotorForce: float,\n collideConnected: boolean,\n variable: gdjs.Variable\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n\n // If there is no second object or it doesn't share the behavior, return\n if (other == null || !other.hasBehavior(this.name)) {\n return;\n }\n\n // Get the second body\n const otherBody = (\n other.getBehavior(this.name) as gdjs.Physics2RuntimeBehavior\n ).getBody();\n\n // If the first and second objects/bodies are the same, return\n if (this._body === otherBody) {\n return;\n }\n const body = this._body!;\n\n // Set joint settings\n const jointDef = new Box2D.b2PrismaticJointDef();\n jointDef.set_bodyA(body);\n jointDef.set_localAnchorA(\n body.GetLocalPoint(\n this.b2Vec2(\n x1 * this._sharedData.worldInvScale,\n y1 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_bodyB(otherBody);\n jointDef.set_localAnchorB(\n otherBody.GetLocalPoint(\n this.b2Vec2(\n x2 * this._sharedData.worldInvScale,\n y2 * this._sharedData.worldInvScale\n )\n )\n );\n axisAngle = gdjs.toRad(axisAngle) - body.GetAngle();\n jointDef.set_localAxisA(\n this.b2Vec2(Math.cos(axisAngle), Math.sin(axisAngle))\n );\n jointDef.set_referenceAngle(gdjs.toRad(referenceAngle));\n jointDef.set_enableLimit(enableLimit);\n\n // Lower translation must be lower than upper translation\n if (upperTranslation < lowerTranslation) {\n const temp = lowerTranslation;\n lowerTranslation = upperTranslation;\n upperTranslation = temp;\n }\n\n // The translation range must include zero\n jointDef.set_lowerTranslation(\n lowerTranslation < 0\n ? lowerTranslation * this._sharedData.worldInvScale\n : 0\n );\n jointDef.set_upperTranslation(\n upperTranslation > 0\n ? upperTranslation * this._sharedData.worldInvScale\n : 0\n );\n jointDef.set_enableMotor(enableMotor);\n jointDef.set_motorSpeed(motorSpeed * this._sharedData.worldInvScale);\n jointDef.set_maxMotorForce(maxMotorForce);\n jointDef.set_collideConnected(collideConnected);\n\n // Create the joint and get the id\n const jointId = this._sharedData.addJoint(\n Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2PrismaticJoint\n )\n );\n\n // Store the id in the variable\n variable.setNumber(jointId);\n }\n\n getPrismaticJointAxisAngle(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return 0;\n }\n\n // Get the joint axis angle\n return gdjs.toDegrees(\n Math.atan2(\n joint.GetLocalAxisA().get_y(),\n joint.GetLocalAxisA().get_x()\n ) + joint.GetBodyA().GetAngle()\n );\n }\n\n getPrismaticJointReferenceAngle(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return 0;\n }\n\n // Get the joint reference angle\n return gdjs.toDegrees(joint.GetReferenceAngle());\n }\n\n getPrismaticJointTranslation(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return 0;\n }\n\n // Get the joint current translation\n return joint.GetJointTranslation() * this._sharedData.worldScale;\n }\n\n getPrismaticJointSpeed(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return 0;\n }\n\n // Get the joint speed\n return joint.GetJointSpeed() * this._sharedData.worldScale;\n }\n\n isPrismaticJointLimitsEnabled(jointId: integer | string): boolean {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return false;\n }\n\n // Get the joint limits state\n return joint.IsLimitEnabled();\n }\n\n enablePrismaticJointLimits(\n jointId: integer | string,\n enable: boolean\n ): void {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return;\n }\n\n // Set the joint limits state\n joint.EnableLimit(enable);\n }\n\n getPrismaticJointMinTranslation(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return 0;\n }\n\n // Get the joint lower limit\n return joint.GetLowerLimit() * this._sharedData.worldScale;\n }\n\n getPrismaticJointMaxTranslation(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return 0;\n }\n\n // Get the joint upper angle\n return joint.GetUpperLimit() * this._sharedData.worldScale;\n }\n\n setPrismaticJointLimits(\n jointId: integer | string,\n lowerTranslation: float,\n upperTranslation: float\n ): void {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return;\n }\n\n // Lower translation must be lower than upper translation\n if (upperTranslation < lowerTranslation) {\n const temp = lowerTranslation;\n lowerTranslation = upperTranslation;\n upperTranslation = temp;\n }\n\n // The translation range must include zero\n lowerTranslation = lowerTranslation < 0 ? lowerTranslation : 0;\n upperTranslation = upperTranslation > 0 ? upperTranslation : 0;\n\n // Set the joint limits\n joint.SetLimits(\n lowerTranslation * this._sharedData.worldInvScale,\n upperTranslation * this._sharedData.worldInvScale\n );\n }\n\n isPrismaticJointMotorEnabled(jointId: integer | string): boolean {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return false;\n }\n\n // Get the joint motor state\n return joint.IsMotorEnabled();\n }\n\n enablePrismaticJointMotor(\n jointId: integer | string,\n enable: boolean\n ): void {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return;\n }\n\n // Set the joint motor state\n joint.EnableMotor(enable);\n }\n\n getPrismaticJointMotorSpeed(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return 0;\n }\n\n // Get the joint motor speed\n return joint.GetMotorSpeed() * this._sharedData.worldScale;\n }\n\n setPrismaticJointMotorSpeed(jointId: integer | string, speed): void {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return;\n }\n\n // Set the joint motor speed\n joint.SetMotorSpeed(speed * this._sharedData.worldInvScale);\n }\n\n getPrismaticJointMaxMotorForce(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return 0;\n }\n\n // Get the joint max motor force\n return joint.GetMaxMotorForce();\n }\n\n setPrismaticJointMaxMotorForce(jointId: integer | string, maxForce): void {\n // Invalid value\n if (maxForce < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return;\n }\n\n // Set the joint max motor force\n joint.SetMaxMotorForce(maxForce);\n }\n\n getPrismaticJointMotorForce(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return 0;\n }\n\n // Get the joint motor torque\n return joint.GetMotorForce(1 / this._sharedData.timeStep);\n }\n\n // Pulley joint\n addPulleyJoint(\n x1: float,\n y1: float,\n other: gdjs.RuntimeObject | null,\n x2: float,\n y2: float,\n groundX1: float,\n groundY1: float,\n groundX2: float,\n groundY2: float,\n lengthA: float,\n lengthB: float,\n ratio: float,\n collideConnected: boolean,\n variable: gdjs.Variable\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // If there is no second object or it doesn't share the behavior, return\n if (other == null || !other.hasBehavior(this.name)) {\n return;\n }\n\n // Get the second body\n const otherBody = (\n other.getBehavior(this.name) as gdjs.Physics2RuntimeBehavior\n ).getBody();\n\n // If the first and second objects/bodies are the same, return\n if (this._body === otherBody) {\n return;\n }\n\n // Set joint settings\n const jointDef = new Box2D.b2PulleyJointDef();\n jointDef.set_bodyA(body);\n jointDef.set_localAnchorA(\n body.GetLocalPoint(\n this.b2Vec2(\n x1 * this._sharedData.worldInvScale,\n y1 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_bodyB(otherBody);\n jointDef.set_localAnchorB(\n otherBody.GetLocalPoint(\n this.b2Vec2(\n x2 * this._sharedData.worldInvScale,\n y2 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_groundAnchorA(\n this.b2Vec2(\n groundX1 * this._sharedData.worldInvScale,\n groundY1 * this._sharedData.worldInvScale\n )\n );\n jointDef.set_groundAnchorB(\n this.b2Vec2(\n groundX2 * this._sharedData.worldInvScale,\n groundY2 * this._sharedData.worldInvScale\n )\n );\n jointDef.set_lengthA(\n lengthA > 0\n ? lengthA * this._sharedData.worldInvScale\n : this.b2Vec2(\n (groundX1 - x1) * this._sharedData.worldInvScale,\n (groundY1 - y1) * this._sharedData.worldInvScale\n ).Length()\n );\n jointDef.set_lengthB(\n lengthB > 0\n ? lengthB * this._sharedData.worldInvScale\n : this.b2Vec2(\n (groundX2 - x2) * this._sharedData.worldInvScale,\n (groundY2 - y2) * this._sharedData.worldInvScale\n ).Length()\n );\n jointDef.set_ratio(ratio > 0 ? ratio : 1);\n jointDef.set_collideConnected(collideConnected);\n\n // Create the joint and get the id\n const jointId = this._sharedData.addJoint(\n Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2PulleyJoint\n )\n );\n\n // Store the id in the variable\n variable.setNumber(jointId);\n }\n\n getPulleyJointFirstGroundAnchorX(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2PulleyJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_pulleyJoint) {\n return 0;\n }\n\n // Get the joint ground anchor\n return joint.GetGroundAnchorA().get_x() * this._sharedData.worldScale;\n }\n\n getPulleyJointFirstGroundAnchorY(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2PulleyJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_pulleyJoint) {\n return 0;\n }\n\n // Get the joint ground anchor\n return joint.GetGroundAnchorA().get_y() * this._sharedData.worldScale;\n }\n\n getPulleyJointSecondGroundAnchorX(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2PulleyJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_pulleyJoint) {\n return 0;\n }\n\n // Get the joint ground anchor\n return joint.GetGroundAnchorB().get_x() * this._sharedData.worldScale;\n }\n\n getPulleyJointSecondGroundAnchorY(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2PulleyJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_pulleyJoint) {\n return 0;\n }\n\n // Get the joint ground anchor\n return joint.GetGroundAnchorB().get_y() * this._sharedData.worldScale;\n }\n\n getPulleyJointFirstLength(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2PulleyJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_pulleyJoint) {\n return 0;\n }\n\n // Get the joint length\n return joint.GetCurrentLengthA() * this._sharedData.worldScale;\n }\n\n getPulleyJointSecondLength(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2PulleyJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_pulleyJoint) {\n return 0;\n }\n\n // Get the joint length\n return joint.GetCurrentLengthB() * this._sharedData.worldScale;\n }\n\n getPulleyJointRatio(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2PulleyJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_pulleyJoint) {\n return 0;\n }\n\n // Get the joint ratio\n return joint.GetRatio();\n }\n\n // Gear joint\n addGearJoint(jointId1, jointId2, ratio, collideConnected, variable) {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Get the first joint\n const joint1 = this._sharedData.getJoint(jointId1);\n\n // Joint not found or has wrong type\n if (\n joint1 === null ||\n (joint1.GetType() !== Box2D.e_revoluteJoint &&\n joint1.GetType() !== Box2D.e_prismaticJoint)\n ) {\n return;\n }\n\n // Get the second joint\n const joint2 = this._sharedData.getJoint(jointId2);\n if (\n joint2 === null ||\n (joint2.GetType() !== Box2D.e_revoluteJoint &&\n joint2.GetType() !== Box2D.e_prismaticJoint)\n ) {\n return;\n }\n\n // The joints are the same\n if (joint1 === joint2) {\n return;\n }\n\n // Set joint settings\n const jointDef = new Box2D.b2GearJointDef();\n\n // Set gear joint bodies is not necessary at first, as the gear get the bodies from the two child joints\n // But we must pass two different bodies to bypass a test inherited from b2Joint\n jointDef.set_bodyA(this._sharedData.staticBody);\n jointDef.set_bodyB(body);\n jointDef.set_joint1(joint1);\n jointDef.set_joint2(joint2);\n jointDef.set_ratio(ratio);\n jointDef.set_collideConnected(collideConnected);\n\n // Create the joint and get the id\n const jointId = this._sharedData.addJoint(\n Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2GearJoint\n )\n );\n\n // Store the id in the variable\n variable.setNumber(jointId);\n }\n\n getGearJointFirstJoint(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2GearJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_gearJoint) {\n return 0;\n }\n\n // Get the joint first joint\n return this._sharedData.getJointId(joint.GetJoint1());\n }\n\n getGearJointSecondJoint(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2GearJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_gearJoint) {\n return 0;\n }\n\n // Get the joint second joint\n return this._sharedData.getJointId(joint.GetJoint2());\n }\n\n getGearJointRatio(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2GearJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_gearJoint) {\n return 0;\n }\n\n // Get the joint ratio\n return joint.GetRatio();\n }\n\n setGearJointRatio(jointId: integer | string, ratio: float): void {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2GearJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_gearJoint) {\n return;\n }\n\n // Set the joint ratio\n joint.SetRatio(ratio);\n\n // Awake the bodies, the gear joint picks the dynamic bodies as first and second body (second bodies from the child joints)\n joint.GetBodyA().SetAwake(true);\n joint.GetBodyB().SetAwake(true);\n }\n\n // Mouse joint\n addMouseJoint(\n targetX: float,\n targetY: float,\n maxForce: float,\n frequency: float,\n dampingRatio: float,\n variable: gdjs.Variable\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Set joint settings\n const jointDef = new Box2D.b2MouseJointDef();\n jointDef.set_bodyA(this._sharedData.staticBody);\n jointDef.set_bodyB(body);\n jointDef.set_target(\n this.b2Vec2(\n targetX * this._sharedData.worldInvScale,\n targetY * this._sharedData.worldInvScale\n )\n );\n jointDef.set_maxForce(maxForce >= 0 ? maxForce : 0);\n jointDef.set_frequencyHz(frequency > 0 ? frequency : 1);\n jointDef.set_dampingRatio(dampingRatio >= 0 ? dampingRatio : 0);\n\n // Create the joint and get the id\n const jointId = this._sharedData.addJoint(\n Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2MouseJoint\n )\n );\n\n // Store the id in the variable\n variable.setNumber(jointId);\n }\n\n getMouseJointTargetX(jointId: integer | string): float {\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MouseJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) {\n return 0;\n }\n\n // Get the joint target X\n return joint.GetTarget().get_x() * this._sharedData.worldScale;\n }\n\n getMouseJointTargetY(jointId: integer | string): float {\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MouseJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) {\n return 0;\n }\n\n // Get the joint target Y\n return joint.GetTarget().get_y() * this._sharedData.worldScale;\n }\n\n setMouseJointTarget(\n jointId: integer | string,\n targetX: float,\n targetY: float\n ): void {\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MouseJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) {\n return;\n }\n\n // Set the joint target\n joint.SetTarget(\n this.b2Vec2(\n targetX * this._sharedData.worldInvScale,\n targetY * this._sharedData.worldInvScale\n )\n );\n\n // Awake the body\n joint.GetBodyB().SetAwake(true);\n }\n\n getMouseJointMaxForce(jointId: integer | string): float {\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MouseJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) {\n return 0;\n }\n\n // Get the joint max force\n return joint.GetMaxForce();\n }\n\n setMouseJointMaxForce(jointId: integer | string, maxForce: float): void {\n // Invalid value\n if (maxForce < 0) {\n return;\n }\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MouseJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) {\n return;\n }\n\n // Set the joint max force\n joint.SetMaxForce(maxForce);\n }\n\n getMouseJointFrequency(jointId: integer | string): float {\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MouseJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) {\n return 0;\n }\n\n // Get the joint frequency\n return joint.GetFrequency();\n }\n\n setMouseJointFrequency(jointId: integer | string, frequency: float): void {\n // Invalid value\n if (frequency <= 0) {\n return;\n }\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MouseJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) {\n return;\n }\n\n // Set the joint frequency\n joint.SetFrequency(frequency);\n }\n\n getMouseJointDampingRatio(jointId: integer | string): float {\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MouseJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) {\n return 0;\n }\n\n // Get the joint damping ratio\n return joint.GetDampingRatio();\n }\n\n setMouseJointDampingRatio(\n jointId: integer | string,\n dampingRatio: float\n ): void {\n // Invalid value\n if (dampingRatio < 0) {\n return;\n }\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MouseJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) {\n return;\n }\n\n // Set the joint damping ratio\n joint.SetDampingRatio(dampingRatio);\n }\n\n // Wheel joint\n addWheelJoint(\n x1: float,\n y1: float,\n other: gdjs.RuntimeObject | null,\n x2: float,\n y2: float,\n axisAngle: float,\n frequency: float,\n dampingRatio: float,\n enableMotor: boolean,\n motorSpeed: float,\n maxMotorTorque: float,\n collideConnected: boolean,\n variable: gdjs.Variable\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // If there is no second object or it doesn't share the behavior, return\n if (other == null || !other.hasBehavior(this.name)) {\n return;\n }\n\n // Get the second body\n const otherBody = (\n other.getBehavior(this.name) as gdjs.Physics2RuntimeBehavior\n ).getBody();\n\n // If the first and second objects/bodies are the same, return\n if (this._body === otherBody) {\n return;\n }\n\n // Set joint settings\n const jointDef = new Box2D.b2WheelJointDef();\n jointDef.set_bodyA(body);\n jointDef.set_localAnchorA(\n body.GetLocalPoint(\n this.b2Vec2(\n x1 * this._sharedData.worldInvScale,\n y1 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_bodyB(otherBody);\n jointDef.set_localAnchorB(\n otherBody.GetLocalPoint(\n this.b2Vec2(\n x2 * this._sharedData.worldInvScale,\n y2 * this._sharedData.worldInvScale\n )\n )\n );\n axisAngle = gdjs.toRad(axisAngle) - body.GetAngle();\n jointDef.set_localAxisA(\n this.b2Vec2(Math.cos(axisAngle), Math.sin(axisAngle))\n );\n jointDef.set_frequencyHz(frequency > 0 ? frequency : 1);\n jointDef.set_dampingRatio(dampingRatio >= 0 ? dampingRatio : 0);\n jointDef.set_enableMotor(enableMotor);\n jointDef.set_motorSpeed(gdjs.toRad(motorSpeed));\n jointDef.set_maxMotorTorque(maxMotorTorque);\n jointDef.set_collideConnected(collideConnected);\n\n // Create the joint and get the id\n const jointId = this._sharedData.addJoint(\n Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2WheelJoint\n )\n );\n\n // Store the id in the variable\n variable.setNumber(jointId);\n }\n\n getWheelJointAxisAngle(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return 0;\n }\n\n // Get the joint axis angle\n return gdjs.toDegrees(\n Math.atan2(\n joint.GetLocalAxisA().get_y(),\n joint.GetLocalAxisA().get_x()\n ) + joint.GetBodyA().GetAngle()\n );\n }\n\n getWheelJointTranslation(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return 0;\n }\n\n // Get the joint current translation\n return joint.GetJointTranslation() * this._sharedData.worldScale;\n }\n\n getWheelJointSpeed(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return 0;\n }\n\n // Get the joint speed\n return gdjs.toDegrees(joint.GetJointSpeed());\n }\n\n isWheelJointMotorEnabled(jointId: integer | string): boolean {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return false;\n }\n\n // Get the joint motor state\n return joint.IsMotorEnabled();\n }\n\n enableWheelJointMotor(jointId: integer | string, enable): void {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return;\n }\n\n // Set the joint motor state\n joint.EnableMotor(enable);\n }\n\n getWheelJointMotorSpeed(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return 0;\n }\n\n // Get the joint motor speed\n return gdjs.toDegrees(joint.GetMotorSpeed());\n }\n\n setWheelJointMotorSpeed(jointId: integer | string, speed): void {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return;\n }\n\n // Set the joint motor speed\n joint.SetMotorSpeed(gdjs.toRad(speed));\n }\n\n getWheelJointMaxMotorTorque(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return 0;\n }\n\n // Get the joint max motor torque\n return joint.GetMaxMotorTorque();\n }\n\n setWheelJointMaxMotorTorque(\n jointId: integer | string,\n maxTorque: float\n ): void {\n // Invalid value\n if (maxTorque < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return;\n }\n\n // Set the joint max motor torque\n joint.SetMaxMotorTorque(maxTorque);\n }\n\n getWheelJointMotorTorque(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return 0;\n }\n\n // Get the joint motor torque\n return joint.GetMotorTorque(1 / this._sharedData.timeStep);\n }\n\n getWheelJointFrequency(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return 0;\n }\n\n // Get the joint frequency\n return joint.GetSpringFrequencyHz();\n }\n\n setWheelJointFrequency(jointId: integer | string, frequency): void {\n // Invalid value\n if (frequency < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return;\n }\n\n // Set the joint frequency\n joint.SetSpringFrequencyHz(frequency);\n }\n\n getWheelJointDampingRatio(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return 0;\n }\n\n // Get the joint damping ratio\n return joint.GetSpringDampingRatio();\n }\n\n setWheelJointDampingRatio(jointId: integer | string, dampingRatio): void {\n // Invalid value\n if (dampingRatio < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return;\n }\n\n // Set the joint damping ratio\n joint.SetSpringDampingRatio(dampingRatio);\n }\n\n // Weld joint\n addWeldJoint(\n x1: float,\n y1: float,\n other: gdjs.RuntimeObject | null,\n x2: float,\n y2: float,\n referenceAngle: float,\n frequency: float,\n dampingRatio: float,\n collideConnected: boolean,\n variable: gdjs.Variable\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n\n // If there is no second object or it doesn't share the behavior, return\n if (other == null || !other.hasBehavior(this.name)) {\n return;\n }\n\n // Get the second body\n const otherBody = (\n other.getBehavior(this.name) as gdjs.Physics2RuntimeBehavior\n ).getBody();\n\n // If the first and second objects/bodies are the same, return\n if (this._body === otherBody) {\n return;\n }\n const body = this._body!;\n\n // Set joint settings\n const jointDef = new Box2D.b2WeldJointDef();\n jointDef.set_bodyA(body);\n jointDef.set_localAnchorA(\n body.GetLocalPoint(\n this.b2Vec2(\n x1 * this._sharedData.worldInvScale,\n y1 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_bodyB(otherBody);\n jointDef.set_localAnchorB(\n otherBody.GetLocalPoint(\n this.b2Vec2(\n x2 * this._sharedData.worldInvScale,\n y2 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_referenceAngle(gdjs.toRad(referenceAngle));\n jointDef.set_frequencyHz(frequency > 0 ? frequency : 1);\n jointDef.set_dampingRatio(dampingRatio >= 0 ? dampingRatio : 0);\n jointDef.set_collideConnected(collideConnected);\n\n // Create the joint\n const joint = Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2WeldJoint\n );\n\n // @ts-ignore b2WeldJoint.GetReferenceAngle() is not binded, store it manually\n joint.referenceAngle = jointDef.get_referenceAngle();\n\n // Store the id in the variable\n variable.setNumber(this._sharedData.addJoint(joint));\n }\n\n getWeldJointReferenceAngle(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WeldJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_weldJoint) {\n return 0;\n }\n\n // @ts-ignore b2WeldJoint.GetReferenceAngle() is not binded\n return gdjs.toDegrees(joint.referenceAngle);\n // return gdjs.toDegrees(joint.GetReferenceAngle());\n }\n\n getWeldJointFrequency(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WeldJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_weldJoint) {\n return 0;\n }\n\n // Get the joint frequency\n return joint.GetFrequency();\n }\n\n setWeldJointFrequency(jointId: integer | string, frequency: float): void {\n // Invalid value\n if (frequency < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WeldJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_weldJoint) {\n return;\n }\n\n // Set the joint frequency\n joint.SetFrequency(frequency);\n }\n\n getWeldJointDampingRatio(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WeldJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_weldJoint) {\n return 0;\n }\n\n // Get the joint damping ratio\n return joint.GetDampingRatio();\n }\n\n setWeldJointDampingRatio(\n jointId: integer | string,\n dampingRatio: float\n ): void {\n // Invalid value\n if (dampingRatio < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WeldJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_weldJoint) {\n return;\n }\n\n // Set the joint damping ratio\n joint.SetDampingRatio(dampingRatio);\n }\n\n // Rope joint\n addRopeJoint(\n x1: float,\n y1: float,\n other: gdjs.RuntimeObject | null,\n x2: float,\n y2: float,\n maxLength: float,\n collideConnected: boolean,\n variable: gdjs.Variable\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // If there is no second object or it doesn't share the behavior, return\n if (other == null || !other.hasBehavior(this.name)) {\n return;\n }\n\n // Get the second body\n const otherBody = (\n other.getBehavior(this.name) as gdjs.Physics2RuntimeBehavior\n ).getBody();\n\n // If the first and second objects/bodies are the same, return\n if (this._body === otherBody) {\n return;\n }\n\n // Set joint settings\n const jointDef = new Box2D.b2RopeJointDef();\n jointDef.set_bodyA(body);\n jointDef.set_localAnchorA(\n body.GetLocalPoint(\n this.b2Vec2(\n x1 * this._sharedData.worldInvScale,\n y1 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_bodyB(otherBody);\n jointDef.set_localAnchorB(\n otherBody.GetLocalPoint(\n this.b2Vec2(\n x2 * this._sharedData.worldInvScale,\n y2 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_maxLength(\n maxLength > 0\n ? maxLength * this._sharedData.worldInvScale\n : this.b2Vec2(\n (x2 - x1) * this._sharedData.worldInvScale,\n (y2 - y1) * this._sharedData.worldInvScale\n ).Length()\n );\n jointDef.set_collideConnected(collideConnected);\n\n // Create the joint and get the id\n const jointId = this._sharedData.addJoint(\n Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2RopeJoint\n )\n );\n\n // Store the id in the variable\n variable.setNumber(jointId);\n }\n\n getRopeJointMaxLength(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RopeJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_ropeJoint) {\n return 0;\n }\n\n // Get the joint maximum length\n return joint.GetMaxLength() * this._sharedData.worldScale;\n }\n\n setRopeJointMaxLength(jointId: integer | string, maxLength: float): void {\n // Invalid value\n if (maxLength < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RopeJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_ropeJoint) {\n return;\n }\n\n // Set the joint maximum length\n joint.SetMaxLength(maxLength * this._sharedData.worldInvScale);\n\n // Awake the bodies\n joint.GetBodyA().SetAwake(true);\n joint.GetBodyB().SetAwake(true);\n }\n\n // Friction joint\n addFrictionJoint(\n x1: float,\n y1: float,\n other: gdjs.RuntimeObject | null,\n x2: float,\n y2: float,\n maxForce: float,\n maxTorque: float,\n collideConnected: boolean,\n variable: gdjs.Variable\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n\n // If there is no second object or it doesn't share the behavior, return\n if (other == null || !other.hasBehavior(this.name)) {\n return;\n }\n\n // Get the second body\n const otherBody = (\n other.getBehavior(this.name) as gdjs.Physics2RuntimeBehavior\n ).getBody();\n\n // If the first and second objects/bodies are the same, return\n if (this._body === otherBody) {\n return;\n }\n const body = this._body!;\n\n // Set joint settings\n const jointDef = new Box2D.b2FrictionJointDef();\n jointDef.set_bodyA(body);\n jointDef.set_localAnchorA(\n body.GetLocalPoint(\n this.b2Vec2(\n x1 * this._sharedData.worldInvScale,\n y1 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_bodyB(otherBody);\n jointDef.set_localAnchorB(\n otherBody.GetLocalPoint(\n this.b2Vec2(\n x2 * this._sharedData.worldInvScale,\n y2 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_maxForce(maxForce >= 0 ? maxForce : 0);\n jointDef.set_maxTorque(maxTorque >= 0 ? maxTorque : 0);\n jointDef.set_collideConnected(collideConnected);\n\n // Create the joint and get the id\n const jointId = this._sharedData.addJoint(\n Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2FrictionJoint\n )\n );\n\n // Store the id in the variable\n variable.setNumber(jointId);\n }\n\n getFrictionJointMaxForce(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2FrictionJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_frictionJoint) {\n return 0;\n }\n\n // Get the joint maximum force\n return joint.GetMaxForce();\n }\n\n setFrictionJointMaxForce(jointId: integer | string, maxForce: float): void {\n // Invalid value\n if (maxForce < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2FrictionJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_frictionJoint) {\n return;\n }\n\n // Set the joint maximum force\n joint.SetMaxForce(maxForce);\n }\n\n getFrictionJointMaxTorque(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2FrictionJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_frictionJoint) {\n return 0;\n }\n\n // Get the joint maximum torque\n return joint.GetMaxTorque();\n }\n\n setFrictionJointMaxTorque(\n jointId: integer | string,\n maxTorque: float\n ): void {\n // Invalid value\n if (maxTorque < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2FrictionJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_frictionJoint) {\n return;\n }\n\n // Set the joint maximum torque\n joint.SetMaxTorque(maxTorque);\n }\n\n // Motor joint\n addMotorJoint(\n other: gdjs.RuntimeObject | null,\n offsetX: float,\n offsetY: float,\n offsetAngle: float,\n maxForce: float,\n maxTorque: float,\n correctionFactor: float,\n collideConnected: boolean,\n variable: gdjs.Variable\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // If there is no second object or it doesn't share the behavior, return\n if (other == null || !other.hasBehavior(this.name)) {\n return;\n }\n\n // Get the second body\n const otherBody = (\n other.getBehavior(this.name) as gdjs.Physics2RuntimeBehavior\n ).getBody();\n\n // If the first and second objects/bodies are the same, return\n if (this._body === otherBody) {\n return;\n }\n\n // Set joint settings\n const jointDef = new Box2D.b2MotorJointDef();\n jointDef.set_bodyA(body);\n jointDef.set_bodyB(otherBody);\n jointDef.set_linearOffset(\n this.b2Vec2(\n offsetX * this._sharedData.worldInvScale,\n offsetY * this._sharedData.worldInvScale\n )\n );\n jointDef.set_angularOffset(gdjs.toRad(offsetAngle));\n jointDef.set_maxForce(maxForce >= 0 ? maxForce : 0);\n jointDef.set_maxTorque(maxTorque >= 0 ? maxTorque : 0);\n jointDef.set_correctionFactor(\n correctionFactor < 0 ? 0 : correctionFactor > 1 ? 1 : correctionFactor\n );\n jointDef.set_collideConnected(collideConnected);\n\n // Create the joint and get the id\n const jointId = this._sharedData.addJoint(\n Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2MotorJoint\n )\n );\n\n // Store the id in the variable\n variable.setNumber(jointId);\n }\n\n getMotorJointOffsetX(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MotorJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_motorJoint) {\n return 0;\n }\n\n // Get the joint offset\n return joint.GetLinearOffset().get_x() * this._sharedData.worldScale;\n }\n\n getMotorJointOffsetY(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MotorJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_motorJoint) {\n return 0;\n }\n\n // Get the joint offset\n return joint.GetLinearOffset().get_y() * this._sharedData.worldScale;\n }\n\n setMotorJointOffset(\n jointId: integer | string,\n offsetX: float,\n offsetY: float\n ): void {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MotorJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_motorJoint) {\n return;\n }\n\n // Set the joint offset\n joint.SetLinearOffset(\n this.b2Vec2(\n offsetX * this._sharedData.worldInvScale,\n offsetY * this._sharedData.worldInvScale\n )\n );\n }\n\n getMotorJointAngularOffset(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MotorJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_motorJoint) {\n return 0;\n }\n\n // Get the joint angular offset\n return gdjs.toDegrees(joint.GetAngularOffset());\n }\n\n setMotorJointAngularOffset(\n jointId: integer | string,\n offsetAngle: float\n ): void {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MotorJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_motorJoint) {\n return;\n }\n\n // Set the joint angular offset\n joint.SetAngularOffset(gdjs.toRad(offsetAngle));\n }\n\n getMotorJointMaxForce(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MotorJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_motorJoint) {\n return 0;\n }\n\n // Get the joint maximum force\n return joint.GetMaxForce();\n }\n\n setMotorJointMaxForce(jointId: integer | string, maxForce: float): void {\n // Invalid value\n if (maxForce < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MotorJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_motorJoint) {\n return;\n }\n\n // Set the joint maximum force\n joint.SetMaxForce(maxForce);\n }\n\n getMotorJointMaxTorque(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MotorJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_motorJoint) {\n return 0;\n }\n\n // Get the joint maximum torque\n return joint.GetMaxTorque();\n }\n\n setMotorJointMaxTorque(jointId: integer | string, maxTorque: float): void {\n // Invalid value\n if (maxTorque < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MotorJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_motorJoint) {\n return;\n }\n\n // Set the joint maximum torque\n joint.SetMaxTorque(maxTorque);\n\n // Awake the bodies\n joint.GetBodyA().SetAwake(true);\n joint.GetBodyB().SetAwake(true);\n }\n\n getMotorJointCorrectionFactor(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MotorJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_motorJoint) {\n return 0;\n }\n\n // Get the joint correction factor\n return joint.GetCorrectionFactor();\n }\n\n setMotorJointCorrectionFactor(\n jointId: integer | string,\n correctionFactor: float\n ): void {\n // Invalid value\n if (correctionFactor < 0 || correctionFactor > 1) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MotorJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_motorJoint) {\n return;\n }\n\n // Set the joint correction factor\n joint.SetCorrectionFactor(correctionFactor);\n\n // Awake the bodies\n joint.GetBodyA().SetAwake(true);\n joint.GetBodyB().SetAwake(true);\n }\n\n onContactBegin(otherBehavior: Physics2RuntimeBehavior): void {\n this.currentContacts.push(otherBehavior);\n\n // There might be contacts that end during the frame and\n // start again right away. It is considered a glitch\n // and should not be detected.\n let i = this.contactsEndedThisFrame.indexOf(otherBehavior);\n if (i !== -1) {\n this.contactsEndedThisFrame.splice(i, 1);\n } else {\n this.contactsStartedThisFrame.push(otherBehavior);\n }\n }\n\n onContactEnd(otherBehavior: Physics2RuntimeBehavior): void {\n this.contactsEndedThisFrame.push(otherBehavior);\n\n const index = this.currentContacts.indexOf(otherBehavior);\n if (index !== -1) {\n this.currentContacts.splice(index, 1);\n }\n }\n\n /**\n * @deprecated Prefer using `Physics2RuntimeBehavior.areObjectsColliding`.\n */\n static collisionTest = Physics2RuntimeBehavior.areObjectsColliding;\n\n static areObjectsColliding(\n object1: gdjs.RuntimeObject,\n object2: gdjs.RuntimeObject,\n behaviorName: string\n ): boolean {\n // Test if the second object is in the list of contacts of the first one\n const behavior1 = object1.getBehavior(\n behaviorName\n ) as Physics2RuntimeBehavior | null;\n if (!behavior1) return false;\n\n if (\n behavior1.currentContacts.some((behavior) => behavior.owner === object2)\n ) {\n return true;\n }\n // If a contact has started at this frame and ended right away, it\n // won't appear in current contacts but the condition should return\n // true anyway.\n if (\n behavior1.contactsStartedThisFrame.some(\n (behavior) => behavior.owner === object2\n )\n ) {\n return true;\n }\n\n // No contact found\n return false;\n }\n\n static hasCollisionStartedBetween(\n object1: gdjs.RuntimeObject,\n object2: gdjs.RuntimeObject,\n behaviorName: string\n ): boolean {\n // Test if the second object is in the list of contacts of the first one\n const behavior1 = object1.getBehavior(\n behaviorName\n ) as Physics2RuntimeBehavior | null;\n if (!behavior1) return false;\n\n return behavior1.contactsStartedThisFrame.some(\n (behavior) => behavior.owner === object2\n );\n }\n\n static hasCollisionStoppedBetween(\n object1: gdjs.RuntimeObject,\n object2: gdjs.RuntimeObject,\n behaviorName: string\n ): boolean {\n // Test if the second object is in the list of contacts of the first one\n const behavior1 = object1.getBehavior(\n behaviorName\n ) as Physics2RuntimeBehavior | null;\n if (!behavior1) return false;\n\n return behavior1.contactsEndedThisFrame.some(\n (behavior) => behavior.owner === object2\n );\n }\n }\n gdjs.registerBehavior(\n 'Physics2::Physics2Behavior',\n gdjs.Physics2RuntimeBehavior\n );\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["namespace Box2D {\n export interface b2Body {\n gdjsAssociatedBehavior: gdjs.Physics2RuntimeBehavior | null;\n }\n}\nnamespace gdjs {\n export interface RuntimeScene {\n physics2SharedData: gdjs.Physics2SharedData | null;\n }\n interface Physics2NetworkSyncDataType {\n tpx: number | undefined;\n tpy: number | undefined;\n tqa: number | undefined;\n lvx: number | undefined;\n lvy: number | undefined;\n av: number | undefined;\n aw: boolean | undefined;\n layers: number;\n masks: number;\n }\n\n export interface Physics2NetworkSyncData extends BehaviorNetworkSyncData {\n props: Physics2NetworkSyncDataType;\n }\n export class Physics2SharedData {\n gravityX: float;\n gravityY: float;\n worldScale: float;\n worldInvScale: float;\n /** @deprecated Use `worldScale` instead */\n scaleX: float;\n /** @deprecated Use `worldScale` instead */\n scaleY: float;\n /** @deprecated Use `worldInvScale` instead */\n invScaleX: float;\n /** @deprecated Use `worldInvScale` instead */\n invScaleY: float;\n\n timeStep: float;\n frameTime: float = 0;\n stepped: boolean = false;\n timeScale: float = 1;\n\n world: Box2D.b2World;\n staticBody: Box2D.b2Body;\n /** Contact listener to keep track of current collisions */\n contactListener: Box2D.JSContactListener;\n _nextJointId: number = 1;\n /** Start with 1 so the user is safe from default variables value (0) */\n joints: { [key: string]: Box2D.b2Joint } = {};\n /** Avoid creating new vectors all the time */\n _tempb2Vec2 = new Box2D.b2Vec2(0, 0);\n /** Sometimes two vectors are needed on the same function call */\n _tempb2Vec2Sec = new Box2D.b2Vec2(0, 0);\n\n /**\n * List of physics behavior in the runtimeScene. It should be updated\n * when a new physics object is created (constructor), on destruction (onDestroy),\n * on behavior activation (onActivate) and on behavior deactivation (onDeActivate).\n */\n _registeredBehaviors: Set<Physics2RuntimeBehavior>;\n\n constructor(instanceContainer: gdjs.RuntimeInstanceContainer, sharedData) {\n this._registeredBehaviors = new Set();\n this.gravityX = sharedData.gravityX;\n this.gravityY = sharedData.gravityY;\n this.scaleX = sharedData.scaleX || 100;\n this.scaleY = sharedData.scaleY || 100;\n this.invScaleX = 1 / this.scaleX;\n this.invScaleY = 1 / this.scaleY;\n this.worldScale =\n sharedData.worldScale || Math.sqrt(this.scaleX * this.scaleY);\n this.worldInvScale = 1 / this.worldScale;\n this.timeStep = 1 / 60;\n this.world = new Box2D.b2World(this.b2Vec2(this.gravityX, this.gravityY));\n this.world.SetAutoClearForces(false);\n this.staticBody = this.world.CreateBody(new Box2D.b2BodyDef());\n this.contactListener = new Box2D.JSContactListener();\n this.contactListener.BeginContact = function (contactPtr) {\n // Get the contact\n const contact = Box2D.wrapPointer(\n contactPtr as number,\n Box2D.b2Contact\n );\n\n // There is no body, return\n if (\n contact.GetFixtureA().GetBody() === null ||\n contact.GetFixtureB().GetBody() === null\n ) {\n return;\n }\n\n // Get associated behaviors\n const behaviorA = contact\n .GetFixtureA()\n .GetBody().gdjsAssociatedBehavior;\n const behaviorB = contact\n .GetFixtureB()\n .GetBody().gdjsAssociatedBehavior;\n\n if (!behaviorA || !behaviorB) {\n return;\n }\n\n behaviorA.onContactBegin(behaviorB);\n behaviorB.onContactBegin(behaviorA);\n };\n this.contactListener.EndContact = function (contactPtr) {\n // Get the contact\n const contact = Box2D.wrapPointer(\n contactPtr as number,\n Box2D.b2Contact\n );\n\n // There is no body, return\n if (\n contact.GetFixtureA().GetBody() === null ||\n contact.GetFixtureB().GetBody() === null\n ) {\n return;\n }\n\n // Get associated behaviors\n const behaviorA = contact.GetFixtureA().GetBody()\n .gdjsAssociatedBehavior as Physics2RuntimeBehavior | null;\n const behaviorB = contact.GetFixtureB().GetBody()\n .gdjsAssociatedBehavior as Physics2RuntimeBehavior | null;\n\n if (!behaviorA || !behaviorB) {\n return;\n }\n\n behaviorA.onContactEnd(behaviorB);\n behaviorB.onContactEnd(behaviorA);\n };\n this.contactListener.PreSolve = function () {};\n this.contactListener.PostSolve = function () {};\n this.world.SetContactListener(this.contactListener);\n }\n\n b2Vec2(x: float, y: float): Box2D.b2Vec2 {\n const tempb2Vec2 = this._tempb2Vec2;\n tempb2Vec2.set_x(x);\n tempb2Vec2.set_y(y);\n return tempb2Vec2;\n }\n\n // (string)jointId -> (b2Joint)b2Joint\n static getSharedData(\n runtimeScene: gdjs.RuntimeScene,\n behaviorName: string\n ): gdjs.Physics2SharedData {\n // Create one if needed\n if (!runtimeScene.physics2SharedData) {\n const initialData =\n runtimeScene.getInitialSharedDataForBehavior(behaviorName);\n runtimeScene.physics2SharedData = new gdjs.Physics2SharedData(\n runtimeScene,\n initialData\n );\n }\n return runtimeScene.physics2SharedData;\n }\n\n /**\n * Add a physics object to the list of existing object.\n */\n addToBehaviorsList(physicsBehavior: gdjs.Physics2RuntimeBehavior): void {\n this._registeredBehaviors.add(physicsBehavior);\n }\n\n /**\n * Remove a physics object to the list of existing object.\n */\n removeFromBehaviorsList(\n physicsBehavior: gdjs.Physics2RuntimeBehavior\n ): void {\n this._registeredBehaviors.delete(physicsBehavior);\n }\n\n step(deltaTime: float): void {\n // Reset started and ended contacts array for all physics instances.\n for (const physicsBehavior of this._registeredBehaviors) {\n physicsBehavior.contactsStartedThisFrame.length = 0;\n physicsBehavior.contactsEndedThisFrame.length = 0;\n }\n for (const physicsBehavior of this._registeredBehaviors) {\n physicsBehavior.updateBodyFromObject();\n }\n\n this.frameTime += deltaTime;\n // `frameTime` can take negative values.\n // It's better to be a bit early rather than skipping a frame and being\n // a lot more late.\n let numberOfSteps = Math.max(\n 0,\n Math.round(this.frameTime / this.timeStep)\n );\n this.frameTime -= numberOfSteps * this.timeStep;\n if (numberOfSteps > 5) {\n numberOfSteps = 5;\n }\n for (let i = 0; i < numberOfSteps; i++) {\n this.world.Step(this.timeStep * this.timeScale, 8, 10);\n }\n this.world.ClearForces();\n this.stepped = true;\n\n // It's important that updateBodyFromObject and updateObjectFromBody are\n // called at the same time because other behavior may move the object in\n // their doStepPreEvents.\n for (const physicsBehavior of this._registeredBehaviors) {\n physicsBehavior.updateObjectFromBody();\n }\n }\n\n clearBodyJoints(body: Box2D.b2Body): void {\n // Iterate through all the joints\n for (const jointId in this.joints) {\n if (this.joints.hasOwnProperty(jointId)) {\n // If the joint is attached to the body, delete it\n if (\n this.joints[jointId].GetBodyA() === body ||\n this.joints[jointId].GetBodyB() === body\n ) {\n this.removeJoint(jointId);\n }\n }\n }\n }\n\n addJoint(joint: Box2D.b2Joint): integer {\n // Add the joint to the list\n this.joints[this._nextJointId.toString(10)] = joint;\n\n // Return the current joint id and then increase it\n return this._nextJointId++;\n }\n\n getJoint(jointId: integer | string): Box2D.b2Joint | null {\n // Cast to string\n jointId = jointId.toString(10);\n\n // Get the joint\n if (this.joints.hasOwnProperty(jointId)) {\n return this.joints[jointId];\n }\n\n // Joint not found, return null\n return null;\n }\n\n getJointId(joint: Box2D.b2Joint): integer {\n // Search the joint in the list and return the ID\n for (const jointId in this.joints) {\n if (this.joints.hasOwnProperty(jointId)) {\n if (this.joints[jointId] === joint) {\n return parseInt(jointId, 10);\n }\n }\n }\n\n // Joint not found, return 0\n return 0;\n }\n\n removeJoint(jointId: integer | string) {\n // Cast to string\n jointId = jointId.toString(10);\n\n // Delete the joint\n if (this.joints.hasOwnProperty(jointId)) {\n const joint = this.joints[jointId];\n\n // If we delete a joint attached to a gear joint, the gear will crash, so we must delete the gear joint first\n // Search in our joints list gear joints attached to this one we want to remove\n // The joint can be attached to a gear joint if it's revolute or prismatic only\n if (\n joint.GetType() === Box2D.e_revoluteJoint ||\n joint.GetType() === Box2D.e_prismaticJoint\n ) {\n for (const jId in this.joints) {\n if (this.joints.hasOwnProperty(jId)) {\n // Must check pointers because gears store non-casted joints (b2Joint)\n if (\n this.joints[jId].GetType() === Box2D.e_gearJoint &&\n (Box2D.getPointer(\n (this.joints[jId] as Box2D.b2GearJoint).GetJoint1()\n ) === Box2D.getPointer(joint) ||\n Box2D.getPointer(\n (this.joints[jId] as Box2D.b2GearJoint).GetJoint2()\n ) === Box2D.getPointer(joint))\n ) {\n // We could pass it a string, but lets do it right\n this.removeJoint(parseInt(jId, 10));\n }\n }\n }\n }\n\n // Remove the joint\n this.world.DestroyJoint(joint);\n delete this.joints[jointId];\n }\n }\n }\n gdjs.registerRuntimeSceneUnloadedCallback(function (runtimeScene) {\n const physics2SharedData = runtimeScene.physics2SharedData;\n if (physics2SharedData && physics2SharedData.world) {\n Box2D.destroy(physics2SharedData.world);\n Box2D.destroy(physics2SharedData._tempb2Vec2);\n Box2D.destroy(physics2SharedData._tempb2Vec2Sec);\n }\n });\n\n export class Physics2RuntimeBehavior extends gdjs.RuntimeBehavior {\n bodyType: string;\n bullet: boolean;\n fixedRotation: boolean;\n canSleep: boolean;\n shape: string;\n shapeDimensionA: any;\n shapeDimensionB: any;\n shapeOffsetX: float;\n shapeOffsetY: float;\n polygonOrigin: string;\n polygon: gdjs.Polygon | null;\n density: float;\n friction: float;\n restitution: float;\n linearDamping: float;\n angularDamping: float;\n gravityScale: float;\n layers: integer;\n masks: integer;\n shapeScale: number = 1;\n\n /**\n * Array containing the beginning of contacts reported by onContactBegin. Each contact\n * should be unique to avoid recording glitches where the object loses and regain\n * contact between two frames. The array is updated each time the method\n * onContactBegin is called by the listener, which is only called when stepping\n * the world i.e. in the first preEvent called by a physics behavior. This array is\n * cleared just before stepping the world.\n */\n contactsStartedThisFrame: Array<Physics2RuntimeBehavior>;\n\n /**\n * Array containing the end of contacts reported by onContactEnd. The array is updated\n * each time the method onContactEnd is called by the listener, which can be called at\n * any time. This array is cleared just before stepping the world.\n */\n contactsEndedThisFrame: Array<Physics2RuntimeBehavior>;\n\n /**\n * Array containing the exact current contacts with the objects. It is updated\n * each time the methods onContactBegin and onContactEnd are called by the contact\n * listener.\n */\n currentContacts: Array<Physics2RuntimeBehavior>;\n destroyedDuringFrameLogic: boolean;\n _body: Box2D.b2Body | null = null;\n\n /**\n * sharedData is a reference to the shared data of the scene, that registers\n * every physics behavior that is created so that collisions can be cleared\n * before stepping the world.\n */\n _sharedData: Physics2SharedData;\n\n _objectOldX: number = 0;\n _objectOldY: number = 0;\n _objectOldAngle: float = 0;\n _objectOldWidth: float = 0;\n _objectOldHeight: float = 0;\n _verticesBuffer: integer = 0;\n\n constructor(\n instanceContainer: gdjs.RuntimeInstanceContainer,\n behaviorData,\n owner: gdjs.RuntimeObject\n ) {\n super(instanceContainer, behaviorData, owner);\n this.bodyType = behaviorData.bodyType;\n this.bullet = behaviorData.bullet;\n this.fixedRotation = behaviorData.fixedRotation;\n this.canSleep = behaviorData.canSleep;\n this.shape = behaviorData.shape;\n this.shapeDimensionA = behaviorData.shapeDimensionA;\n this.shapeDimensionB = behaviorData.shapeDimensionB;\n this.shapeOffsetX = behaviorData.shapeOffsetX;\n this.shapeOffsetY = behaviorData.shapeOffsetY;\n this.polygonOrigin = behaviorData.polygonOrigin;\n this.polygon =\n this.shape === 'Polygon'\n ? Physics2RuntimeBehavior.getPolygon(behaviorData.vertices)\n : null;\n this.density = behaviorData.density;\n this.friction = behaviorData.friction;\n this.restitution = behaviorData.restitution;\n this.linearDamping = Math.max(0, behaviorData.linearDamping);\n this.angularDamping = Math.max(0, behaviorData.angularDamping);\n this.gravityScale = behaviorData.gravityScale;\n this.layers = behaviorData.layers;\n this.masks = behaviorData.masks;\n this.contactsStartedThisFrame = [];\n this.contactsEndedThisFrame = [];\n this.currentContacts = [];\n this.currentContacts.length = 0;\n this.destroyedDuringFrameLogic = false;\n this._sharedData = Physics2SharedData.getSharedData(\n instanceContainer.getScene(),\n behaviorData.name\n );\n this._sharedData.addToBehaviorsList(this);\n }\n\n // Stores a Box2D pointer of created vertices\n b2Vec2(x: float, y: float): Box2D.b2Vec2 {\n const tempb2Vec2 = this._sharedData._tempb2Vec2;\n tempb2Vec2.set_x(x);\n tempb2Vec2.set_y(y);\n return tempb2Vec2;\n }\n\n b2Vec2Sec(x: float, y: float): Box2D.b2Vec2 {\n const tempb2Vec2Sec = this._sharedData._tempb2Vec2Sec;\n tempb2Vec2Sec.set_x(x);\n tempb2Vec2Sec.set_y(y);\n return tempb2Vec2Sec;\n }\n\n updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {\n if (oldBehaviorData.bullet !== newBehaviorData.bullet) {\n this.setBullet(newBehaviorData.bullet);\n }\n if (oldBehaviorData.fixedRotation !== newBehaviorData.fixedRotation) {\n this.setFixedRotation(newBehaviorData.fixedRotation);\n }\n if (oldBehaviorData.canSleep !== newBehaviorData.canSleep) {\n this.setSleepingAllowed(newBehaviorData.canSleep);\n }\n if (oldBehaviorData.shapeDimensionA !== newBehaviorData.shapeDimensionA) {\n this.shapeDimensionA = newBehaviorData.shapeDimensionA;\n this.recreateShape();\n }\n if (oldBehaviorData.shapeDimensionB !== newBehaviorData.shapeDimensionB) {\n this.shapeDimensionB = newBehaviorData.shapeDimensionB;\n this.recreateShape();\n }\n if (oldBehaviorData.shapeOffsetX !== newBehaviorData.shapeOffsetX) {\n this.shapeOffsetX = newBehaviorData.shapeOffsetX;\n this.recreateShape();\n }\n if (oldBehaviorData.shapeOffsetY !== newBehaviorData.shapeOffsetY) {\n this.shapeOffsetY = newBehaviorData.shapeOffsetY;\n this.recreateShape();\n }\n if (oldBehaviorData.polygonOrigin !== newBehaviorData.polygonOrigin) {\n this.polygonOrigin = newBehaviorData.polygonOrigin;\n this.recreateShape();\n }\n if (oldBehaviorData.density !== newBehaviorData.density) {\n this.setDensity(newBehaviorData.density);\n }\n if (oldBehaviorData.friction !== newBehaviorData.friction) {\n this.setFriction(newBehaviorData.friction);\n }\n if (oldBehaviorData.restitution !== newBehaviorData.restitution) {\n this.setRestitution(newBehaviorData.restitution);\n }\n if (oldBehaviorData.linearDamping !== newBehaviorData.linearDamping) {\n this.setLinearDamping(newBehaviorData.linearDamping);\n }\n if (oldBehaviorData.angularDamping !== newBehaviorData.angularDamping) {\n this.setAngularDamping(newBehaviorData.angularDamping);\n }\n if (oldBehaviorData.gravityScale !== newBehaviorData.gravityScale) {\n this.setGravityScale(newBehaviorData.gravityScale);\n }\n\n // TODO: make these properties updatable.\n if (oldBehaviorData.layers !== newBehaviorData.layers) {\n return false;\n }\n if (oldBehaviorData.masks !== newBehaviorData.masks) {\n return false;\n }\n if (oldBehaviorData.vertices !== newBehaviorData.vertices) {\n return false;\n }\n if (oldBehaviorData.bodyType !== newBehaviorData.bodyType) {\n return false;\n }\n if (oldBehaviorData.shape !== newBehaviorData.shape) {\n return false;\n }\n return true;\n }\n\n getNetworkSyncData(\n options: GetNetworkSyncDataOptions\n ): Physics2NetworkSyncData {\n const bodyProps = this._body\n ? {\n tpx: this._body.GetTransform().get_p().get_x(),\n tpy: this._body.GetTransform().get_p().get_y(),\n tqa: this._body.GetTransform().get_q().GetAngle(),\n lvx: this._body.GetLinearVelocity().get_x(),\n lvy: this._body.GetLinearVelocity().get_y(),\n av: this._body.GetAngularVelocity(),\n aw: this._body.IsAwake(),\n }\n : {\n tpx: undefined,\n tpy: undefined,\n tqa: undefined,\n lvx: undefined,\n lvy: undefined,\n av: undefined,\n aw: undefined,\n };\n return {\n ...super.getNetworkSyncData(options),\n props: {\n ...bodyProps,\n layers: this.layers,\n masks: this.masks,\n },\n };\n }\n\n updateFromNetworkSyncData(\n networkSyncData: Physics2NetworkSyncData,\n options: UpdateFromNetworkSyncDataOptions\n ) {\n super.updateFromNetworkSyncData(networkSyncData, options);\n\n const behaviorSpecificProps = networkSyncData.props;\n\n if (behaviorSpecificProps.layers !== undefined) {\n this.layers = behaviorSpecificProps.layers;\n }\n\n if (behaviorSpecificProps.masks !== undefined) {\n this.masks = behaviorSpecificProps.masks;\n }\n\n this.updateBodyFromObject();\n\n if (!this._body) return;\n\n if (\n behaviorSpecificProps.tpx !== undefined &&\n behaviorSpecificProps.tpy !== undefined &&\n behaviorSpecificProps.tqa !== undefined\n ) {\n this._body.SetTransform(\n this.b2Vec2(behaviorSpecificProps.tpx, behaviorSpecificProps.tpy),\n behaviorSpecificProps.tqa\n );\n }\n\n if (\n behaviorSpecificProps.lvx !== undefined &&\n behaviorSpecificProps.lvy !== undefined\n ) {\n this._body.SetLinearVelocity(\n this.b2Vec2(behaviorSpecificProps.lvx, behaviorSpecificProps.lvy)\n );\n }\n\n if (behaviorSpecificProps.av !== undefined) {\n this._body.SetAngularVelocity(behaviorSpecificProps.av);\n }\n\n if (behaviorSpecificProps.aw !== undefined) {\n this._body.SetAwake(behaviorSpecificProps.aw);\n }\n }\n\n onDeActivate() {\n this._sharedData.removeFromBehaviorsList(this);\n if (this._body !== null) {\n // When a body is deleted, Box2D removes automatically its joints, leaving an invalid pointer in our joints list\n this._sharedData.clearBodyJoints(this._body);\n\n // Delete the vertices\n if (this._verticesBuffer) {\n Box2D._free(this._verticesBuffer);\n this._verticesBuffer = 0;\n }\n\n // Delete the body\n this._sharedData.world.DestroyBody(this._body);\n this._body = null;\n }\n this.contactsEndedThisFrame.length = 0;\n this.contactsStartedThisFrame.length = 0;\n this.currentContacts.length = 0;\n }\n\n onActivate() {\n this._sharedData.addToBehaviorsList(this);\n\n this.contactsEndedThisFrame.length = 0;\n this.contactsStartedThisFrame.length = 0;\n this.currentContacts.length = 0;\n this.updateBodyFromObject();\n }\n\n onDestroy() {\n this.destroyedDuringFrameLogic = true;\n this.onDeActivate();\n }\n\n static getPolygon(verticesData: Box2D.b2Vec2[]): gdjs.Polygon | null {\n if (!verticesData) {\n return null;\n }\n const polygon = new gdjs.Polygon();\n const maxVertices = 8;\n for (\n let i = 0, len = verticesData.length;\n i < Math.min(len, maxVertices);\n i++\n ) {\n polygon.vertices.push([verticesData[i].x, verticesData[i].y]);\n }\n return polygon;\n }\n\n static isPolygonConvex(polygon: gdjs.Polygon): boolean {\n if (!polygon.isConvex()) {\n return false;\n }\n\n // Check for repeated vertices or check if all vertices are aligned (would crash Box2D)\n let alignedX = true;\n let alignedY = true;\n for (let i = 0; i < polygon.vertices.length - 1; ++i) {\n for (let j = i + 1; j < polygon.vertices.length; ++j) {\n if (\n polygon.vertices[i][0] === polygon.vertices[j][0] &&\n polygon.vertices[i][1] === polygon.vertices[j][1]\n ) {\n return false;\n }\n }\n if (polygon.vertices[i][0] !== polygon.vertices[i + 1][0]) {\n alignedX = false;\n }\n if (polygon.vertices[i][1] !== polygon.vertices[i + 1][1]) {\n alignedY = false;\n }\n }\n if (alignedX || alignedY) {\n return false;\n }\n return true;\n }\n\n createShape(): Box2D.b2FixtureDef {\n // Get the scaled offset\n const offsetX = this.shapeOffsetX\n ? this.shapeOffsetX * this.shapeScale * this._sharedData.worldInvScale\n : 0;\n const offsetY = this.shapeOffsetY\n ? this.shapeOffsetY * this.shapeScale * this._sharedData.worldInvScale\n : 0;\n\n // Generate the base shape\n let shape;\n if (this.shape === 'Circle') {\n shape = new Box2D.b2CircleShape();\n\n // Radius determined by the custom dimension\n // Average radius from width and height\n if (this.shapeDimensionA > 0) {\n shape.set_m_radius(\n Math.max(0.1, this.shapeDimensionA) *\n this.shapeScale *\n this._sharedData.worldInvScale\n );\n } else {\n const radius =\n (Math.max(0.1, this.owner.getWidth()) *\n this._sharedData.worldInvScale +\n Math.max(0.1, this.owner.getHeight()) *\n this._sharedData.worldInvScale) /\n 4;\n shape.set_m_radius(radius);\n }\n\n // Set the offset\n shape.set_m_p(this.b2Vec2(offsetX, offsetY));\n } else {\n if (this.shape === 'Polygon') {\n shape = new Box2D.b2PolygonShape();\n\n // Not convex, fall back to a box\n if (\n !this.polygon ||\n !Physics2RuntimeBehavior.isPolygonConvex(this.polygon)\n ) {\n const width =\n Math.max(0.1, this.owner.getWidth()) *\n this._sharedData.worldInvScale;\n const height =\n Math.max(0.1, this.owner.getHeight()) *\n this._sharedData.worldInvScale;\n\n // Set the shape box\n shape.SetAsBox(\n width / 2,\n height / 2,\n this.b2Vec2(offsetX, offsetY),\n 0\n );\n } else {\n let originOffsetX = 0;\n let originOffsetY = 0;\n if (this.polygonOrigin === 'Origin') {\n originOffsetX =\n (this.owner.getWidth() > 0 ? -this.owner.getWidth() / 2 : 0) +\n (this.owner.getX() - this.owner.getDrawableX());\n originOffsetY =\n (this.owner.getHeight() > 0 ? -this.owner.getHeight() / 2 : 0) +\n (this.owner.getY() - this.owner.getDrawableY());\n } else {\n if (this.polygonOrigin === 'TopLeft') {\n originOffsetX =\n this.owner.getWidth() > 0 ? -this.owner.getWidth() / 2 : 0;\n originOffsetY =\n this.owner.getHeight() > 0 ? -this.owner.getHeight() / 2 : 0;\n }\n }\n\n // Generate vertices if not done already\n if (!this._verticesBuffer) {\n // Store the vertices using a memory allocation function\n const buffer = Box2D._malloc(\n this.polygon.vertices.length * 8,\n 'float',\n Box2D.ALLOC_STACK\n );\n this._verticesBuffer = buffer;\n }\n\n // Overwrite the vertices stored in the buffer\n let offset = 0;\n for (let i = 0, len = this.polygon.vertices.length; i < len; i++) {\n Box2D.HEAPF32[(this._verticesBuffer + offset) >> 2] =\n (this.polygon.vertices[i][0] * this.shapeScale +\n originOffsetX) *\n this._sharedData.worldInvScale +\n offsetX;\n Box2D.HEAPF32[(this._verticesBuffer + (offset + 4)) >> 2] =\n (this.polygon.vertices[i][1] * this.shapeScale +\n originOffsetY) *\n this._sharedData.worldInvScale +\n offsetY;\n offset += 8;\n }\n\n // Set the shape vertices\n const b2Vertices = Box2D.wrapPointer(\n this._verticesBuffer,\n Box2D.b2Vec2\n );\n shape.Set(b2Vertices, this.polygon.vertices.length);\n }\n } else {\n if (this.shape === 'Edge') {\n shape = new Box2D.b2EdgeShape();\n\n // Length from the custom dimension or from the object width\n const length =\n (this.shapeDimensionA > 0\n ? Math.max(0.1, this.shapeDimensionA * this.shapeScale)\n : Math.max(0.1, this.owner.getWidth())) *\n this._sharedData.worldInvScale;\n const height =\n Math.max(0.1, this.owner.getHeight()) *\n this._sharedData.worldInvScale;\n\n // Angle from custom dimension, otherwise is 0\n const angle = this.shapeDimensionB\n ? gdjs.toRad(this.shapeDimensionB)\n : 0;\n\n // Set the edge vertices from the length, the angle and the offset\n shape.Set(\n this.b2Vec2(\n (-length / 2) * Math.cos(angle) + offsetX,\n height / 2 - (length / 2) * Math.sin(angle) + offsetY\n ),\n this.b2Vec2Sec(\n (length / 2) * Math.cos(angle) + offsetX,\n height / 2 + (length / 2) * Math.sin(angle) + offsetY\n )\n );\n } else {\n // Box\n shape = new Box2D.b2PolygonShape();\n\n // Width and height from custom dimensions or object size\n const width =\n (this.shapeDimensionA > 0\n ? Math.max(0.1, this.shapeDimensionA * this.shapeScale)\n : Math.max(0.1, this.owner.getWidth())) *\n this._sharedData.worldInvScale;\n const height =\n (this.shapeDimensionB > 0\n ? Math.max(0.1, this.shapeDimensionB * this.shapeScale)\n : Math.max(0.1, this.owner.getHeight())) *\n this._sharedData.worldInvScale;\n\n // Set the shape box, the offset must be added here too\n shape.SetAsBox(\n width / 2,\n height / 2,\n this.b2Vec2(offsetX, offsetY),\n 0\n );\n }\n }\n }\n\n // Generate filter data\n const filter = new Box2D.b2Filter();\n filter.set_categoryBits(this.layers);\n filter.set_maskBits(this.masks);\n\n // Generate the fixture definition\n const fixDef = new Box2D.b2FixtureDef();\n\n // Set fixture settings\n fixDef.set_shape(shape);\n fixDef.set_filter(filter);\n if (this.density < 0) {\n this.density = 0;\n }\n fixDef.set_density(this.density);\n if (this.friction < 0) {\n this.friction = 0;\n }\n fixDef.set_friction(this.friction);\n if (this.restitution < 0) {\n this.restitution = 0;\n }\n fixDef.set_restitution(this.restitution);\n\n // Return the fixture\n return fixDef;\n }\n\n recreateShape(): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Destroy the old shape\n body.DestroyFixture(body.GetFixtureList());\n body.CreateFixture(this.createShape());\n\n // Update cached size\n this._objectOldWidth = this.owner.getWidth();\n this._objectOldHeight = this.owner.getHeight();\n }\n\n getShapeScale(): float {\n return this.shapeScale;\n }\n\n setShapeScale(shapeScale: float): void {\n if (shapeScale !== this.shapeScale && shapeScale > 0) {\n this.shapeScale = shapeScale;\n this.recreateShape();\n }\n }\n\n getBody(): Box2D.b2Body {\n // If there is no body, set a new one\n if (this._body === null) {\n this.createBody();\n }\n return this._body!;\n }\n\n createBody(): boolean {\n if (!this.activated() || this.destroyedDuringFrameLogic) return false;\n // Generate the body definition\n const bodyDef = new Box2D.b2BodyDef();\n\n const x =\n (this.owner.getDrawableX() + this.owner.getWidth() / 2) *\n this._sharedData.worldInvScale;\n const y =\n (this.owner.getDrawableY() + this.owner.getHeight() / 2) *\n this._sharedData.worldInvScale;\n\n // Set the initial body transformation from the GD object\n bodyDef.set_position(\n this.b2Vec2(Number.isFinite(x) ? x : 0, Number.isFinite(y) ? y : 0)\n );\n const angle = gdjs.toRad(this.owner.getAngle());\n if (Number.isFinite(angle)) {\n bodyDef.set_angle(angle);\n }\n\n // Set body settings\n bodyDef.set_type(\n this.bodyType === 'Static'\n ? Box2D.b2_staticBody\n : this.bodyType === 'Kinematic'\n ? Box2D.b2_kinematicBody\n : Box2D.b2_dynamicBody\n );\n bodyDef.set_bullet(this.bullet);\n bodyDef.set_fixedRotation(this.fixedRotation);\n bodyDef.set_allowSleep(this.canSleep);\n bodyDef.set_linearDamping(this.linearDamping);\n bodyDef.set_angularDamping(this.angularDamping);\n bodyDef.set_gravityScale(this.gravityScale);\n\n // Create the body\n this._body = this._sharedData.world.CreateBody(bodyDef);\n this._body.CreateFixture(this.createShape());\n this._body.gdjsAssociatedBehavior = this;\n\n // Update cached size\n this._objectOldWidth = this.owner.getWidth();\n this._objectOldHeight = this.owner.getHeight();\n return true;\n }\n\n doStepPreEvents(instanceContainer: gdjs.RuntimeInstanceContainer) {\n // Step the world if not done this frame yet.\n // Don't step at the first frame to allow events to handle overlapping objects.\n if (\n !this._sharedData.stepped &&\n !instanceContainer.getScene().getTimeManager().isFirstFrame()\n ) {\n this._sharedData.step(\n instanceContainer.getScene().getTimeManager().getElapsedTime() /\n 1000.0\n );\n }\n }\n\n doStepPostEvents(instanceContainer: gdjs.RuntimeInstanceContainer) {\n // Reset world step to update next frame\n this._sharedData.stepped = false;\n }\n\n onObjectHotReloaded() {\n this.updateBodyFromObject();\n }\n\n updateObjectFromBody() {\n // Copy transform from body to the GD object.\n // The body is null when the behavior was either deactivated or the object deleted.\n // It would be useless to try to recreate it as updateBodyFromObject already does it.\n // If the body is null, we just don't do anything\n // (but still run the physics simulation - this is independent).\n if (this._body !== null && !this.isStatic() && this._body.IsAwake()) {\n this.owner.setX(\n this._body.GetPosition().get_x() * this._sharedData.worldScale -\n this.owner.getWidth() / 2 +\n this.owner.getX() -\n this.owner.getDrawableX()\n );\n this.owner.setY(\n this._body.GetPosition().get_y() * this._sharedData.worldScale -\n this.owner.getHeight() / 2 +\n this.owner.getY() -\n this.owner.getDrawableY()\n );\n this.owner.setAngle(gdjs.toDegrees(this._body.GetAngle()));\n }\n\n // Update cached transform.\n this._objectOldX = this.owner.getX();\n this._objectOldY = this.owner.getY();\n this._objectOldAngle = this.owner.getAngle();\n }\n\n updateBodyFromObject() {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // The object size has changed, recreate the shape.\n // The width has changed and there is no custom dimension A (box: width, circle: radius, edge: length) or\n // The height has changed, the shape is not an edge (edges doesn't have height),\n // it isn't a box with custom height or a circle with custom radius\n if (\n (this._objectOldWidth !== this.owner.getWidth() &&\n this.shapeDimensionA <= 0) ||\n (this._objectOldHeight !== this.owner.getHeight() &&\n this.shape !== 'Edge' &&\n !(this.shape === 'Box' && this.shapeDimensionB > 0) &&\n !(this.shape === 'Circle' && this.shapeDimensionA > 0))\n ) {\n this.recreateShape();\n }\n\n // The object object transform has changed, update body transform:\n if (\n this._objectOldX !== this.owner.getX() ||\n this._objectOldY !== this.owner.getY() ||\n this._objectOldAngle !== this.owner.getAngle()\n ) {\n const x =\n (this.owner.getDrawableX() + this.owner.getWidth() / 2) *\n this._sharedData.worldInvScale;\n const y =\n (this.owner.getDrawableY() + this.owner.getHeight() / 2) *\n this._sharedData.worldInvScale;\n const pos = this.b2Vec2(\n Number.isFinite(x) ? x : body.GetPosition().x,\n Number.isFinite(y) ? y : body.GetPosition().y\n );\n const angle = gdjs.toRad(this.owner.getAngle());\n body.SetTransform(\n pos,\n Number.isFinite(angle) ? angle : body.GetAngle()\n );\n body.SetAwake(true);\n }\n }\n\n getWorldScale(): float {\n return this._sharedData.worldScale;\n }\n\n getGravityX(): float {\n return this._sharedData.gravityX;\n }\n\n getGravityY(): float {\n return this._sharedData.gravityY;\n }\n\n setGravity(x: float, y: float): void {\n // Check if there is no modification\n if (this._sharedData.gravityX === x && this._sharedData.gravityY === y) {\n return;\n }\n\n // Change the gravity\n this._sharedData.gravityX = x;\n this._sharedData.gravityY = y;\n this._sharedData.world.SetGravity(\n this.b2Vec2(this._sharedData.gravityX, this._sharedData.gravityY)\n );\n }\n\n getTimeScale(): float {\n // Get the time scale\n return this._sharedData.timeScale;\n }\n\n setTimeScale(timeScale: float): void {\n // Invalid value\n if (timeScale < 0) {\n return;\n }\n\n // Set the time scale\n this._sharedData.timeScale = timeScale;\n }\n\n static setTimeScaleFromObject(object, behaviorName, timeScale) {\n // Check if the object exist and has the behavior\n if (object === null || !object.hasBehavior(behaviorName)) {\n return;\n }\n\n // Set the time scale\n object.getBehavior(behaviorName).setTimeScale(timeScale);\n }\n\n isDynamic(): boolean {\n return this.bodyType === 'Dynamic';\n }\n\n setDynamic(): void {\n // Check if there is no modification\n if (this.bodyType === 'Dynamic') {\n return;\n }\n\n // Change body type\n this.bodyType = 'Dynamic';\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update body type\n body.SetType(Box2D.b2_dynamicBody);\n body.SetAwake(true);\n }\n\n isStatic(): boolean {\n return this.bodyType === 'Static';\n }\n\n setStatic(): void {\n // Check if there is no modification\n if (this.bodyType === 'Static') {\n return;\n }\n\n // Change body type\n this.bodyType = 'Static';\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update body type\n body.SetType(Box2D.b2_staticBody);\n body.SetAwake(true);\n }\n\n isKinematic(): boolean {\n return this.bodyType === 'Kinematic';\n }\n\n setKinematic(): void {\n // Check if there is no modification\n if (this.bodyType === 'Kinematic') {\n return;\n }\n\n // Change body type\n this.bodyType = 'Kinematic';\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update body type\n body.SetType(Box2D.b2_kinematicBody);\n body.SetAwake(true);\n }\n\n isBullet(): boolean {\n return this.bullet;\n }\n\n setBullet(enable: boolean): void {\n // Check if there is no modification\n if (this.bullet === enable) {\n return;\n }\n\n // Change bullet flag\n this.bullet = enable;\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update body bullet flag\n body.SetBullet(this.bullet);\n }\n\n hasFixedRotation(): boolean {\n return this.fixedRotation;\n }\n\n setFixedRotation(enable: boolean): void {\n this.fixedRotation = enable;\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n body.SetFixedRotation(this.fixedRotation);\n }\n\n isSleepingAllowed(): boolean {\n return this.canSleep;\n }\n\n setSleepingAllowed(enable: boolean): void {\n this.canSleep = enable;\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n body.SetSleepingAllowed(this.canSleep);\n }\n\n isSleeping(): boolean {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return true;\n }\n const body = this._body!;\n\n // Get the body sleeping state\n return !body.IsAwake();\n }\n\n getDensity() {\n return this.density;\n }\n\n setDensity(density: float): void {\n // Non-negative values only\n if (density < 0) {\n density = 0;\n }\n\n // Check if there is no modification\n if (this.density === density) {\n return;\n }\n\n // Change density\n this.density = density;\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update the body density\n body.GetFixtureList().SetDensity(this.density);\n body.ResetMassData();\n }\n\n getFriction(): float {\n return this.friction;\n }\n\n setFriction(friction): void {\n // Non-negative values only\n if (friction < 0) {\n friction = 0;\n }\n\n // Check if there is no modification\n if (this.friction === friction) {\n return;\n }\n\n // Change friction\n this.friction = friction;\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update the body friction\n body.GetFixtureList().SetFriction(this.friction);\n\n // Update contacts\n let contact = body.GetContactList();\n while (Box2D.getPointer(contact)) {\n contact.get_contact().ResetFriction();\n contact = contact.get_next();\n }\n }\n\n getRestitution(): float {\n return this.restitution;\n }\n\n setRestitution(restitution: float): void {\n // Non-negative values only\n if (restitution < 0) {\n restitution = 0;\n }\n\n // Check if there is no modification\n if (this.restitution === restitution) {\n return;\n }\n\n // Change restitution\n this.restitution = restitution;\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update the body restitution\n body.GetFixtureList().SetRestitution(this.restitution);\n\n // Update contacts\n let contact = body.GetContactList();\n while (Box2D.getPointer(contact)) {\n contact.get_contact().ResetRestitution();\n contact = contact.get_next();\n }\n }\n\n getLinearDamping(): float {\n return this.linearDamping;\n }\n\n setLinearDamping(linearDamping: float): void {\n // Non-negative values only\n if (linearDamping < 0) {\n linearDamping = 0;\n }\n\n // Check if there is no modification\n if (this.linearDamping === linearDamping) {\n return;\n }\n\n // Change linearDamping\n this.linearDamping = linearDamping;\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update the body linear damping\n body.SetLinearDamping(this.linearDamping);\n }\n\n getAngularDamping(): float {\n return this.angularDamping;\n }\n\n setAngularDamping(angularDamping: float): void {\n // Non-negative values only\n if (angularDamping < 0) {\n angularDamping = 0;\n }\n\n // Check if there is no modification\n if (this.angularDamping === angularDamping) {\n return;\n }\n\n // Change angularDamping\n this.angularDamping = angularDamping;\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update the body angular damping\n body.SetAngularDamping(this.angularDamping);\n }\n\n getGravityScale(): float {\n return this.gravityScale;\n }\n\n setGravityScale(gravityScale: float): void {\n // Check if there is no modification\n if (this.gravityScale === gravityScale) {\n return;\n }\n\n // Change the gravity scale\n this.gravityScale = gravityScale;\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update the body gravity scale\n body.SetGravityScale(this.gravityScale);\n }\n\n layerEnabled(layer: integer) {\n // Layer must be an integer\n layer = Math.floor(layer);\n\n // Layer must be in range [1, 16]\n if (layer < 1 || layer > 16) {\n return false;\n }\n return !!(this.layers & (1 << (layer - 1)));\n }\n\n enableLayer(layer: integer, enable: boolean): void {\n // Layer must be an integer\n layer = Math.floor(layer);\n\n // Layer must be in range [1, 16]\n if (layer < 1 || layer > 16) {\n return;\n }\n\n // Change the layers\n if (enable) {\n this.layers |= 1 << (layer - 1);\n } else {\n this.layers &= ~(1 << (layer - 1));\n }\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update the body layers\n const filter = body.GetFixtureList().GetFilterData();\n filter.set_categoryBits(this.layers);\n body.GetFixtureList().SetFilterData(filter);\n }\n\n maskEnabled(mask: integer): boolean {\n // Mask must be an integer\n mask = Math.floor(mask);\n\n // Mask must be in range [1, 16]\n if (mask < 1 || mask > 16) {\n return false;\n }\n return !!(this.masks & (1 << (mask - 1)));\n }\n\n enableMask(mask: integer, enable: boolean): void {\n // Mask must be an integer\n mask = Math.floor(mask);\n\n // Mask must be in range [1, 16]\n if (mask < 1 || mask > 16) {\n return;\n }\n\n // Change the masks\n if (enable) {\n this.masks |= 1 << (mask - 1);\n } else {\n this.masks &= ~(1 << (mask - 1));\n }\n\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Update the body masks\n const filter = body.GetFixtureList().GetFilterData();\n filter.set_maskBits(this.masks);\n body.GetFixtureList().SetFilterData(filter);\n }\n\n getLinearVelocityX(): float {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return 0;\n }\n const body = this._body!;\n\n // Get the linear velocity on X\n return body.GetLinearVelocity().get_x() * this._sharedData.worldScale;\n }\n\n setLinearVelocityX(linearVelocityX: float): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Set the linear velocity on X\n body.SetLinearVelocity(\n this.b2Vec2(\n linearVelocityX * this._sharedData.worldInvScale,\n body.GetLinearVelocity().get_y()\n )\n );\n }\n\n getLinearVelocityY(): float {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return 0;\n }\n const body = this._body!;\n\n // Get the linear velocity on Y\n return body.GetLinearVelocity().get_y() * this._sharedData.worldScale;\n }\n\n setLinearVelocityY(linearVelocityY: float): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Set the linear velocity on Y\n body.SetLinearVelocity(\n this.b2Vec2(\n body.GetLinearVelocity().get_x(),\n linearVelocityY * this._sharedData.worldInvScale\n )\n );\n }\n\n getLinearVelocityLength(): float {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return 0;\n }\n const body = this._body!;\n\n // Get the linear velocity length\n return this.b2Vec2(\n body.GetLinearVelocity().get_x() * this._sharedData.worldScale,\n body.GetLinearVelocity().get_y() * this._sharedData.worldScale\n ).Length();\n }\n\n getLinearVelocityAngle(): float {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return 0;\n }\n const body = this._body!;\n\n // Get the linear velocity angle\n return gdjs.toDegrees(\n Math.atan2(\n body.GetLinearVelocity().get_y() * this._sharedData.worldScale,\n body.GetLinearVelocity().get_x() * this._sharedData.worldScale\n )\n );\n }\n\n setLinearVelocityAngle(angle: float, linearVelocity: float): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Set the linear velocity toward an angle\n angle = gdjs.toRad(angle);\n body.SetLinearVelocity(\n this.b2Vec2(\n linearVelocity * Math.cos(angle) * this._sharedData.worldInvScale,\n linearVelocity * Math.sin(angle) * this._sharedData.worldInvScale\n )\n );\n }\n\n isLinearVelocityAngleAround(degreeAngle: float, tolerance: float) {\n return (\n Math.abs(\n gdjs.evtTools.common.angleDifference(\n this.getLinearVelocityAngle(),\n degreeAngle\n )\n ) <= tolerance\n );\n }\n\n getAngularVelocity(): float {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return 0;\n }\n const body = this._body!;\n\n // Get the angular velocity\n return gdjs.toDegrees(body.GetAngularVelocity());\n }\n\n setAngularVelocity(angularVelocity: float): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Set the angular velocity\n body.SetAngularVelocity(gdjs.toRad(angularVelocity));\n }\n\n applyForce(\n forceX: float,\n forceY: float,\n positionX: float,\n positionY: float\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Wake up the object\n body.SetAwake(true);\n\n // Apply the force\n body.ApplyForce(\n this.b2Vec2(forceX, forceY),\n this.b2Vec2Sec(\n positionX * this._sharedData.worldInvScale,\n positionY * this._sharedData.worldInvScale\n ),\n // TODO Should let Box2d awake the object itself.\n false\n );\n }\n\n applyPolarForce(\n angle: float,\n length: float,\n positionX: float,\n positionY: float\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Wake up the object\n body.SetAwake(true);\n\n // Apply the force\n angle = gdjs.toRad(angle);\n body.ApplyForce(\n this.b2Vec2(length * Math.cos(angle), length * Math.sin(angle)),\n this.b2Vec2Sec(\n positionX * this._sharedData.worldInvScale,\n positionY * this._sharedData.worldInvScale\n ),\n // TODO Should let Box2d awake the object itself.\n false\n );\n }\n\n applyForceTowardPosition(\n length: float,\n towardX: float,\n towardY: float,\n positionX: float,\n positionY: float\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Wake up the object\n body.SetAwake(true);\n\n // TODO Optimize this using a unit vector instead of trigonometry.\n // Apply the force\n const angle = Math.atan2(\n towardY * this._sharedData.worldInvScale - body.GetPosition().get_y(),\n towardX * this._sharedData.worldInvScale - body.GetPosition().get_x()\n );\n body.ApplyForce(\n this.b2Vec2(length * Math.cos(angle), length * Math.sin(angle)),\n this.b2Vec2Sec(\n positionX * this._sharedData.worldInvScale,\n positionY * this._sharedData.worldInvScale\n ),\n // TODO Should let Box2d awake the object itself.\n false\n );\n }\n\n applyImpulse(\n impulseX: float,\n impulseY: float,\n positionX: float,\n positionY: float\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Wake up the object\n body.SetAwake(true);\n\n // Apply the impulse\n body.ApplyLinearImpulse(\n this.b2Vec2(impulseX, impulseY),\n this.b2Vec2Sec(\n positionX * this._sharedData.worldInvScale,\n positionY * this._sharedData.worldInvScale\n ),\n // TODO Should let Box2d awake the object itself.\n false\n );\n }\n\n applyPolarImpulse(\n angle: float,\n length: float,\n positionX: float,\n positionY: float\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Wake up the object\n body.SetAwake(true);\n\n // Apply the impulse\n angle = gdjs.toRad(angle);\n body.ApplyLinearImpulse(\n this.b2Vec2(length * Math.cos(angle), length * Math.sin(angle)),\n this.b2Vec2Sec(\n positionX * this._sharedData.worldInvScale,\n positionY * this._sharedData.worldInvScale\n ),\n // TODO Should let Box2d awake the object itself.\n false\n );\n }\n\n applyImpulseTowardPosition(\n length: float,\n towardX: float,\n towardY: float,\n positionX: float,\n positionY: float\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Wake up the object\n body.SetAwake(true);\n\n // TODO Optimize this using a unit vector instead of trigonometry.\n // Apply the impulse\n const angle = Math.atan2(\n towardY * this._sharedData.worldInvScale - body.GetPosition().get_y(),\n towardX * this._sharedData.worldInvScale - body.GetPosition().get_x()\n );\n body.ApplyLinearImpulse(\n this.b2Vec2(length * Math.cos(angle), length * Math.sin(angle)),\n this.b2Vec2Sec(\n positionX * this._sharedData.worldInvScale,\n positionY * this._sharedData.worldInvScale\n ),\n // TODO Should let Box2d awake the object itself.\n false\n );\n }\n\n applyTorque(torque: float): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Wake up the object\n body.SetAwake(true);\n\n // Apply the torque\n body.ApplyTorque(\n torque,\n // TODO Should let Box2d awake the object itself.\n false\n );\n }\n\n applyAngularImpulse(angularImpulse: float): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Wake up the object\n body.SetAwake(true);\n\n // Apply the angular impulse\n body.ApplyAngularImpulse(\n angularImpulse,\n // TODO Should let Box2d awake the object itself.\n false\n );\n }\n\n getMass(): float {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return 0;\n }\n const body = this._body!;\n\n // Wake up the object\n body.SetAwake(true);\n\n return body.GetMass();\n }\n\n getInertia(): float {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return 0;\n }\n const body = this._body!;\n\n // Wake up the object\n body.SetAwake(true);\n\n return body.GetInertia();\n }\n\n getMassCenterX(): float {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return 0;\n }\n const body = this._body!;\n\n // Get the mass center on X\n return body.GetWorldCenter().get_x() * this._sharedData.worldScale;\n }\n\n getMassCenterY(): float {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return 0;\n }\n const body = this._body!;\n\n // Get the mass center on Y\n return body.GetWorldCenter().get_y() * this._sharedData.worldScale;\n }\n\n // Joints\n isJointFirstObject(jointId: integer | string): boolean {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return false;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId);\n\n // Joint not found\n if (joint === null) {\n return false;\n }\n\n // Check the joint object\n return joint.GetBodyA() === this._body;\n }\n\n isJointSecondObject(jointId: integer | string): boolean {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return false;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId);\n\n // Joint not found\n if (joint === null) {\n return false;\n }\n\n // Check the joint object\n return joint.GetBodyB() === this._body;\n }\n\n getJointFirstAnchorX(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId);\n\n // Joint not found\n if (joint === null) {\n return 0;\n }\n\n // Get the joint anchor\n // @ts-ignore GetLocalAnchorA is implemented by any joint but is not in the interface.\n return joint.GetBodyA().GetWorldPoint(joint.GetLocalAnchorA()).get_x();\n }\n\n getJointFirstAnchorY(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId);\n\n // Joint not found\n if (joint === null) {\n return 0;\n }\n\n // Get the joint anchor\n // @ts-ignore GetLocalAnchorA is implemented by any joint but is not in the interface.\n return joint.GetBodyA().GetWorldPoint(joint.GetLocalAnchorA()).get_y();\n }\n\n getJointSecondAnchorX(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId);\n\n // Joint not found\n if (joint === null) {\n return 0;\n }\n\n // Get the joint anchor\n // @ts-ignore GetLocalAnchorA is implemented by any joint but is not in the interface.\n return joint.GetBodyB().GetWorldPoint(joint.GetLocalAnchorB()).get_x();\n }\n\n getJointSecondAnchorY(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId);\n\n // Joint not found\n if (joint === null) {\n return 0;\n }\n\n // Get the joint anchor\n // @ts-ignore GetLocalAnchorA is implemented by any joint but is not in the interface.\n return joint.GetBodyB().GetWorldPoint(joint.GetLocalAnchorB()).get_y();\n }\n\n getJointReactionForce(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId);\n\n // Joint not found\n if (joint === null) {\n return 0;\n }\n\n // Get the reaction force\n return joint.GetReactionForce(1 / this._sharedData.timeStep).Length();\n }\n\n getJointReactionTorque(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId);\n\n // Joint not found\n if (joint === null) {\n return 0;\n }\n\n // Get the reaction torque\n return joint.GetReactionTorque(1 / this._sharedData.timeStep);\n }\n\n removeJoint(jointId: integer | string): void {\n // Just let the sharedData to manage and delete the joint\n this._sharedData.removeJoint(jointId);\n }\n\n // Distance joint\n addDistanceJoint(\n x1: float,\n y1: float,\n other: gdjs.RuntimeObject | null,\n x2: float,\n y2: float,\n length: float,\n frequency: float,\n dampingRatio: float,\n collideConnected: boolean,\n variable: gdjs.Variable\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // If there is no second object or it doesn't share the behavior, return\n if (other == null || !other.hasBehavior(this.name)) {\n return;\n }\n\n // Get the second body\n const otherBody = (\n other.getBehavior(this.name) as gdjs.Physics2RuntimeBehavior\n ).getBody();\n\n // If the first and second objects/bodies are the same, return\n if (this._body === otherBody) {\n return;\n }\n\n // Set joint settings\n const jointDef = new Box2D.b2DistanceJointDef();\n jointDef.set_bodyA(body);\n jointDef.set_localAnchorA(\n body.GetLocalPoint(\n this.b2Vec2(\n x1 * this._sharedData.worldInvScale,\n y1 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_bodyB(otherBody);\n jointDef.set_localAnchorB(\n otherBody.GetLocalPoint(\n this.b2Vec2(\n x2 * this._sharedData.worldInvScale,\n y2 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_length(\n length > 0\n ? length * this._sharedData.worldInvScale\n : this.b2Vec2(\n (x2 - x1) * this._sharedData.worldInvScale,\n (y2 - y1) * this._sharedData.worldInvScale\n ).Length()\n );\n jointDef.set_frequencyHz(frequency >= 0 ? frequency : 0);\n jointDef.set_dampingRatio(dampingRatio >= 0 ? dampingRatio : 1);\n jointDef.set_collideConnected(collideConnected);\n\n // Create the joint and get the id\n const jointId = this._sharedData.addJoint(\n Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2DistanceJoint\n )\n );\n\n // Store the id in the variable\n variable.setNumber(jointId);\n }\n\n getDistanceJointLength(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2DistanceJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_distanceJoint) {\n return 0;\n }\n\n // Get the joint length\n return joint.GetLength() * this._sharedData.worldScale;\n }\n\n setDistanceJointLength(jointId: integer | string, length: float): void {\n // Invalid value\n if (length <= 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2DistanceJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_distanceJoint) {\n return;\n }\n\n // Set the joint length\n joint.SetLength(length * this._sharedData.worldInvScale);\n\n // Awake the bodies\n joint.GetBodyA().SetAwake(true);\n joint.GetBodyB().SetAwake(true);\n }\n\n getDistanceJointFrequency(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2DistanceJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_distanceJoint) {\n return 0;\n }\n\n // Get the joint frequency\n return joint.GetFrequency();\n }\n\n setDistanceJointFrequency(\n jointId: integer | string,\n frequency: float\n ): void {\n // Invalid value\n if (frequency < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2DistanceJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_distanceJoint) {\n return;\n }\n\n // Set the joint frequency\n joint.SetFrequency(frequency);\n }\n\n getDistanceJointDampingRatio(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2DistanceJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_distanceJoint) {\n return 0;\n }\n\n // Get the joint damping ratio\n return joint.GetDampingRatio();\n }\n\n setDistanceJointDampingRatio(\n jointId: integer | string,\n dampingRatio: float\n ): void {\n // Invalid value\n if (dampingRatio < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2DistanceJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_distanceJoint) {\n }\n\n // Set the joint damping ratio\n joint.SetDampingRatio(dampingRatio);\n }\n\n // Revolute joint\n addRevoluteJoint(\n x: float,\n y: float,\n enableLimit: boolean,\n referenceAngle: float,\n lowerAngle: float,\n upperAngle: float,\n enableMotor: boolean,\n motorSpeed: float,\n maxMotorTorque: float,\n variable: gdjs.Variable\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Set joint settings\n const jointDef = new Box2D.b2RevoluteJointDef();\n jointDef.set_bodyA(this._sharedData.staticBody);\n jointDef.set_localAnchorA(\n this._sharedData.staticBody.GetLocalPoint(\n this.b2Vec2(\n x * this._sharedData.worldInvScale,\n y * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_bodyB(body);\n jointDef.set_localAnchorB(\n body.GetLocalPoint(\n this.b2Vec2(\n x * this._sharedData.worldInvScale,\n y * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_enableLimit(enableLimit);\n jointDef.set_referenceAngle(gdjs.toRad(referenceAngle));\n\n // Lower angle must be lower than upper angle\n if (upperAngle < lowerAngle) {\n const temp = lowerAngle;\n lowerAngle = upperAngle;\n upperAngle = temp;\n }\n jointDef.set_lowerAngle(gdjs.toRad(lowerAngle));\n jointDef.set_upperAngle(gdjs.toRad(upperAngle));\n jointDef.set_enableMotor(enableMotor);\n jointDef.set_motorSpeed(gdjs.toRad(motorSpeed));\n jointDef.set_maxMotorTorque(maxMotorTorque >= 0 ? maxMotorTorque : 0);\n jointDef.set_collideConnected(false);\n\n // Create the joint and get the id\n const jointId = this._sharedData.addJoint(\n Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2RevoluteJoint\n )\n );\n\n // Store the id in the variable\n variable.setNumber(jointId);\n }\n\n addRevoluteJointBetweenTwoBodies(\n x1: float,\n y1: float,\n other: gdjs.RuntimeObject | null,\n x2: float,\n y2: float,\n enableLimit: boolean,\n referenceAngle: float,\n lowerAngle: float,\n upperAngle: float,\n enableMotor: boolean,\n motorSpeed: float,\n maxMotorTorque: float,\n collideConnected: boolean,\n variable: gdjs.Variable\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n\n // If there is no second object or it doesn't share the behavior, return\n if (other == null || !other.hasBehavior(this.name)) {\n return;\n }\n\n // Get the second body\n const otherBody = (\n other.getBehavior(this.name) as gdjs.Physics2RuntimeBehavior\n ).getBody();\n\n // If the first and second objects/bodies are the same, return\n if (this._body === otherBody) {\n return;\n }\n const body = this._body!;\n\n // Set joint settings\n const jointDef = new Box2D.b2RevoluteJointDef();\n jointDef.set_bodyA(body);\n jointDef.set_localAnchorA(\n body.GetLocalPoint(\n this.b2Vec2(\n x1 * this._sharedData.worldInvScale,\n y1 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_bodyB(otherBody);\n jointDef.set_localAnchorB(\n otherBody.GetLocalPoint(\n this.b2Vec2(\n x2 * this._sharedData.worldInvScale,\n y2 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_enableLimit(enableLimit);\n jointDef.set_referenceAngle(gdjs.toRad(referenceAngle));\n\n // Lower angle must be lower than upper angle\n if (upperAngle < lowerAngle) {\n const temp = lowerAngle;\n lowerAngle = upperAngle;\n upperAngle = temp;\n }\n jointDef.set_lowerAngle(gdjs.toRad(lowerAngle));\n jointDef.set_upperAngle(gdjs.toRad(upperAngle));\n jointDef.set_enableMotor(enableMotor);\n jointDef.set_motorSpeed(gdjs.toRad(motorSpeed));\n jointDef.set_maxMotorTorque(maxMotorTorque >= 0 ? maxMotorTorque : 0);\n jointDef.set_collideConnected(collideConnected);\n\n // Create the joint and get the id\n const jointId = this._sharedData.addJoint(\n Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2RevoluteJoint\n )\n );\n\n // Store the id in the variable\n variable.setNumber(jointId);\n }\n\n getRevoluteJointReferenceAngle(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return 0;\n }\n\n // Get the joint reference angle\n return gdjs.toDegrees(joint.GetReferenceAngle());\n }\n\n getRevoluteJointAngle(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return 0;\n }\n\n // Get the joint current angle\n return gdjs.toDegrees(joint.GetJointAngle());\n }\n\n getRevoluteJointSpeed(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return 0;\n }\n\n // Get the joint angular speed\n return gdjs.toDegrees(joint.GetJointSpeed());\n }\n\n isRevoluteJointLimitsEnabled(jointId: integer | string): boolean {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return false;\n }\n\n // Get the joint limits state\n return joint.IsLimitEnabled();\n }\n\n enableRevoluteJointLimits(\n jointId: integer | string,\n enable: boolean\n ): void {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return;\n }\n\n // Set the joint limits state\n joint.EnableLimit(enable);\n }\n\n getRevoluteJointMinAngle(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return 0;\n }\n\n // Get the joint lower angle\n return gdjs.toDegrees(joint.GetLowerLimit());\n }\n\n getRevoluteJointMaxAngle(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return 0;\n }\n\n // Get the joint upper angle\n return gdjs.toDegrees(joint.GetUpperLimit());\n }\n\n setRevoluteJointLimits(\n jointId: integer | string,\n lowerAngle: float,\n upperAngle: float\n ): void {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return;\n }\n\n // Lower angle must be lower than upper angle\n if (upperAngle < lowerAngle) {\n const temp = lowerAngle;\n lowerAngle = upperAngle;\n upperAngle = temp;\n }\n\n // Set the joint limits\n joint.SetLimits(gdjs.toRad(lowerAngle), gdjs.toRad(upperAngle));\n }\n\n isRevoluteJointMotorEnabled(jointId: integer | string): boolean {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return false;\n }\n\n // Get the joint motor state\n return joint.IsMotorEnabled();\n }\n\n enableRevoluteJointMotor(jointId: integer | string, enable): void {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return;\n }\n\n // Set the joint motor state\n joint.EnableMotor(enable);\n }\n\n getRevoluteJointMotorSpeed(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return 0;\n }\n\n // Get the joint motor speed\n return gdjs.toDegrees(joint.GetMotorSpeed());\n }\n\n setRevoluteJointMotorSpeed(jointId: integer | string, speed): void {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return;\n }\n\n // Set the joint motor speed\n joint.SetMotorSpeed(gdjs.toRad(speed));\n }\n\n getRevoluteJointMaxMotorTorque(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return 0;\n }\n\n // Get the joint max motor\n return joint.GetMaxMotorTorque();\n }\n\n setRevoluteJointMaxMotorTorque(jointId: integer | string, maxTorque): void {\n // Invalid value\n if (maxTorque < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return;\n }\n\n // Set the joint max motor\n joint.SetMaxMotorTorque(maxTorque);\n }\n\n getRevoluteJointMotorTorque(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RevoluteJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_revoluteJoint) {\n return 0;\n }\n\n // Get the joint motor torque\n return joint.GetMotorTorque(1 / this._sharedData.timeStep);\n }\n\n // Prismatic joint\n addPrismaticJoint(\n x1: float,\n y1: float,\n other: gdjs.RuntimeObject | null,\n x2: float,\n y2: float,\n axisAngle: float,\n referenceAngle: float,\n enableLimit: boolean,\n lowerTranslation: float,\n upperTranslation: float,\n enableMotor: boolean,\n motorSpeed: float,\n maxMotorForce: float,\n collideConnected: boolean,\n variable: gdjs.Variable\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n\n // If there is no second object or it doesn't share the behavior, return\n if (other == null || !other.hasBehavior(this.name)) {\n return;\n }\n\n // Get the second body\n const otherBody = (\n other.getBehavior(this.name) as gdjs.Physics2RuntimeBehavior\n ).getBody();\n\n // If the first and second objects/bodies are the same, return\n if (this._body === otherBody) {\n return;\n }\n const body = this._body!;\n\n // Set joint settings\n const jointDef = new Box2D.b2PrismaticJointDef();\n jointDef.set_bodyA(body);\n jointDef.set_localAnchorA(\n body.GetLocalPoint(\n this.b2Vec2(\n x1 * this._sharedData.worldInvScale,\n y1 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_bodyB(otherBody);\n jointDef.set_localAnchorB(\n otherBody.GetLocalPoint(\n this.b2Vec2(\n x2 * this._sharedData.worldInvScale,\n y2 * this._sharedData.worldInvScale\n )\n )\n );\n axisAngle = gdjs.toRad(axisAngle) - body.GetAngle();\n jointDef.set_localAxisA(\n this.b2Vec2(Math.cos(axisAngle), Math.sin(axisAngle))\n );\n jointDef.set_referenceAngle(gdjs.toRad(referenceAngle));\n jointDef.set_enableLimit(enableLimit);\n\n // Lower translation must be lower than upper translation\n if (upperTranslation < lowerTranslation) {\n const temp = lowerTranslation;\n lowerTranslation = upperTranslation;\n upperTranslation = temp;\n }\n\n // The translation range must include zero\n jointDef.set_lowerTranslation(\n lowerTranslation < 0\n ? lowerTranslation * this._sharedData.worldInvScale\n : 0\n );\n jointDef.set_upperTranslation(\n upperTranslation > 0\n ? upperTranslation * this._sharedData.worldInvScale\n : 0\n );\n jointDef.set_enableMotor(enableMotor);\n jointDef.set_motorSpeed(motorSpeed * this._sharedData.worldInvScale);\n jointDef.set_maxMotorForce(maxMotorForce);\n jointDef.set_collideConnected(collideConnected);\n\n // Create the joint and get the id\n const jointId = this._sharedData.addJoint(\n Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2PrismaticJoint\n )\n );\n\n // Store the id in the variable\n variable.setNumber(jointId);\n }\n\n getPrismaticJointAxisAngle(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return 0;\n }\n\n // Get the joint axis angle\n return gdjs.toDegrees(\n Math.atan2(\n joint.GetLocalAxisA().get_y(),\n joint.GetLocalAxisA().get_x()\n ) + joint.GetBodyA().GetAngle()\n );\n }\n\n getPrismaticJointReferenceAngle(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return 0;\n }\n\n // Get the joint reference angle\n return gdjs.toDegrees(joint.GetReferenceAngle());\n }\n\n getPrismaticJointTranslation(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return 0;\n }\n\n // Get the joint current translation\n return joint.GetJointTranslation() * this._sharedData.worldScale;\n }\n\n getPrismaticJointSpeed(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return 0;\n }\n\n // Get the joint speed\n return joint.GetJointSpeed() * this._sharedData.worldScale;\n }\n\n isPrismaticJointLimitsEnabled(jointId: integer | string): boolean {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return false;\n }\n\n // Get the joint limits state\n return joint.IsLimitEnabled();\n }\n\n enablePrismaticJointLimits(\n jointId: integer | string,\n enable: boolean\n ): void {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return;\n }\n\n // Set the joint limits state\n joint.EnableLimit(enable);\n }\n\n getPrismaticJointMinTranslation(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return 0;\n }\n\n // Get the joint lower limit\n return joint.GetLowerLimit() * this._sharedData.worldScale;\n }\n\n getPrismaticJointMaxTranslation(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return 0;\n }\n\n // Get the joint upper angle\n return joint.GetUpperLimit() * this._sharedData.worldScale;\n }\n\n setPrismaticJointLimits(\n jointId: integer | string,\n lowerTranslation: float,\n upperTranslation: float\n ): void {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return;\n }\n\n // Lower translation must be lower than upper translation\n if (upperTranslation < lowerTranslation) {\n const temp = lowerTranslation;\n lowerTranslation = upperTranslation;\n upperTranslation = temp;\n }\n\n // The translation range must include zero\n lowerTranslation = lowerTranslation < 0 ? lowerTranslation : 0;\n upperTranslation = upperTranslation > 0 ? upperTranslation : 0;\n\n // Set the joint limits\n joint.SetLimits(\n lowerTranslation * this._sharedData.worldInvScale,\n upperTranslation * this._sharedData.worldInvScale\n );\n }\n\n isPrismaticJointMotorEnabled(jointId: integer | string): boolean {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return false;\n }\n\n // Get the joint motor state\n return joint.IsMotorEnabled();\n }\n\n enablePrismaticJointMotor(\n jointId: integer | string,\n enable: boolean\n ): void {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return;\n }\n\n // Set the joint motor state\n joint.EnableMotor(enable);\n }\n\n getPrismaticJointMotorSpeed(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return 0;\n }\n\n // Get the joint motor speed\n return joint.GetMotorSpeed() * this._sharedData.worldScale;\n }\n\n setPrismaticJointMotorSpeed(jointId: integer | string, speed): void {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return;\n }\n\n // Set the joint motor speed\n joint.SetMotorSpeed(speed * this._sharedData.worldInvScale);\n }\n\n getPrismaticJointMaxMotorForce(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return 0;\n }\n\n // Get the joint max motor force\n return joint.GetMaxMotorForce();\n }\n\n setPrismaticJointMaxMotorForce(jointId: integer | string, maxForce): void {\n // Invalid value\n if (maxForce < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return;\n }\n\n // Set the joint max motor force\n joint.SetMaxMotorForce(maxForce);\n }\n\n getPrismaticJointMotorForce(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(\n jointId\n ) as Box2D.b2PrismaticJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_prismaticJoint) {\n return 0;\n }\n\n // Get the joint motor torque\n return joint.GetMotorForce(1 / this._sharedData.timeStep);\n }\n\n // Pulley joint\n addPulleyJoint(\n x1: float,\n y1: float,\n other: gdjs.RuntimeObject | null,\n x2: float,\n y2: float,\n groundX1: float,\n groundY1: float,\n groundX2: float,\n groundY2: float,\n lengthA: float,\n lengthB: float,\n ratio: float,\n collideConnected: boolean,\n variable: gdjs.Variable\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // If there is no second object or it doesn't share the behavior, return\n if (other == null || !other.hasBehavior(this.name)) {\n return;\n }\n\n // Get the second body\n const otherBody = (\n other.getBehavior(this.name) as gdjs.Physics2RuntimeBehavior\n ).getBody();\n\n // If the first and second objects/bodies are the same, return\n if (this._body === otherBody) {\n return;\n }\n\n // Set joint settings\n const jointDef = new Box2D.b2PulleyJointDef();\n jointDef.set_bodyA(body);\n jointDef.set_localAnchorA(\n body.GetLocalPoint(\n this.b2Vec2(\n x1 * this._sharedData.worldInvScale,\n y1 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_bodyB(otherBody);\n jointDef.set_localAnchorB(\n otherBody.GetLocalPoint(\n this.b2Vec2(\n x2 * this._sharedData.worldInvScale,\n y2 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_groundAnchorA(\n this.b2Vec2(\n groundX1 * this._sharedData.worldInvScale,\n groundY1 * this._sharedData.worldInvScale\n )\n );\n jointDef.set_groundAnchorB(\n this.b2Vec2(\n groundX2 * this._sharedData.worldInvScale,\n groundY2 * this._sharedData.worldInvScale\n )\n );\n jointDef.set_lengthA(\n lengthA > 0\n ? lengthA * this._sharedData.worldInvScale\n : this.b2Vec2(\n (groundX1 - x1) * this._sharedData.worldInvScale,\n (groundY1 - y1) * this._sharedData.worldInvScale\n ).Length()\n );\n jointDef.set_lengthB(\n lengthB > 0\n ? lengthB * this._sharedData.worldInvScale\n : this.b2Vec2(\n (groundX2 - x2) * this._sharedData.worldInvScale,\n (groundY2 - y2) * this._sharedData.worldInvScale\n ).Length()\n );\n jointDef.set_ratio(ratio > 0 ? ratio : 1);\n jointDef.set_collideConnected(collideConnected);\n\n // Create the joint and get the id\n const jointId = this._sharedData.addJoint(\n Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2PulleyJoint\n )\n );\n\n // Store the id in the variable\n variable.setNumber(jointId);\n }\n\n getPulleyJointFirstGroundAnchorX(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2PulleyJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_pulleyJoint) {\n return 0;\n }\n\n // Get the joint ground anchor\n return joint.GetGroundAnchorA().get_x() * this._sharedData.worldScale;\n }\n\n getPulleyJointFirstGroundAnchorY(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2PulleyJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_pulleyJoint) {\n return 0;\n }\n\n // Get the joint ground anchor\n return joint.GetGroundAnchorA().get_y() * this._sharedData.worldScale;\n }\n\n getPulleyJointSecondGroundAnchorX(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2PulleyJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_pulleyJoint) {\n return 0;\n }\n\n // Get the joint ground anchor\n return joint.GetGroundAnchorB().get_x() * this._sharedData.worldScale;\n }\n\n getPulleyJointSecondGroundAnchorY(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2PulleyJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_pulleyJoint) {\n return 0;\n }\n\n // Get the joint ground anchor\n return joint.GetGroundAnchorB().get_y() * this._sharedData.worldScale;\n }\n\n getPulleyJointFirstLength(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2PulleyJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_pulleyJoint) {\n return 0;\n }\n\n // Get the joint length\n return joint.GetCurrentLengthA() * this._sharedData.worldScale;\n }\n\n getPulleyJointSecondLength(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2PulleyJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_pulleyJoint) {\n return 0;\n }\n\n // Get the joint length\n return joint.GetCurrentLengthB() * this._sharedData.worldScale;\n }\n\n getPulleyJointRatio(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2PulleyJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_pulleyJoint) {\n return 0;\n }\n\n // Get the joint ratio\n return joint.GetRatio();\n }\n\n // Gear joint\n addGearJoint(jointId1, jointId2, ratio, collideConnected, variable) {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Get the first joint\n const joint1 = this._sharedData.getJoint(jointId1);\n\n // Joint not found or has wrong type\n if (\n joint1 === null ||\n (joint1.GetType() !== Box2D.e_revoluteJoint &&\n joint1.GetType() !== Box2D.e_prismaticJoint)\n ) {\n return;\n }\n\n // Get the second joint\n const joint2 = this._sharedData.getJoint(jointId2);\n if (\n joint2 === null ||\n (joint2.GetType() !== Box2D.e_revoluteJoint &&\n joint2.GetType() !== Box2D.e_prismaticJoint)\n ) {\n return;\n }\n\n // The joints are the same\n if (joint1 === joint2) {\n return;\n }\n\n // Set joint settings\n const jointDef = new Box2D.b2GearJointDef();\n\n // Set gear joint bodies is not necessary at first, as the gear get the bodies from the two child joints\n // But we must pass two different bodies to bypass a test inherited from b2Joint\n jointDef.set_bodyA(this._sharedData.staticBody);\n jointDef.set_bodyB(body);\n jointDef.set_joint1(joint1);\n jointDef.set_joint2(joint2);\n jointDef.set_ratio(ratio);\n jointDef.set_collideConnected(collideConnected);\n\n // Create the joint and get the id\n const jointId = this._sharedData.addJoint(\n Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2GearJoint\n )\n );\n\n // Store the id in the variable\n variable.setNumber(jointId);\n }\n\n getGearJointFirstJoint(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2GearJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_gearJoint) {\n return 0;\n }\n\n // Get the joint first joint\n return this._sharedData.getJointId(joint.GetJoint1());\n }\n\n getGearJointSecondJoint(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2GearJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_gearJoint) {\n return 0;\n }\n\n // Get the joint second joint\n return this._sharedData.getJointId(joint.GetJoint2());\n }\n\n getGearJointRatio(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2GearJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_gearJoint) {\n return 0;\n }\n\n // Get the joint ratio\n return joint.GetRatio();\n }\n\n setGearJointRatio(jointId: integer | string, ratio: float): void {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2GearJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_gearJoint) {\n return;\n }\n\n // Set the joint ratio\n joint.SetRatio(ratio);\n\n // Awake the bodies, the gear joint picks the dynamic bodies as first and second body (second bodies from the child joints)\n joint.GetBodyA().SetAwake(true);\n joint.GetBodyB().SetAwake(true);\n }\n\n // Mouse joint\n addMouseJoint(\n targetX: float,\n targetY: float,\n maxForce: float,\n frequency: float,\n dampingRatio: float,\n variable: gdjs.Variable\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // Set joint settings\n const jointDef = new Box2D.b2MouseJointDef();\n jointDef.set_bodyA(this._sharedData.staticBody);\n jointDef.set_bodyB(body);\n jointDef.set_target(\n this.b2Vec2(\n targetX * this._sharedData.worldInvScale,\n targetY * this._sharedData.worldInvScale\n )\n );\n jointDef.set_maxForce(maxForce >= 0 ? maxForce : 0);\n jointDef.set_frequencyHz(frequency > 0 ? frequency : 1);\n jointDef.set_dampingRatio(dampingRatio >= 0 ? dampingRatio : 0);\n\n // Create the joint and get the id\n const jointId = this._sharedData.addJoint(\n Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2MouseJoint\n )\n );\n\n // Store the id in the variable\n variable.setNumber(jointId);\n }\n\n getMouseJointTargetX(jointId: integer | string): float {\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MouseJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) {\n return 0;\n }\n\n // Get the joint target X\n return joint.GetTarget().get_x() * this._sharedData.worldScale;\n }\n\n getMouseJointTargetY(jointId: integer | string): float {\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MouseJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) {\n return 0;\n }\n\n // Get the joint target Y\n return joint.GetTarget().get_y() * this._sharedData.worldScale;\n }\n\n setMouseJointTarget(\n jointId: integer | string,\n targetX: float,\n targetY: float\n ): void {\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MouseJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) {\n return;\n }\n\n // Set the joint target\n joint.SetTarget(\n this.b2Vec2(\n targetX * this._sharedData.worldInvScale,\n targetY * this._sharedData.worldInvScale\n )\n );\n\n // Awake the body\n joint.GetBodyB().SetAwake(true);\n }\n\n getMouseJointMaxForce(jointId: integer | string): float {\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MouseJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) {\n return 0;\n }\n\n // Get the joint max force\n return joint.GetMaxForce();\n }\n\n setMouseJointMaxForce(jointId: integer | string, maxForce: float): void {\n // Invalid value\n if (maxForce < 0) {\n return;\n }\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MouseJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) {\n return;\n }\n\n // Set the joint max force\n joint.SetMaxForce(maxForce);\n }\n\n getMouseJointFrequency(jointId: integer | string): float {\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MouseJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) {\n return 0;\n }\n\n // Get the joint frequency\n return joint.GetFrequency();\n }\n\n setMouseJointFrequency(jointId: integer | string, frequency: float): void {\n // Invalid value\n if (frequency <= 0) {\n return;\n }\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MouseJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) {\n return;\n }\n\n // Set the joint frequency\n joint.SetFrequency(frequency);\n }\n\n getMouseJointDampingRatio(jointId: integer | string): float {\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MouseJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) {\n return 0;\n }\n\n // Get the joint damping ratio\n return joint.GetDampingRatio();\n }\n\n setMouseJointDampingRatio(\n jointId: integer | string,\n dampingRatio: float\n ): void {\n // Invalid value\n if (dampingRatio < 0) {\n return;\n }\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MouseJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_mouseJoint) {\n return;\n }\n\n // Set the joint damping ratio\n joint.SetDampingRatio(dampingRatio);\n }\n\n // Wheel joint\n addWheelJoint(\n x1: float,\n y1: float,\n other: gdjs.RuntimeObject | null,\n x2: float,\n y2: float,\n axisAngle: float,\n frequency: float,\n dampingRatio: float,\n enableMotor: boolean,\n motorSpeed: float,\n maxMotorTorque: float,\n collideConnected: boolean,\n variable: gdjs.Variable\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // If there is no second object or it doesn't share the behavior, return\n if (other == null || !other.hasBehavior(this.name)) {\n return;\n }\n\n // Get the second body\n const otherBody = (\n other.getBehavior(this.name) as gdjs.Physics2RuntimeBehavior\n ).getBody();\n\n // If the first and second objects/bodies are the same, return\n if (this._body === otherBody) {\n return;\n }\n\n // Set joint settings\n const jointDef = new Box2D.b2WheelJointDef();\n jointDef.set_bodyA(body);\n jointDef.set_localAnchorA(\n body.GetLocalPoint(\n this.b2Vec2(\n x1 * this._sharedData.worldInvScale,\n y1 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_bodyB(otherBody);\n jointDef.set_localAnchorB(\n otherBody.GetLocalPoint(\n this.b2Vec2(\n x2 * this._sharedData.worldInvScale,\n y2 * this._sharedData.worldInvScale\n )\n )\n );\n axisAngle = gdjs.toRad(axisAngle) - body.GetAngle();\n jointDef.set_localAxisA(\n this.b2Vec2(Math.cos(axisAngle), Math.sin(axisAngle))\n );\n jointDef.set_frequencyHz(frequency > 0 ? frequency : 1);\n jointDef.set_dampingRatio(dampingRatio >= 0 ? dampingRatio : 0);\n jointDef.set_enableMotor(enableMotor);\n jointDef.set_motorSpeed(gdjs.toRad(motorSpeed));\n jointDef.set_maxMotorTorque(maxMotorTorque);\n jointDef.set_collideConnected(collideConnected);\n\n // Create the joint and get the id\n const jointId = this._sharedData.addJoint(\n Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2WheelJoint\n )\n );\n\n // Store the id in the variable\n variable.setNumber(jointId);\n }\n\n getWheelJointAxisAngle(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return 0;\n }\n\n // Get the joint axis angle\n return gdjs.toDegrees(\n Math.atan2(\n joint.GetLocalAxisA().get_y(),\n joint.GetLocalAxisA().get_x()\n ) + joint.GetBodyA().GetAngle()\n );\n }\n\n getWheelJointTranslation(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return 0;\n }\n\n // Get the joint current translation\n return joint.GetJointTranslation() * this._sharedData.worldScale;\n }\n\n getWheelJointSpeed(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return 0;\n }\n\n // Get the joint speed\n return gdjs.toDegrees(joint.GetJointSpeed());\n }\n\n isWheelJointMotorEnabled(jointId: integer | string): boolean {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return false;\n }\n\n // Get the joint motor state\n return joint.IsMotorEnabled();\n }\n\n enableWheelJointMotor(jointId: integer | string, enable): void {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return;\n }\n\n // Set the joint motor state\n joint.EnableMotor(enable);\n }\n\n getWheelJointMotorSpeed(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return 0;\n }\n\n // Get the joint motor speed\n return gdjs.toDegrees(joint.GetMotorSpeed());\n }\n\n setWheelJointMotorSpeed(jointId: integer | string, speed): void {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return;\n }\n\n // Set the joint motor speed\n joint.SetMotorSpeed(gdjs.toRad(speed));\n }\n\n getWheelJointMaxMotorTorque(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return 0;\n }\n\n // Get the joint max motor torque\n return joint.GetMaxMotorTorque();\n }\n\n setWheelJointMaxMotorTorque(\n jointId: integer | string,\n maxTorque: float\n ): void {\n // Invalid value\n if (maxTorque < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return;\n }\n\n // Set the joint max motor torque\n joint.SetMaxMotorTorque(maxTorque);\n }\n\n getWheelJointMotorTorque(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return 0;\n }\n\n // Get the joint motor torque\n return joint.GetMotorTorque(1 / this._sharedData.timeStep);\n }\n\n getWheelJointFrequency(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return 0;\n }\n\n // Get the joint frequency\n return joint.GetSpringFrequencyHz();\n }\n\n setWheelJointFrequency(jointId: integer | string, frequency): void {\n // Invalid value\n if (frequency < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return;\n }\n\n // Set the joint frequency\n joint.SetSpringFrequencyHz(frequency);\n }\n\n getWheelJointDampingRatio(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return 0;\n }\n\n // Get the joint damping ratio\n return joint.GetSpringDampingRatio();\n }\n\n setWheelJointDampingRatio(jointId: integer | string, dampingRatio): void {\n // Invalid value\n if (dampingRatio < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WheelJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_wheelJoint) {\n return;\n }\n\n // Set the joint damping ratio\n joint.SetSpringDampingRatio(dampingRatio);\n }\n\n // Weld joint\n addWeldJoint(\n x1: float,\n y1: float,\n other: gdjs.RuntimeObject | null,\n x2: float,\n y2: float,\n referenceAngle: float,\n frequency: float,\n dampingRatio: float,\n collideConnected: boolean,\n variable: gdjs.Variable\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n\n // If there is no second object or it doesn't share the behavior, return\n if (other == null || !other.hasBehavior(this.name)) {\n return;\n }\n\n // Get the second body\n const otherBody = (\n other.getBehavior(this.name) as gdjs.Physics2RuntimeBehavior\n ).getBody();\n\n // If the first and second objects/bodies are the same, return\n if (this._body === otherBody) {\n return;\n }\n const body = this._body!;\n\n // Set joint settings\n const jointDef = new Box2D.b2WeldJointDef();\n jointDef.set_bodyA(body);\n jointDef.set_localAnchorA(\n body.GetLocalPoint(\n this.b2Vec2(\n x1 * this._sharedData.worldInvScale,\n y1 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_bodyB(otherBody);\n jointDef.set_localAnchorB(\n otherBody.GetLocalPoint(\n this.b2Vec2(\n x2 * this._sharedData.worldInvScale,\n y2 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_referenceAngle(gdjs.toRad(referenceAngle));\n jointDef.set_frequencyHz(frequency > 0 ? frequency : 1);\n jointDef.set_dampingRatio(dampingRatio >= 0 ? dampingRatio : 0);\n jointDef.set_collideConnected(collideConnected);\n\n // Create the joint\n const joint = Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2WeldJoint\n );\n\n // @ts-ignore b2WeldJoint.GetReferenceAngle() is not binded, store it manually\n joint.referenceAngle = jointDef.get_referenceAngle();\n\n // Store the id in the variable\n variable.setNumber(this._sharedData.addJoint(joint));\n }\n\n getWeldJointReferenceAngle(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WeldJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_weldJoint) {\n return 0;\n }\n\n // @ts-ignore b2WeldJoint.GetReferenceAngle() is not binded\n return gdjs.toDegrees(joint.referenceAngle);\n // return gdjs.toDegrees(joint.GetReferenceAngle());\n }\n\n getWeldJointFrequency(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WeldJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_weldJoint) {\n return 0;\n }\n\n // Get the joint frequency\n return joint.GetFrequency();\n }\n\n setWeldJointFrequency(jointId: integer | string, frequency: float): void {\n // Invalid value\n if (frequency < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WeldJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_weldJoint) {\n return;\n }\n\n // Set the joint frequency\n joint.SetFrequency(frequency);\n }\n\n getWeldJointDampingRatio(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WeldJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_weldJoint) {\n return 0;\n }\n\n // Get the joint damping ratio\n return joint.GetDampingRatio();\n }\n\n setWeldJointDampingRatio(\n jointId: integer | string,\n dampingRatio: float\n ): void {\n // Invalid value\n if (dampingRatio < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2WeldJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_weldJoint) {\n return;\n }\n\n // Set the joint damping ratio\n joint.SetDampingRatio(dampingRatio);\n }\n\n // Rope joint\n addRopeJoint(\n x1: float,\n y1: float,\n other: gdjs.RuntimeObject | null,\n x2: float,\n y2: float,\n maxLength: float,\n collideConnected: boolean,\n variable: gdjs.Variable\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // If there is no second object or it doesn't share the behavior, return\n if (other == null || !other.hasBehavior(this.name)) {\n return;\n }\n\n // Get the second body\n const otherBody = (\n other.getBehavior(this.name) as gdjs.Physics2RuntimeBehavior\n ).getBody();\n\n // If the first and second objects/bodies are the same, return\n if (this._body === otherBody) {\n return;\n }\n\n // Set joint settings\n const jointDef = new Box2D.b2RopeJointDef();\n jointDef.set_bodyA(body);\n jointDef.set_localAnchorA(\n body.GetLocalPoint(\n this.b2Vec2(\n x1 * this._sharedData.worldInvScale,\n y1 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_bodyB(otherBody);\n jointDef.set_localAnchorB(\n otherBody.GetLocalPoint(\n this.b2Vec2(\n x2 * this._sharedData.worldInvScale,\n y2 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_maxLength(\n maxLength > 0\n ? maxLength * this._sharedData.worldInvScale\n : this.b2Vec2(\n (x2 - x1) * this._sharedData.worldInvScale,\n (y2 - y1) * this._sharedData.worldInvScale\n ).Length()\n );\n jointDef.set_collideConnected(collideConnected);\n\n // Create the joint and get the id\n const jointId = this._sharedData.addJoint(\n Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2RopeJoint\n )\n );\n\n // Store the id in the variable\n variable.setNumber(jointId);\n }\n\n getRopeJointMaxLength(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RopeJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_ropeJoint) {\n return 0;\n }\n\n // Get the joint maximum length\n return joint.GetMaxLength() * this._sharedData.worldScale;\n }\n\n setRopeJointMaxLength(jointId: integer | string, maxLength: float): void {\n // Invalid value\n if (maxLength < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2RopeJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_ropeJoint) {\n return;\n }\n\n // Set the joint maximum length\n joint.SetMaxLength(maxLength * this._sharedData.worldInvScale);\n\n // Awake the bodies\n joint.GetBodyA().SetAwake(true);\n joint.GetBodyB().SetAwake(true);\n }\n\n // Friction joint\n addFrictionJoint(\n x1: float,\n y1: float,\n other: gdjs.RuntimeObject | null,\n x2: float,\n y2: float,\n maxForce: float,\n maxTorque: float,\n collideConnected: boolean,\n variable: gdjs.Variable\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n\n // If there is no second object or it doesn't share the behavior, return\n if (other == null || !other.hasBehavior(this.name)) {\n return;\n }\n\n // Get the second body\n const otherBody = (\n other.getBehavior(this.name) as gdjs.Physics2RuntimeBehavior\n ).getBody();\n\n // If the first and second objects/bodies are the same, return\n if (this._body === otherBody) {\n return;\n }\n const body = this._body!;\n\n // Set joint settings\n const jointDef = new Box2D.b2FrictionJointDef();\n jointDef.set_bodyA(body);\n jointDef.set_localAnchorA(\n body.GetLocalPoint(\n this.b2Vec2(\n x1 * this._sharedData.worldInvScale,\n y1 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_bodyB(otherBody);\n jointDef.set_localAnchorB(\n otherBody.GetLocalPoint(\n this.b2Vec2(\n x2 * this._sharedData.worldInvScale,\n y2 * this._sharedData.worldInvScale\n )\n )\n );\n jointDef.set_maxForce(maxForce >= 0 ? maxForce : 0);\n jointDef.set_maxTorque(maxTorque >= 0 ? maxTorque : 0);\n jointDef.set_collideConnected(collideConnected);\n\n // Create the joint and get the id\n const jointId = this._sharedData.addJoint(\n Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2FrictionJoint\n )\n );\n\n // Store the id in the variable\n variable.setNumber(jointId);\n }\n\n getFrictionJointMaxForce(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2FrictionJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_frictionJoint) {\n return 0;\n }\n\n // Get the joint maximum force\n return joint.GetMaxForce();\n }\n\n setFrictionJointMaxForce(jointId: integer | string, maxForce: float): void {\n // Invalid value\n if (maxForce < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2FrictionJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_frictionJoint) {\n return;\n }\n\n // Set the joint maximum force\n joint.SetMaxForce(maxForce);\n }\n\n getFrictionJointMaxTorque(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2FrictionJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_frictionJoint) {\n return 0;\n }\n\n // Get the joint maximum torque\n return joint.GetMaxTorque();\n }\n\n setFrictionJointMaxTorque(\n jointId: integer | string,\n maxTorque: float\n ): void {\n // Invalid value\n if (maxTorque < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2FrictionJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_frictionJoint) {\n return;\n }\n\n // Set the joint maximum torque\n joint.SetMaxTorque(maxTorque);\n }\n\n // Motor joint\n addMotorJoint(\n other: gdjs.RuntimeObject | null,\n offsetX: float,\n offsetY: float,\n offsetAngle: float,\n maxForce: float,\n maxTorque: float,\n correctionFactor: float,\n collideConnected: boolean,\n variable: gdjs.Variable\n ): void {\n // If there is no body, set a new one\n if (this._body === null) {\n if (!this.createBody()) return;\n }\n const body = this._body!;\n\n // If there is no second object or it doesn't share the behavior, return\n if (other == null || !other.hasBehavior(this.name)) {\n return;\n }\n\n // Get the second body\n const otherBody = (\n other.getBehavior(this.name) as gdjs.Physics2RuntimeBehavior\n ).getBody();\n\n // If the first and second objects/bodies are the same, return\n if (this._body === otherBody) {\n return;\n }\n\n // Set joint settings\n const jointDef = new Box2D.b2MotorJointDef();\n jointDef.set_bodyA(body);\n jointDef.set_bodyB(otherBody);\n jointDef.set_linearOffset(\n this.b2Vec2(\n offsetX * this._sharedData.worldInvScale,\n offsetY * this._sharedData.worldInvScale\n )\n );\n jointDef.set_angularOffset(gdjs.toRad(offsetAngle));\n jointDef.set_maxForce(maxForce >= 0 ? maxForce : 0);\n jointDef.set_maxTorque(maxTorque >= 0 ? maxTorque : 0);\n jointDef.set_correctionFactor(\n correctionFactor < 0 ? 0 : correctionFactor > 1 ? 1 : correctionFactor\n );\n jointDef.set_collideConnected(collideConnected);\n\n // Create the joint and get the id\n const jointId = this._sharedData.addJoint(\n Box2D.castObject(\n this._sharedData.world.CreateJoint(jointDef),\n Box2D.b2MotorJoint\n )\n );\n\n // Store the id in the variable\n variable.setNumber(jointId);\n }\n\n getMotorJointOffsetX(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MotorJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_motorJoint) {\n return 0;\n }\n\n // Get the joint offset\n return joint.GetLinearOffset().get_x() * this._sharedData.worldScale;\n }\n\n getMotorJointOffsetY(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MotorJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_motorJoint) {\n return 0;\n }\n\n // Get the joint offset\n return joint.GetLinearOffset().get_y() * this._sharedData.worldScale;\n }\n\n setMotorJointOffset(\n jointId: integer | string,\n offsetX: float,\n offsetY: float\n ): void {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MotorJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_motorJoint) {\n return;\n }\n\n // Set the joint offset\n joint.SetLinearOffset(\n this.b2Vec2(\n offsetX * this._sharedData.worldInvScale,\n offsetY * this._sharedData.worldInvScale\n )\n );\n }\n\n getMotorJointAngularOffset(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MotorJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_motorJoint) {\n return 0;\n }\n\n // Get the joint angular offset\n return gdjs.toDegrees(joint.GetAngularOffset());\n }\n\n setMotorJointAngularOffset(\n jointId: integer | string,\n offsetAngle: float\n ): void {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MotorJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_motorJoint) {\n return;\n }\n\n // Set the joint angular offset\n joint.SetAngularOffset(gdjs.toRad(offsetAngle));\n }\n\n getMotorJointMaxForce(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MotorJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_motorJoint) {\n return 0;\n }\n\n // Get the joint maximum force\n return joint.GetMaxForce();\n }\n\n setMotorJointMaxForce(jointId: integer | string, maxForce: float): void {\n // Invalid value\n if (maxForce < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MotorJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_motorJoint) {\n return;\n }\n\n // Set the joint maximum force\n joint.SetMaxForce(maxForce);\n }\n\n getMotorJointMaxTorque(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MotorJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_motorJoint) {\n return 0;\n }\n\n // Get the joint maximum torque\n return joint.GetMaxTorque();\n }\n\n setMotorJointMaxTorque(jointId: integer | string, maxTorque: float): void {\n // Invalid value\n if (maxTorque < 0) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MotorJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_motorJoint) {\n return;\n }\n\n // Set the joint maximum torque\n joint.SetMaxTorque(maxTorque);\n\n // Awake the bodies\n joint.GetBodyA().SetAwake(true);\n joint.GetBodyB().SetAwake(true);\n }\n\n getMotorJointCorrectionFactor(jointId: integer | string): float {\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MotorJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_motorJoint) {\n return 0;\n }\n\n // Get the joint correction factor\n return joint.GetCorrectionFactor();\n }\n\n setMotorJointCorrectionFactor(\n jointId: integer | string,\n correctionFactor: float\n ): void {\n // Invalid value\n if (correctionFactor < 0 || correctionFactor > 1) {\n return;\n }\n\n // Get the joint\n const joint = this._sharedData.getJoint(jointId) as Box2D.b2MotorJoint;\n\n // Joint not found or has wrong type\n if (joint === null || joint.GetType() !== Box2D.e_motorJoint) {\n return;\n }\n\n // Set the joint correction factor\n joint.SetCorrectionFactor(correctionFactor);\n\n // Awake the bodies\n joint.GetBodyA().SetAwake(true);\n joint.GetBodyB().SetAwake(true);\n }\n\n onContactBegin(otherBehavior: Physics2RuntimeBehavior): void {\n this.currentContacts.push(otherBehavior);\n\n // There might be contacts that end during the frame and\n // start again right away. It is considered a glitch\n // and should not be detected.\n let i = this.contactsEndedThisFrame.indexOf(otherBehavior);\n if (i !== -1) {\n this.contactsEndedThisFrame.splice(i, 1);\n } else {\n this.contactsStartedThisFrame.push(otherBehavior);\n }\n }\n\n onContactEnd(otherBehavior: Physics2RuntimeBehavior): void {\n this.contactsEndedThisFrame.push(otherBehavior);\n\n const index = this.currentContacts.indexOf(otherBehavior);\n if (index !== -1) {\n this.currentContacts.splice(index, 1);\n }\n }\n\n /**\n * @deprecated Prefer using `Physics2RuntimeBehavior.areObjectsColliding`.\n */\n static collisionTest = Physics2RuntimeBehavior.areObjectsColliding;\n\n static areObjectsColliding(\n object1: gdjs.RuntimeObject,\n object2: gdjs.RuntimeObject,\n behaviorName: string\n ): boolean {\n // Test if the second object is in the list of contacts of the first one\n const behavior1 = object1.getBehavior(\n behaviorName\n ) as Physics2RuntimeBehavior | null;\n if (!behavior1) return false;\n\n if (\n behavior1.currentContacts.some((behavior) => behavior.owner === object2)\n ) {\n return true;\n }\n // If a contact has started at this frame and ended right away, it\n // won't appear in current contacts but the condition should return\n // true anyway.\n if (\n behavior1.contactsStartedThisFrame.some(\n (behavior) => behavior.owner === object2\n )\n ) {\n return true;\n }\n\n // No contact found\n return false;\n }\n\n static hasCollisionStartedBetween(\n object1: gdjs.RuntimeObject,\n object2: gdjs.RuntimeObject,\n behaviorName: string\n ): boolean {\n // Test if the second object is in the list of contacts of the first one\n const behavior1 = object1.getBehavior(\n behaviorName\n ) as Physics2RuntimeBehavior | null;\n if (!behavior1) return false;\n\n return behavior1.contactsStartedThisFrame.some(\n (behavior) => behavior.owner === object2\n );\n }\n\n static hasCollisionStoppedBetween(\n object1: gdjs.RuntimeObject,\n object2: gdjs.RuntimeObject,\n behaviorName: string\n ): boolean {\n // Test if the second object is in the list of contacts of the first one\n const behavior1 = object1.getBehavior(\n behaviorName\n ) as Physics2RuntimeBehavior | null;\n if (!behavior1) return false;\n\n return behavior1.contactsEndedThisFrame.some(\n (behavior) => behavior.owner === object2\n );\n }\n }\n gdjs.registerBehavior(\n 'Physics2::Physics2Behavior',\n gdjs.Physics2RuntimeBehavior\n );\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|