p2-es
v1.2.3
Published
A JavaScript 2D physics engine.
Downloads
1,586
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 | Examples | Documentation
This is a maintained fork of p2.js, originally created by Stefan Hedman @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! It's a wrapper around p2-es that runs in a web worker.
Getting Started
NPM
npm install p2-es
yarn add p2-es
CDN
You can also import the esm bundle with unpkg:
<script type="module">
// import a specific version
import * as p2 from 'https://www.unpkg.com/[email protected]/dist/p2-es.js'
// or import latest
import * as p2 from 'https://www.unpkg.com/p2-es/dist/p2-es.js'
</script>
If you would like to use ordinary Array
instead of Float32Array
, define P2_ARRAY_TYPE
globally before loading the library.
<script type="text/javascript">
P2_ARRAY_TYPE = Array
</script>
<script type="module">
import * as p2 from 'p2-es.js'
</script>
Sample code
The following example uses the World, Circle, Body and Plane classes to set up a simple physics scene with a ball on a plane.
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.
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 | Yes | - | - | - | - | - | - | - | - | | Plane | Yes | - | - | - | - | - | - | - | - | | Box | Yes | Yes | Yes | - | - | - | - | - | - | | Convex | Yes | Yes | Yes | Yes | - | - | - | - | - | | Particle | Yes | Yes | Yes | Yes | - | - | - | - | - | | Line | Yes | Yes | (todo) | (todo) | - | - | - | - | - | | Capsule | Yes | Yes | Yes | Yes | Yes | (todo) | Yes | - | - | | Heightfield | Yes | - | Yes | Yes | (todo) | (todo) | (todo) | - | - | | Ray | Yes | Yes | Yes | Yes | - | Yes | Yes | Yes | - |
Note that concave polygon shapes can be created using Body.fromPolygon.
Building
Make sure you have git, Node.js v14+ and Yarn installed
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