Observed since 20 Oct, 19:10 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
2d-physics-engine
A lightweight, flexible 2D physics engine with ECS architecture, built with TypeScript
A lightweight, flexible 2D physics engine built with TypeScript, featuring an Entity-Component-System (ECS) architecture. Perfect for building 2D games, simulations, and interactive applications.
⚠️ Note: This project is not production-ready. It is still under active development and primarily built for educational purposes, experimentation, and learning how 2D physics engines and ECS architectures work. Use it as a learning tool or prototype, but it may contain bugs, incomplete features, and performance limitations.
npm install 2d-physics-engine
# or
yarn add 2d-physics-engine
# or
pnpm add 2d-physics-engine
import {
Iterator,
Scene,
Entity,
Transform,
Rigidbody,
CircleCollider,
Vector2,
InputManager,
} from '2d-physics-engine';
// Setup canvas
const canvas = document.getElementById('canvas') as HTMLCanvasElement;
const ctx = canvas.getContext('2d')!;
const inputManager = new InputManager();
// Create engine
const engine = new Iterator(inputManager, canvas, ctx);
// Create scene
const scene = new Scene();
// Create an entity with physics
const ball = new Entity('Ball');
ball.addComponent(new Transform(new Vector2(100, 100)));
ball.addComponent(new Rigidbody({ mass: 1, restitution: 0.8, friction: 0.1 }));
ball.addComponent(new CircleCollider(25));
scene.addEntity(ball);
// Start the engine
engine.setScene(scene);
engine.start();
Handles position, rotation, and scale of entities.
const transform = new Transform(
new Vector2(100, 100), // position
0, // rotation (radians)
new Vector2(1, 1), // scale
);
Adds physics properties to an entity.
const rigidbody = new Rigidbody({
mass: 1, // mass in kg
restitution: 0.8, // bounciness (0-1)
friction: 0.1, // friction coefficient
});
Define collision shapes for entities.
const collider = new CircleCollider(25); // radius
2D vector operations for position, velocity, forces, etc.
import { Vector2 } from '2d-physics-engine';
const v1 = new Vector2(10, 20);
const v2 = new Vector2(5, 5);
// Operations (all return new vectors, immutable)
const sum = v1.add(v2);
const diff = v1.subtract(v2);
const scaled = v1.scale(2);
const normalized = v1.getNormal();
const magnitude = v1.getMagnitude();
Axis-Aligned Bounding Box for spatial queries.
import { AABB, Vector2 } from '2d-physics-engine';
const box = new AABB(
new Vector2(0, 0), // min corner
new Vector2(100, 100), // max corner
);
// Or use factory methods
const box2 = AABB.fromCenter(new Vector2(50, 50), new Vector2(25, 25));
Entity - Container for componentsScene - Manages collections of entitiesIterator - Main game loop and system managerInputManager - Handles keyboard and mouse inputTransform - Position, rotation, scaleRigidbody - Physics propertiesCollider (abstract) - Collision shape base classCircleCollider - Circular collision shapeController - WASD/Arrow key movement controllerDrawer (abstract) - Rendering base classCircleDrawer - Renders circlesPhysics - Handles physics simulationRendering - Renders entities with drawer componentsCollisionDetector - Detects collisions between entitiesCollisionResolver - Resolves collisionsVector2 - 2D vector classAABB - Axis-Aligned Bounding BoxQuadTree - Spatial partitioning structureconst rigidbody = entity.getComponent(Rigidbody);
if (rigidbody) {
rigidbody.addForce(new Vector2(100, 0)); // Apply force to the right
}
import { Drawer, Transform } from '2d-physics-engine';
class MyDrawer extends Drawer {
draw(ctx: CanvasRenderingContext2D, transform: Transform): void {
// Your custom rendering code
}
}
import { Collider, AABB, Transform } from '2d-physics-engine';
class BoxCollider extends Collider {
static readonly COLLIDER_ID = Symbol('BoxCollider');
readonly colliderId = BoxCollider.COLLIDER_ID;
constructor(
private width: number,
private height: number,
) {
super();
}
getAABB(transform: Transform): AABB {
// Return AABB based on transform
}
calculateInertia(mass: number): number {
// Calculate moment of inertia
}
}
# Install dependencies
npm install
# Run development server
npm run dev
# Build library
npm run build:lib
# Run tests
npm test
# Format code
npm run format
MIT
Contributions are welcome! Please feel free to submit a Pull Request.
Download counts and popularity will appear here as the collector receives them.
| Package / target | Requirement | Relationship |
|---|---|---|
jestEnvironment{
"local_name": "jest",
"alias": false,
"peer_metadata": null
} | ^29.7.0 | development |
viteEnvironment{
"local_name": "vite",
"alias": false,
"peer_metadata": null
} | ^5.0.0 | development |
ts-jestEnvironment{
"local_name": "ts-jest",
"alias": false,
"peer_metadata": null
} | ^29.1.1 | development |
prettierEnvironment{
"local_name": "prettier",
"alias": false,
"peer_metadata": null
} | ^3.1.1 | development |
babel-jestEnvironment{
"local_name": "babel-jest",
"alias": false,
"peer_metadata": null
} | ^29.7.0 | development |
typescriptEnvironment{
"local_name": "typescript",
"alias": false,
"peer_metadata": null
} | ^5.2.2 | development |
@types/jestEnvironment{
"local_name": "@types/jest",
"alias": false,
"peer_metadata": null
} | ^29.5.10 | development |
@babel/preset-envEnvironment{
"local_name": "@babel/preset-env",
"alias": false,
"peer_metadata": null
} | ^7.23.5 | development |
jest-environment-jsdomEnvironment{
"local_name": "jest-environment-jsdom",
"alias": false,
"peer_metadata": null
} | ^29.7.0 | development |
Source distribution
{
"shasum": "4c0de88e9a7041101c0e8c6c8c14a304dff95640",
"tarball": "https://registry.npmjs.org/2d-physics-engine/-/2d-physics-engine-1.5.2.tgz",
"fileCount": 155,
"integrity": "sha512-Z76m9x26zr/y6CTMRhuPDOX5HRqWjxVuZUhQZGjhPyZFqdObMa+1XMvHvn6vWj2/uV7SZ8hbQLRDazUXOz7jXg==",
"signatures": [
{
"sig": "MEQCIGUlhpH6FIQPPFg3BKvbPS87jaIAeWmUlY4ZRwPg5wYMAiARmj9k7RPyJnkQkp3E+ojSWGdTpb7yaJWdRQwq941I0g==",
"keyid": "SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"
}
],
"unpackedSize": 228826
}Shared repository data · GitHub
Observed since 20 Oct, 19:10 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package_version:99026ca53745c487be669ebbf0df0d61114e1060c4286fdb51235de86a5f65a5