Skip to content

@web-engine-dev/physics2d

2D physics engine with collision detection, rigid body dynamics, and constraints for web-engine-dev.

Features

  • Rigid Body Dynamics: Forces, impulses, torque
  • Collision Detection: AABB, circles, polygons
  • Collision Response: Sequential impulse (basic restitution + friction)
  • Constraints: Joint API (reference implementation)
  • Continuous Detection: Bullet CCD for fast bodies (swept shapes)
  • Raycasting: 2D ray queries

Production backend: For best-in-class performance, CCD, and full solver features, use the Rapier adapter via @web-engine-dev/physics2d-rapier.

Installation

bash
npm install @web-engine-dev/physics2d
# or
pnpm add @web-engine-dev/physics2d

Quick Start

typescript
import { PhysicsWorld2D, RigidBody2D, BoxShape, CircleShape } from '@web-engine-dev/physics2d';

// Create physics world
const world = new PhysicsWorld2D({
  gravity: { x: 0, y: -9.81 },
});

// Add ground
const ground = world.createBody({
  type: 'static',
  position: { x: 0, y: -5 },
  shape: new BoxShape(10, 0.5),
});

// Add dynamic body
const ball = world.createBody({
  type: 'dynamic',
  position: { x: 0, y: 5 },
  shape: new CircleShape(0.5),
  restitution: 0.8,
});

// Step simulation
world.step(1 / 60);

API Overview

Body Types

typescript
// Static - never moves
world.createBody({ type: 'static', ... });

// Kinematic - moved by code, not physics
world.createBody({ type: 'kinematic', ... });

// Dynamic - fully simulated
world.createBody({ type: 'dynamic', ... });

Shapes

typescript
// Box
new BoxShape(width, height);

// Circle
new CircleShape(radius);

// Polygon
new PolygonShape([
  { x: 0, y: 1 },
  { x: 1, y: -1 },
  { x: -1, y: -1 },
]);

// Edge (one-sided)
new EdgeShape({ x: -5, y: 0 }, { x: 5, y: 0 });

Forces and Impulses

typescript
// Apply force (continuous)
body.applyForce({ x: 100, y: 0 });

// Apply impulse (instant)
body.applyImpulse({ x: 10, y: 0 });

// Apply torque
body.applyTorque(5);

// Set velocity directly
body.setLinearVelocity({ x: 5, y: 0 });
body.setAngularVelocity(2);

Constraints

typescript
// Distance joint
world.createJoint({
  type: 'distance',
  bodyA: ball1,
  bodyB: ball2,
  length: 2,
});

// Revolute (hinge) joint
world.createJoint({
  type: 'revolute',
  bodyA: wheel,
  bodyB: chassis,
  anchor: { x: 0, y: 0 },
});

// Prismatic (slider) joint
world.createJoint({
  type: 'prismatic',
  bodyA: platform,
  bodyB: rail,
  axis: { x: 1, y: 0 },
});

Collision Events

typescript
world.on('collision-start', (a, b, contact) => {
  console.log('Collision started');
});

world.on('collision-end', (a, b) => {
  console.log('Collision ended');
});

Peer Dependencies

  • @web-engine-dev/math - Vector math

Proprietary software. All rights reserved.