# p2-es **Repository Path**: mirrors_pmndrs/p2-es ## Basic Information - **Project Name**: p2-es - **Description**: JavaScript 2D physics library - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-01-01 - **Last Updated**: 2026-02-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # p2-es p2-es is a 2D rigid body physics engine written in JavaScript. Features include collision detection, contacts, friction, restitution, motors, springs, advanced constraints and various shape types. [Demos](https://p2-es.pmnd.rs/#demos) | [Examples](https://p2-es.pmnd.rs/#examples) | [Documentation](https://p2-es.pmnd.rs/docs/) This is a maintained fork of [p2.js](https://github.com/schteppe/p2.js), originally created by Stefan Hedman [@schteppe](https://github.com/schteppe). It is a type-safe flatbundle (esm and cjs) which allows for **tree shaking** and usage in modern environments. If you're using three.js in a React environment with react-three-fiber, check out [use-p2](https://github.com/pmndrs/use-p2)! It's a wrapper around p2-es that runs in a web worker. ### Getting Started **NPM** ```ts npm install p2-es yarn add p2-es ``` **CDN** You can also import the esm bundle with unpkg: ```html ``` --- If you would like to use ordinary `Array` instead of `Float32Array`, define `P2_ARRAY_TYPE` globally before loading the library. ```html ``` ### Sample code The following example uses the [World](https://p2-es.pmnd.rs/docs/classes/World.html), [Circle](https://p2-es.pmnd.rs/docs/classes/Circle.html), [Body](https://p2-es.pmnd.rs/docs/classes/Body.html) and [Plane](https://p2-es.pmnd.rs/docs/classes/Plane.html) classes to set up a simple physics scene with a ball on a plane. ```js import * as p2 from 'p2-es' // Create a physics world, where bodies and constraints live const world = new p2.World({ gravity: [0, -9.82], }) // Create an empty dynamic body const circleBody = new p2.Body({ mass: 5, position: [0, 10], }) // Add a circle shape to the body const circleShape = new p2.Circle({ radius: 1 }) circleBody.addShape(circleShape) // ...and add the body to the world. // If we don't add it to the world, it won't be simulated. world.addBody(circleBody) // Create an infinite ground plane body const groundBody = new p2.Body({ mass: 0, // Setting mass to 0 makes it static }) const groundShape = new p2.Plane() groundBody.addShape(groundShape) world.addBody(groundBody) // To animate the bodies, we must step the world forward in time, using a fixed time step size. // The World will run substeps and interpolate automatically for us, to get smooth animation. const fixedTimeStep = 1 / 60 // seconds const maxSubSteps = 10 // Max sub steps to catch up with the wall clock let lastTime = 0 // Animation loop function animate(time) { requestAnimationFrame(animate) // Compute elapsed time since last render frame const deltaTime = (time - lastTime) / 1000 // Move bodies forward in time world.step(fixedTimeStep, deltaTime, maxSubSteps) // Render the circle at the current interpolated position renderCircleAtPosition(circleBody.interpolatedPosition) lastTime = time } // Start the animation loop requestAnimationFrame(animate) ``` To interact with bodies, you need to do it _after each internal step_. Simply attach a _"postStep"_ listener to the world, and make sure to use `body.position` here - `body.interpolatedPosition` is only for rendering. ```js world.on('postStep', function (event) { // Add horizontal spring force circleBody.force[0] -= 100 * circleBody.position[0] }) ``` ### Supported collision pairs | | Circle | Plane | Box | Convex | Particle | Line | Capsule | Heightfield | Ray | | :----------------------------------------------------------------: | :----: | :---: | :----: | :----: | :------: | :----: | :-----: | :---------: | :-: | | [Circle](https://p2-es.pmnd.rs/docs/classes/Circle.html) | Yes | - | - | - | - | - | - | - | - | | [Plane](https://p2-es.pmnd.rs/docs/classes/Plane.html) | Yes | - | - | - | - | - | - | - | - | | [Box](https://p2-es.pmnd.rs/docs/classes/Box.html) | Yes | Yes | Yes | - | - | - | - | - | - | | [Convex](https://p2-es.pmnd.rs/docs/classes/Convex.html) | Yes | Yes | Yes | Yes | - | - | - | - | - | | [Particle](https://p2-es.pmnd.rs/docs/classes/Particle.html) | Yes | Yes | Yes | Yes | - | - | - | - | - | | [Line](https://p2-es.pmnd.rs/docs/classes/Line.html) | Yes | Yes | (todo) | (todo) | - | - | - | - | - | | [Capsule](https://p2-es.pmnd.rs/docs/classes/Capsule.html) | Yes | Yes | Yes | Yes | Yes | (todo) | Yes | - | - | | [Heightfield](https://p2-es.pmnd.rs/docs/classes/Heightfield.html) | Yes | - | Yes | Yes | (todo) | (todo) | (todo) | - | - | | [Ray](https://p2-es.pmnd.rs/docs/classes/Ray.html) | Yes | Yes | Yes | Yes | - | Yes | Yes | Yes | - | Note that concave polygon shapes can be created using [Body.fromPolygon](https://p2-es.pmnd.rs/docs/classes/Body.html#fromPolygon). ### Building Make sure you have git, [Node.js](http://nodejs.org) v14+ and Yarn installed ```sh git clone https://github.com/pmndrs/p2-es.git && cd p2-es # install deps yarn # build p2-es (cd packages/p2-es && yarn build) # build the website yarn build npx http-server apps/p2-es-website/dist ```