### Activate and Serve Forge2D Project Source: https://github.com/flame-engine/forge2d/blob/main/packages/forge2d/example/README.md Commands to install the webdev tool and launch the development server. The server can be run in standard mode for development or release mode for optimized performance. ```bash pub global activate webdev pub global run webdev serve ``` ```bash pub global run webdev serve --release ``` -------------------------------- ### Install webdev Package Source: https://github.com/flame-engine/forge2d/blob/main/packages/benchmark/README.md Installs the webdev package globally, which is required for serving and building web applications, including benchmarks. ```sh dart pub global activate webdev ``` -------------------------------- ### Serve Browser Benchmark Source: https://github.com/flame-engine/forge2d/blob/main/packages/benchmark/README.md Starts a local web server to run the Forge2D benchmarks in a browser environment using webdev. Access the benchmarks by navigating to the specified URL. ```sh dart pub global run webdev serve --release ``` -------------------------------- ### Implement Physics World and Game Logic in Forge2D Source: https://context7.com/flame-engine/forge2d/llms.txt This example demonstrates the full lifecycle of a Forge2D physics simulation, including world initialization, body creation, joint configuration, and collision detection. It uses a custom ContactListener to process game-specific events and provides methods for player movement and simulation stepping. ```dart import 'package:forge2d/forge2d.dart'; import 'dart:math'; class PhysicsGame { late World world; late Body player; final List enemies = []; void initialize() { world = World(Vector2(0.0, -10.0)); world.setAllowSleep(true); world.setContactListener(GameContactListener()); _createGround(); _createPlayer(); for (var i = 0; i < 5; i++) { _createEnemy(Vector2(-10.0 + i * 5, 15.0)); } _createRotatingPlatform(); } void _createGround() { final groundDef = BodyDef(position: Vector2(0.0, -10.0)); final ground = world.createBody(groundDef); final groundShape = PolygonShape()..setAsBoxXY(50.0, 10.0); ground.createFixtureFromShape(groundShape, friction: 0.8); final terrain = ChainShape(); terrain.createChain([ Vector2(-30.0, 10.0), Vector2(-20.0, 12.0), Vector2(-10.0, 10.0), Vector2(0.0, 11.0), Vector2(10.0, 10.0), Vector2(20.0, 13.0), Vector2(30.0, 10.0), ]); ground.createFixtureFromShape(terrain, friction: 0.5); } void _createPlayer() { final playerDef = BodyDef( type: BodyType.dynamic, position: Vector2(0.0, 5.0), fixedRotation: true, ); player = world.createBody(playerDef); player.userData = 'player'; final bodyShape = PolygonShape()..setAsBoxXY(0.5, 1.0); final fixtureDef = FixtureDef( bodyShape, density: 1.0, friction: 0.3, filter: Filter()..categoryBits = 0x0001..maskBits = 0xFFFF, ); player.createFixture(fixtureDef); } void _createEnemy(Vector2 position) { final enemyDef = BodyDef(type: BodyType.dynamic, position: position); final enemy = world.createBody(enemyDef); enemy.userData = 'enemy'; final shape = CircleShape(radius: 1.0); final fixtureDef = FixtureDef( shape, density: 0.5, friction: 0.3, restitution: 0.4, filter: Filter()..categoryBits = 0x0002..maskBits = 0xFFFF, ); enemy.createFixture(fixtureDef); enemies.add(enemy); } void _createRotatingPlatform() { final anchor = world.createBody(BodyDef(position: Vector2(15.0, 10.0))); final platformDef = BodyDef(type: BodyType.dynamic, position: Vector2(15.0, 10.0)); final platform = world.createBody(platformDef); final platformShape = PolygonShape()..setAsBoxXY(5.0, 0.3); platform.createFixtureFromShape(platformShape, density: 2.0); final jointDef = RevoluteJointDef() ..initialize(platform, anchor, platform.position) ..enableMotor = true ..motorSpeed = pi / 2 ..maxMotorTorque = 10000.0; world.createJoint(RevoluteJoint(jointDef)); } void movePlayer(Vector2 direction) { player.applyLinearImpulse(direction * 5.0); final velocity = player.linearVelocity; final maxSpeed = 10.0; if (velocity.length > maxSpeed) { velocity.normalize(); velocity.scale(maxSpeed); player.linearVelocity = velocity; } } void jump() { player.applyLinearImpulse(Vector2(0.0, 20.0)); } void update(double dt) { world.stepDt(dt); } } class GameContactListener extends ContactListener { @override void beginContact(Contact contact) { final userDataA = contact.fixtureA.body.userData; final userDataB = contact.fixtureB.body.userData; if ((userDataA == 'player' && userDataB == 'enemy') || (userDataA == 'enemy' && userDataB == 'player')) { print('Player collided with enemy!'); } } @override void postSolve(Contact contact, ContactImpulse impulse) { final maxImpulse = impulse.normalImpulses.fold(0, max); if (maxImpulse > 50.0) { print('High impact collision: $maxImpulse'); } } } void main() { final game = PhysicsGame(); game.initialize(); const dt = 1.0 / 60.0; for (var i = 0; i < 300; i++) { game.update(dt); if (i % 60 == 0) { print('Player position: ${game.player.position}'); } } } ``` -------------------------------- ### Implement ContactListener for Collision Events in Dart Source: https://context7.com/flame-engine/forge2d/llms.txt This Dart code demonstrates how to implement the ContactListener interface to handle collision events such as the start and end of contact, pre-solve adjustments, and post-solve impulse analysis. It allows for custom game logic based on these physics interactions. ```dart import 'package:forge2d/forge2d.dart'; class GameContactListener extends ContactListener { @override void beginContact(Contact contact) { // Called when two fixtures begin touching final fixtureA = contact.fixtureA; final fixtureB = contact.fixtureB; final bodyA = fixtureA.body; final bodyB = fixtureB.body; print('Collision started between bodies at ${bodyA.position} and ${bodyB.position}'); // Access user data for game logic if (bodyA.userData == 'player' && bodyB.userData == 'enemy') { print('Player hit enemy!'); } } @override void endContact(Contact contact) { // Called when two fixtures stop touching print('Collision ended'); } @override void preSolve(Contact contact, Manifold oldManifold) { // Called before collision response is calculated // You can disable the contact here if (shouldIgnoreCollision(contact)) { contact.isEnabled = false; } } @override void postSolve(Contact contact, ContactImpulse impulse) { // Called after collision is solved // Access impulse magnitudes for impact effects for (var i = 0; i < impulse.normalImpulses.length; i++) { final impactForce = impulse.normalImpulses[i]; if (impactForce > 10.0) { print('Hard impact: $impactForce'); } } } bool shouldIgnoreCollision(Contact contact) => false; } // Register the contact listener with the world final listener = GameContactListener(); world.setContactListener(listener); ``` -------------------------------- ### Raycast - Find Fixtures Along a Line Source: https://context7.com/flame-engine/forge2d/llms.txt Explains how to cast a ray through the world to find fixtures intersected by a line segment. ```APIDOC ## Raycast ### Description Cast a ray through the world to find fixtures intersected by the ray. Useful for line-of-sight and shooting mechanics. ### Method world.raycast(callback, point1, point2) ### Parameters #### Path Parameters - **callback** (RayCastCallback) - Required - Implementation of reportFixture to handle hit data. - **point1** (Vector2) - Required - Start point of the ray. - **point2** (Vector2) - Required - End point of the ray. ### Request Example final point1 = Vector2(0.0, 10.0); final point2 = Vector2(10.0, 10.0); world.raycast(myCallback, point1, point2); ``` -------------------------------- ### Dynamic Demo Loader Utility Source: https://github.com/flame-engine/forge2d/blob/main/packages/forge2d/example/web/index.html This JavaScript function retrieves query parameters from the browser URL to determine which physics demo to load. It dynamically injects the required Dart-compiled JavaScript file into the document body or generates a navigation menu if no valid demo is specified. ```javascript var demos = ['ball_cage', 'blob_test', 'box_test', 'circle_stress', 'domino_test', 'domino_tower', 'friction_joint_test', 'particles', 'racer']; function getQueryVariable(variable) { var query = window.location.search.substring(1); var vars = query.split('&'); for (var i = 0; i < vars.length; i++) { var pair = vars[i].split('='); if (pair[0] == variable) { return unescape(pair[1]); } } return null; } var demo = getQueryVariable('demo'); if (demo && demos.indexOf(demo) != -1) { var script = document.createElement('script'); script.setAttribute('defer', ''); script.setAttribute('src', demo + '.dart.js'); document.body.appendChild(script); } else { var menu = document.createElement('ul'); for (var d in demos) { var item = document.createElement('li'); var link = document.createElement('a'); link.setAttribute('href', window.location.href + '?demo=' + demos[d]); link.appendChild(document.createTextNode(demos[d])); item.appendChild(link); menu.appendChild(item); } document.body.appendChild(menu); } ``` -------------------------------- ### AABB Query - Find Fixtures in Region Source: https://context7.com/flame-engine/forge2d/llms.txt Explains how to query the world to find all fixtures that overlap with a specific axis-aligned bounding box. ```APIDOC ## AABB Query ### Description Query the world to find all fixtures that potentially overlap with an axis-aligned bounding box (AABB). ### Method world.queryAABB(callback, aabb) ### Parameters #### Path Parameters - **callback** (QueryCallback) - Required - Implementation of reportFixture to handle found fixtures. - **aabb** (AABB) - Required - The region to search for fixtures. ### Request Example final aabb = AABB(); aabb.lowerBound.setValues(-5.0, -5.0); aabb.upperBound.setValues(5.0, 5.0); world.queryAABB(myCallback, aabb); ``` -------------------------------- ### BodyDef - Body Definition Source: https://context7.com/flame-engine/forge2d/llms.txt BodyDef holds the configuration data required to create a Body, allowing for reusable definitions across multiple physics entities. ```APIDOC ## BodyDef - Body Definition ### Description BodyDef is a configuration object used to define the initial state and physical properties of a body before it is added to the world. ### Method N/A (Class-based API) ### Endpoint forge2d.BodyDef ### Parameters #### Configuration Fields - **type** (BodyType) - Required - The type of body: static, dynamic, or kinematic. - **position** (Vector2) - Optional - The initial world position. - **linearVelocity** (Vector2) - Optional - The initial linear velocity. - **gravityScale** (Vector2) - Optional - Multiplier for gravity applied to this body. ### Request Example final bodyDef = BodyDef(type: BodyType.dynamic, position: Vector2(5.0, 10.0)); ### Response #### Success Response - **bodyDef** (BodyDef) - A configured definition object ready for world.createBody(). ``` -------------------------------- ### Configure FixtureDef Properties Source: https://context7.com/flame-engine/forge2d/llms.txt Details how to link shapes to bodies using FixtureDef, including setting physical properties like density, friction, restitution, and collision filtering via category and mask bits. ```dart import 'package:forge2d/forge2d.dart'; final shape = CircleShape(radius: 1.0); final fixtureDef = FixtureDef( shape, density: 2.0, friction: 0.4, restitution: 0.6, isSensor: false, filter: Filter()..categoryBits = 0x0002..maskBits = 0x0001..groupIndex = 0, ); final bodyDef = BodyDef(type: BodyType.dynamic, position: Vector2(0.0, 10.0)); final body = world.createBody(bodyDef); final fixture = body.createFixture(fixtureDef); final sensorDef = FixtureDef(PolygonShape()..setAsBoxXY(5.0, 5.0), isSensor: true); body.createFixture(sensorDef); ``` -------------------------------- ### Run Terminal Benchmark Source: https://github.com/flame-engine/forge2d/blob/main/packages/benchmark/README.md Executes the Forge2D benchmarks directly in the terminal. This command runs the specified Dart script for benchmarking purposes. ```sh dart web/bench2d.dart ``` -------------------------------- ### World - Physics Simulation Container Source: https://context7.com/flame-engine/forge2d/llms.txt The World class is the central manager for all physics entities, handling the simulation loop, collision detection, and constraint solving. ```APIDOC ## World - Physics Simulation Container ### Description The World class acts as the central container for all physics entities including bodies, joints, and contacts. It manages the simulation lifecycle, including stepping the physics forward and cleaning up resources. ### Method N/A (Class-based API) ### Endpoint forge2d.World ### Parameters #### Constructor Parameters - **gravity** (Vector2) - Required - The gravitational force applied to the world. ### Request Example final world = World(Vector2(0.0, -10.0)); ### Response #### Success Response - **world** (World) - An initialized physics world instance. ``` -------------------------------- ### Forge2D Raycast - Find Fixtures Along a Line Source: https://context7.com/flame-engine/forge2d/llms.txt Casts a ray through the physics world to detect fixtures intersected by the ray. This method is ideal for implementing features like line-of-sight checks, shooting mechanics, or object selection. The callback allows for precise control over ray behavior and identification of the closest hit. ```dart import 'package:forge2d/forge2d.dart'; // Define raycast callback class MyRayCastCallback extends RayCastCallback { Fixture? closestFixture; Vector2? hitPoint; Vector2? hitNormal; double closestFraction = 1.0; @override double reportFixture(Fixture fixture, Vector2 point, Vector2 normal, double fraction) { // Return values control ray behavior: // -1: ignore this fixture, continue // 0: terminate the ray cast // fraction: clip ray to this point // 1: don't clip, continue if (fraction < closestFraction) { closestFraction = fraction; closestFixture = fixture; hitPoint = point.clone(); hitNormal = normal.clone(); } return fraction; // Clip to closest hit so far } } // Cast ray from point1 to point2 final point1 = Vector2(0.0, 10.0); final point2 = Vector2(10.0, 10.0); final callback = MyRayCastCallback(); world.raycast(callback, point1, point2); if (callback.closestFixture != null) { print('Hit fixture at: ${callback.hitPoint}'); print('Surface normal: ${callback.hitNormal}'); print('Hit body: ${callback.closestFixture!.body.position}'); } ``` -------------------------------- ### Forge2D: World - Physics Simulation Container (Dart) Source: https://context7.com/flame-engine/forge2d/llms.txt The World class manages all physics entities, the simulation loop, collision detection, and constraint solving. It requires a gravity vector and can be configured with settings like allowing bodies to sleep. The simulation is advanced using `stepDt`. ```dart import 'package:forge2d/forge2d.dart'; // Create a world with gravity pointing downward final gravity = Vector2(0.0, -10.0); final world = World(gravity); // Configure world settings world.setAllowSleep(true); // Allow bodies to sleep when stationary // Step the simulation forward (typically called each frame) // dt is the time delta in seconds (e.g., 1/60 for 60 FPS) void update(double dt) { world.stepDt(dt); } // Access all bodies in the world for (final body in world.bodies) { print('Body at position: ${body.position}'); } // Clean up - destroy all bodies when done for (final body in world.bodies.toList()) { world.destroyBody(body); } ``` -------------------------------- ### Define PolygonShape for Collision Source: https://context7.com/flame-engine/forge2d/llms.txt Shows how to create convex polygons, including axis-aligned boxes, rotated boxes, custom vertex-defined shapes, and edge segments. ```dart import 'package:forge2d/forge2d.dart'; import 'dart:math'; final box = PolygonShape(); box.setAsBoxXY(2.0, 1.0); final rotatedBox = PolygonShape(); rotatedBox.setAsBox(1.5, 0.5, Vector2(2.0, 0.0), pi / 4); final customShape = PolygonShape(); customShape.set([ Vector2(-1.0, -1.0), Vector2(1.0, -1.0), Vector2(1.5, 0.0), Vector2(1.0, 1.0), Vector2(-1.0, 1.0), ]); final edge = PolygonShape(); edge.setAsEdge(Vector2(-10.0, 0.0), Vector2(10.0, 0.0)); final bodyDef = BodyDef(type: BodyType.dynamic, position: Vector2(0.0, 15.0)); final body = world.createBody(bodyDef); final fixtureDef = FixtureDef(box, density: 1.0, friction: 0.6, restitution: 0.3); body.createFixture(fixtureDef); ``` -------------------------------- ### Check Dart Support in Browser (JavaScript) Source: https://github.com/flame-engine/forge2d/blob/main/packages/benchmark/web/index.html This snippet checks the user agent string to determine if the browser supports Dart. It logs a message indicating whether Dart is supported or if a JavaScript fallback is expected. This is useful for optimizing performance by leveraging Dart when available. ```javascript console.log('Loading Bench2d'); if(navigator.userAgent.indexOf('(Dart)') != -1) { console.log('Dart supported. High-five!'); } else { console.log('Browser does not support Dart. Expect JS fallback.'); } ``` -------------------------------- ### FixtureDef - Fixture Definition Source: https://context7.com/flame-engine/forge2d/llms.txt Defines the physical properties of a fixture, such as density, friction, and restitution, linking a shape to a body. ```APIDOC ## FixtureDef ### Description Links a shape to a body and defines physical interaction properties. ### Parameters - **density** (double) - Optional - Affects mass calculation. - **friction** (double) - Optional - Resistance to sliding (0-1). - **restitution** (double) - Optional - Bounciness (0-1). - **isSensor** (bool) - Optional - If true, detects collisions without physical response. ``` -------------------------------- ### Body - Rigid Body Physics Object Source: https://context7.com/flame-engine/forge2d/llms.txt Body represents a rigid object in the physics world, supporting fixtures, force application, and state management. ```APIDOC ## Body - Rigid Body Physics Object ### Description Body represents a physical object within the Forge2D world. It can have shapes attached via fixtures and responds to forces, impulses, and collisions. ### Method N/A (Class-based API) ### Endpoint forge2d.Body ### Parameters #### Methods - **applyForce** (Vector2, [Vector2]) - Applies a force to the body. - **applyLinearImpulse** (Vector2) - Applies an instantaneous velocity change. - **setTransform** (Vector2, double) - Sets the body's position and rotation. ### Request Example body.applyForce(Vector2(100.0, 0.0)); ### Response #### Success Response - **body** (Body) - The instance of the rigid body in the simulation. ``` -------------------------------- ### Forge2D: BodyDef - Body Definition (Dart) Source: https://context7.com/flame-engine/forge2d/llms.txt BodyDef holds configuration data for creating Bodies. It supports different body types (dynamic, static, kinematic) and properties like position, velocity, damping, and collision settings. Definitions can be reused. ```dart import 'package:forge2d/forge2d.dart'; // Create a dynamic body definition (affected by forces and gravity) final dynamicBodyDef = BodyDef( type: BodyType.dynamic, position: Vector2(5.0, 10.0), angle: 0.0, linearVelocity: Vector2(2.0, 0.0), angularVelocity: 0.5, linearDamping: 0.1, angularDamping: 0.1, allowSleep: true, isAwake: true, fixedRotation: false, bullet: false, // Enable for fast-moving objects to prevent tunneling active: true, gravityScale: Vector2(1.0, 1.0), // Scale gravity effect on this body ); // Create a static body definition (immovable, like ground) final staticBodyDef = BodyDef( type: BodyType.static, position: Vector2(0.0, -10.0), ); // Create a kinematic body (moved programmatically, not by forces) final kinematicBodyDef = BodyDef( type: BodyType.kinematic, position: Vector2(0.0, 5.0), linearVelocity: Vector2(1.0, 0.0), // Constant velocity ); // Create bodies from definitions final dynamicBody = world.createBody(dynamicBodyDef); final groundBody = world.createBody(staticBodyDef); ``` -------------------------------- ### Filter - Collision Filtering Source: https://context7.com/flame-engine/forge2d/llms.txt Explains how to control collision behavior using category bits, mask bits, and group indices. ```APIDOC ## Collision Filtering ### Description Filter controls which fixtures can collide with each other using category bits, mask bits, and group indices. ### Parameters #### Request Body - **categoryBits** (int) - Required - The category this fixture belongs to. - **maskBits** (int) - Required - The categories this fixture will collide with. - **groupIndex** (int) - Optional - Group index for objects that should always or never collide. ### Request Example final filter = Filter() ..categoryBits = 0x0001 ..maskBits = 0x0002 | 0x0008; ``` -------------------------------- ### Forge2D Collision Filtering - Category, Mask, and Group Bits Source: https://context7.com/flame-engine/forge2d/llms.txt Implements collision filtering in Forge2D using category bits, mask bits, and group indices. This allows developers to define precise rules for which fixtures can collide with each other, managing complex interactions in physics simulations. Filters are applied to fixtures to control their collision behavior. ```dart import 'package:forge2d/forge2d.dart'; // Define collision categories const int categoryPlayer = 0x0001; const int categoryEnemy = 0x0002; const int categoryBullet = 0x0004; const int categoryWall = 0x0008; // Player: collides with enemies and walls, not own bullets final playerFilter = Filter() ..categoryBits = categoryPlayer ..maskBits = categoryEnemy | categoryWall; // Enemy: collides with player, bullets, and walls final enemyFilter = Filter() ..categoryBits = categoryEnemy ..maskBits = categoryPlayer | categoryBullet | categoryWall; // Player's bullet: only collides with enemies and walls final bulletFilter = Filter() ..categoryBits = categoryBullet ..maskBits = categoryEnemy | categoryWall; // Apply filters to fixtures final playerShape = CircleShape(radius: 1.0); final playerFixtureDef = FixtureDef(playerShape, filter: playerFilter, density: 1.0); final enemyShape = CircleShape(radius: 1.0); final enemyFixtureDef = FixtureDef(enemyShape, filter: enemyFilter, density: 1.0); // Group index for objects that should never/always collide // Negative: never collide within group // Positive: always collide within group final friendlyFilter = Filter() ..groupIndex = -1 // Never collide with other group -1 fixtures ..categoryBits = categoryPlayer; ``` -------------------------------- ### Forge2D AABB Query - Find Fixtures in Region Source: https://context7.com/flame-engine/forge2d/llms.txt Queries the physics world to find all fixtures that potentially overlap with a given axis-aligned bounding box (AABB). It utilizes a callback mechanism to report found fixtures, allowing for custom processing of the results. This is useful for spatial queries and broad-phase collision detection. ```dart import 'package:forge2d/forge2d.dart'; // Define query callback class MyQueryCallback extends QueryCallback { final List foundFixtures = []; @override bool reportFixture(Fixture fixture) { foundFixtures.add(fixture); // Return true to continue searching, false to stop return true; } } // Create query AABB (search region) final aabb = AABB(); aabb.lowerBound.setValues(-5.0, -5.0); aabb.upperBound.setValues(5.0, 5.0); // Execute query final callback = MyQueryCallback(); world.queryAABB(callback, aabb); // Process results for (final fixture in callback.foundFixtures) { print('Found fixture on body at: ${fixture.body.position}'); } ``` -------------------------------- ### Define CircleShape for Collision Source: https://context7.com/flame-engine/forge2d/llms.txt Demonstrates how to create circular collision shapes, including offset positions and compound shapes by attaching multiple circles to a single body. ```dart import 'package:forge2d/forge2d.dart'; final circle = CircleShape(radius: 2.0); final offsetCircle = CircleShape( radius: 1.5, position: Vector2(2.0, 0.0), ); final bodyDef = BodyDef(type: BodyType.dynamic, position: Vector2(0.0, 10.0)); final body = world.createBody(bodyDef); body.createFixtureFromShape(circle, density: 1.0, friction: 0.3, restitution: 0.5); final body2 = world.createBody(BodyDef(type: BodyType.dynamic, position: Vector2(5.0, 10.0))); for (var i = 0; i < 5; i++) { final angle = 2 * 3.14159 * i / 5; final shape = CircleShape( radius: 0.5, position: Vector2(2.0 * cos(angle), 2.0 * sin(angle)), ); body2.createFixtureFromShape(shape, density: 1.0); } ``` -------------------------------- ### Forge2D: Body - Rigid Body Physics Object (Dart) Source: https://context7.com/flame-engine/forge2d/llms.txt A Body represents a rigid object in the physics world, capable of having shapes (fixtures) and responding to forces, impulses, and collisions. It allows direct manipulation of properties like position, velocity, and awake state, and supports coordinate transformations. ```dart import 'package:forge2d/forge2d.dart'; // Create a dynamic body final bodyDef = BodyDef( type: BodyType.dynamic, position: Vector2(0.0, 20.0), ); final body = world.createBody(bodyDef); // Attach a circle shape final circleShape = CircleShape(radius: 1.0); body.createFixtureFromShape(circleShape, density: 1.0); // Apply forces and impulses body.applyForce(Vector2(100.0, 0.0)); // Apply force at center of mass body.applyForce(Vector2(50.0, 0.0), point: Vector2(0.0, 21.0)); // Force at point body.applyTorque(10.0); // Apply rotational torque body.applyLinearImpulse(Vector2(10.0, 0.0)); // Instant velocity change body.applyAngularImpulse(5.0); // Instant angular velocity change // Get/set body properties print('Position: ${body.position}'); print('Angle: ${body.angle}'); print('Linear velocity: ${body.linearVelocity}'); print('Angular velocity: ${body.angularVelocity}'); print('Mass: ${body.mass}'); // Set linear velocity directly body.linearVelocity = Vector2(5.0, 0.0); body.angularVelocity = 1.0; // Transform body position and rotation body.setTransform(Vector2(10.0, 10.0), 0.5); // position, angle in radians // World/local coordinate conversions final worldPoint = body.worldPoint(Vector2(1.0, 0.0)); // Local to world final localPoint = body.localPoint(worldPoint); // World to local // Control body state body.setAwake(true); body.setActive(false); // Disable body temporarily body.isBullet = true; // Enable continuous collision detection ``` -------------------------------- ### Create RevoluteJoint for Hinge and Wheel Axles in Dart Source: https://context7.com/flame-engine/forge2d/llms.txt This Dart code illustrates the creation of RevoluteJoints in Forge2D. It shows how to constrain two bodies to rotate around a common anchor point, enabling hinge-like behavior with optional angle limits and motor control for spinning effects. ```dart import 'package:forge2d/forge2d.dart'; import 'dart:math'; // Create two bodies to connect final bodyDefA = BodyDef(type: BodyType.static, position: Vector2(0.0, 10.0)); final bodyA = world.createBody(bodyDefA);odyA.createFixtureFromShape(PolygonShape()..setAsBoxXY(0.5, 0.5)); final bodyDefB = BodyDef(type: BodyType.dynamic, position: Vector2(3.0, 10.0)); final bodyB = world.createBody(bodyDefB); bodyB.createFixtureFromShape(PolygonShape()..setAsBoxXY(2.0, 0.2), density: 1.0); // Create revolute joint definition final jointDef = RevoluteJointDef() ..initialize(bodyA, bodyB, Vector2(0.0, 10.0)) // anchor point in world coords ..enableLimit = true // Enable angle limits ..lowerAngle = -pi / 4 // -45 degrees ..upperAngle = pi / 4 // +45 degrees ..enableMotor = true // Enable motor ..motorSpeed = pi // Target speed in radians/second ..maxMotorTorque = 100.0; // Maximum torque in N-m // Create the joint final joint = RevoluteJoint(jointDef); world.createJoint(joint); // Creating a spinning wheel final wheelBody = world.createBody(BodyDef(type: BodyType.dynamic, position: Vector2(0.0, 5.0))); wheelBody.createFixtureFromShape(CircleShape(radius: 2.0), density: 1.0); final groundBody = world.createBody(BodyDef()); final wheelJointDef = RevoluteJointDef() ..initialize(wheelBody, groundBody, wheelBody.position) ..enableMotor = true ..motorSpeed = -pi // Rotate counter-clockwise ..maxMotorTorque = 1000000.0; world.createJoint(RevoluteJoint(wheelJointDef)); ``` -------------------------------- ### Create DistanceJoint for Fixed and Spring Connections in Dart Source: https://context7.com/flame-engine/forge2d/llms.txt This Dart code demonstrates how to use DistanceJoint in Forge2D to maintain a fixed or spring-like distance between two bodies. It shows configurations for both rigid connections and soft spring-damper behavior using frequency and damping ratio. ```dart import 'package:forge2d/forge2d.dart'; // Create two bodies final bodyA = world.createBody(BodyDef(type: BodyType.static, position: Vector2(0.0, 20.0))); bdA.createFixtureFromShape(CircleShape(radius: 0.5)); final bodyB = world.createBody(BodyDef(type: BodyType.dynamic, position: Vector2(0.0, 15.0))); bodyB.createFixtureFromShape(CircleShape(radius: 1.0), density: 1.0); // Create distance joint (rigid connection) final jointDef = DistanceJointDef() ..initialize(bodyA, bodyB, bodyA.position, bodyB.position) ..length = 5.0; // Maintain 5 unit distance world.createJoint(DistanceJoint(jointDef)); // Create a soft spring connection final springJointDef = DistanceJointDef() ..initialize(bodyA, bodyB, bodyA.position, bodyB.position) ..length = 5.0 ..frequencyHz = 4.0 // Oscillation frequency (Hz) ..dampingRatio = 0.5; // 0 = no damping, 1 = critical damping world.createJoint(DistanceJoint(springJointDef)); ``` -------------------------------- ### Define ChainShape for Terrain Source: https://context7.com/flame-engine/forge2d/llms.txt Explains the creation of free-form line segments using ChainShape, including open chains, closed loops, and programmatically generated curves. ```dart import 'package:forge2d/forge2d.dart'; final chain = ChainShape(); final vertices = [Vector2(-20.0, 0.0), Vector2(-10.0, 2.0), Vector2(0.0, 0.0), Vector2(10.0, -1.0), Vector2(15.0, 3.0), Vector2(20.0, 0.0)]; chain.createChain(vertices); final groundDef = BodyDef(position: Vector2.zero()); final ground = world.createBody(groundDef); ground.createFixtureFromShape(chain, friction: 0.5); final loopShape = ChainShape(); loopShape.createLoop([Vector2(-5.0, -5.0), Vector2(5.0, -5.0), Vector2(5.0, 5.0), Vector2(-5.0, 5.0)]); final curveChain = ChainShape(); final curveVertices = List.generate(20, (i) => Vector2(i.toDouble() - 10, sin(i * 0.5) * 3)); curveChain.createChain(curveVertices); ``` -------------------------------- ### PolygonShape - Convex Polygon Collision Shape Source: https://context7.com/flame-engine/forge2d/llms.txt Defines convex polygons for collision detection, including boxes and custom multi-vertex shapes. ```APIDOC ## PolygonShape ### Description Represents a convex polygon with up to 8 vertices. Used for boxes, oriented rectangles, and custom convex shapes. ### Methods - **setAsBoxXY(hx, hy)** - Creates an axis-aligned box. - **set(vertices)** - Creates a custom convex polygon from a list of Vector2. - **setAsEdge(v1, v2)** - Creates a line segment. ``` -------------------------------- ### ChainShape - Chain of Line Segments Source: https://context7.com/flame-engine/forge2d/llms.txt Defines a sequence of connected line segments, ideal for static terrain or complex boundaries. ```APIDOC ## ChainShape ### Description Creates a free-form sequence of line segments. Useful for terrain or platforms. ### Methods - **createChain(vertices)** - Connects a list of vertices into a chain. - **createLoop(vertices)** - Connects a list of vertices into a closed loop. ``` -------------------------------- ### CircleShape - Circular Collision Shape Source: https://context7.com/flame-engine/forge2d/llms.txt Defines a circular collision shape, which is the most efficient shape type for collision detection in Forge2D. ```APIDOC ## CircleShape ### Description Represents a circular collision shape. It supports defining a radius and an optional offset from the body's origin. ### Parameters - **radius** (double) - Required - The radius of the circle. - **position** (Vector2) - Optional - The offset of the circle center from the body origin. ### Request Example final circle = CircleShape(radius: 2.0, position: Vector2(0.0, 0.0)); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.