planck.js

repository·master·Indexed 26 days ago

https://github.com/piqnt/planck.js

A high-performance 2D JavaScript/TypeScript physics engine for cross-platform HTML5 game development. As a port of the Box2D engine, it provides an idiomatic API for managing bodies, fixtures, and joints using MKS (Meters-Kilogram-Second) units. Version 1.5.0 includes features for continuous collision detection (CCD), body sleep parameters, and flexible user data attachment for linking physics objects to game logic.

Tokens
23.7K
Snippets
74
Records
148
Agent score
87%

What's inside planck.js

  1. Overview of Planck.js

    master
    Planck.js is a JavaScript/TypeScript rewrite of the Box2D physics engine designed for cross-platform HTML5 game development. It aims to provide an idiomatic JavaScript/TypeScript API while optimizing for web and mobile platforms.
  2. Understand Broad-phase vs Narrow-phase collision

    master

    Collision processing in Planck.js is split into two stages:

    1. Broad-phase: Uses a BroadPhase class (internally powered by a DynamicTree) to quickly identify potential colliding pairs, reducing the complexity from $O(N^2)$ to a much lower load.
    2. Narrow-phase: Performs the actual computation of contact points between the pairs identified by the broad-phase.

    Users typically interact with the World class rather than managing the BroadPhase directly.

  3. Understand Contact terminology

    master

    Contacts manage collisions between two fixtures. Key concepts include:

    • Contact Point: A point where two shapes touch.
    • Contact Normal: A unit vector pointing from fixtureA to fixtureB.
    • Contact Separation: The distance between shapes. Negative values indicate overlap (penetration).
    • Contact Manifold: A group of contact points sharing the same normal, approximating a continuous contact region.
    • Normal Impulse: The impulse applied to prevent penetration.
    • Tangent Impulse: The impulse generated to simulate friction.
    • Contact Ids: Used to match contact points across time steps for performance.
  4. Understand Planck.js Shape properties and behavior

    master

    Shapes in Planck.js define collision geometry and are independent of the physics simulation. They are considered immutable.

    Key behaviors to note:

    • Coordinate Systems: When a shape is not attached to a body, its vertices are in world-space. When attached to a body via a fixture, its vertices are in local coordinates.
    • Base Class Capabilities: All shapes implement the Shape base class, which provides methods for point testing, ray casting, AABB computation, and mass property computation.
    • Properties: Every shape has a type member and a radius (the radius also applies to polygons).
  5. Understand Planck.js Core Concepts

    master

    Planck.js is a 2D physics engine built around several fundamental objects that interact to simulate physical motion:

    • World: The container for the entire simulation. It manages all bodies, fixtures, and constraints, and is responsible for running the simulation loop.
    • Shape: A 2D geometric primitive (e.g., circle or polygon) that defines the geometry of an object.
    • Rigid Body: A physical object with constant mass and volume that responds to forces. In Planck.js, 'body' and 'rigid body' are used interchangeably.
    • Fixture: The bridge between geometry and physics. A fixture binds a Shape to a Rigid Body and defines physical properties like density, friction, and restitution. Fixtures are what enable objects to participate in the collision system.
    • Constraint: A mechanism that removes degrees of freedom from bodies (e.g., pinning a body to a point to allow only rotation).
    • Contact Constraint: Automatically generated constraints that prevent bodies from penetrating each other and simulate friction and restitution.
    • Joint: A specific type of constraint used to connect two or more bodies (e.g., revolute, prismatic, or distance joints). Joints can include limits (restricting range of motion) and motors (driving motion).
  6. Manage mass ratios for simulation stability

    master
    To maintain simulation stability in Planck.js, avoid stacking heavy bodies on top of much lighter bodies or connecting heavy bodies to light bodies via joint chains. Stability degrades significantly when the mass ratio between connected or stacked bodies exceeds 10:1.
  7. Resolve collisions and prevent tunneling with Continuous Collision

    master

    Because the Planck.js solver advances bodies using discrete time steps, fast-moving objects may 'tunnel' through other objects. To prevent this, Planck.js uses two specialized mechanisms:

    1. Time of Impact (TOI) Interpolation: The collision algorithms interpolate the motion of two bodies to calculate the exact moment they would first collide.
    2. Sub-stepping Solver: A specialized solver that moves bodies to their calculated Time of Impact and resolves the collision before proceeding with the rest of the simulation step.
  8. Use Planck Testbed via Script Tag (CDN)

    master

    To use the testbed via CDN, use the planck-with-testbed.min.js distribution. Note that the testbed typically requires specific HTML elements (like #testbed-info, #testbed-status, and #testbed-play) to function correctly.

    <html><body>
      <span id="testbed-info"></span>
      <span id="testbed-status"></span>
      <button id="testbed-play">Play</button>
    
      <script src="https://cdn.jsdelivr.net/npm/planck/dist/planck-with-testbed.min.js"></script>
      <script>
        const { World, Testbed } = planck;
        const world = new World();
    
        const testbed = Testbed.mount();
        testbed.start(world);
      </script>
    </body></html>
  9. Create and destroy Fixtures

    master

    A Fixture attaches a shape to a body, giving it physical properties. A body with multiple fixtures is known as a compound body.

    To create a fixture, pass a definition object to body.createFixture(). You do not need to manually manage the fixture's lifecycle; it is automatically destroyed when the parent body is destroyed. To manually remove a specific fixture (e.g., for breakable objects), use body.destroyFixture(fixture).

    let myFixture = myBody.createFixture({
      shape: myShape,
      density: 1,
    });
    
    // To destroy it manually:
    myBody.destroyFixture(myFixture);
  10. Understand Weld Joint behavior and limitations

    master

    A WeldJoint attempts to constrain all relative motion between two bodies.

    Important Limitation: Because the Planck.js solver is iterative, weld joints are 'soft'. If you connect a chain of bodies using weld joints, the structure will flex rather than remaining perfectly rigid.

    Best Practice for Breakable Structures: Do not use a chain of weld joints to create breakable structures. Instead, create a single body with multiple fixtures. To simulate breaking, destroy a fixture and recreate it on a new body.