npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@esengine/nova-ecs-physics-box2d

v1.0.2

Published

Box2D physics engine implementation for NovaECS physics core

Readme

@esengine/nova-ecs-physics-box2d

Box2D physics engine implementation for NovaECS physics core. Provides deterministic 2D physics simulation using the industry-standard Box2D engine.

NovaECS物理核心的Box2D物理引擎实现。使用行业标准的Box2D引擎提供确定性2D物理模拟。

npm version CI License: MIT TypeScript

Features | 特性

  • 🎯 Deterministic: Fixed-point integration ensures identical results across platforms | 确定性:定点集成确保跨平台的相同结果
  • ⚡ High Performance: WebAssembly-based Box2D for optimal performance | 高性能:基于WebAssembly的Box2D以获得最佳性能
  • 🔧 Complete 2D Physics: Rigid bodies, colliders, joints, raycast, and more | 完整的2D物理:刚体、碰撞器、关节、射线投射等
  • 🧮 Math Integration: Seamless integration with @esengine/nova-ecs-math | 数学集成:与@esengine/nova-ecs-math无缝集成
  • 🔌 Pluggable: Drop-in replacement for other physics engines | 可插拔:其他物理引擎的直接替代品
  • 📦 ECS Ready: Optimized for Entity-Component-System architecture | ECS就绪:为实体组件系统架构优化
  • 🧪 Battle Tested: Based on the proven Box2D physics engine | 久经考验:基于经过验证的Box2D物理引擎

Installation | 安装

npm install @esengine/nova-ecs-physics-box2d

Required dependencies: 必需的依赖项:

npm install @esengine/nova-ecs @esengine/nova-ecs-math @esengine/nova-ecs-physics-core

Quick Start | 快速开始

import { World } from '@esengine/nova-ecs';
import { FixedVector2, Fixed } from '@esengine/nova-ecs-math';
import {
  RigidBodyComponent,
  ColliderComponent,
  PhysicsTransformComponent,
  RigidBodyType,
  ColliderType
} from '@esengine/nova-ecs-physics-core';
import { Box2DPhysicsPlugin } from '@esengine/nova-ecs-physics-box2d';

// Create world and install Box2D physics plugin
const world = new World();
const physicsPlugin = new Box2DPhysicsPlugin({
  worldConfig: {
    gravity: new FixedVector2(0, -9.81),
    allowSleep: true,
    velocityIterations: 8,
    positionIterations: 3
  },
  fixedTimeStep: 1/60,
  enableDebugRender: false
});

await world.plugins.install(physicsPlugin);

// Create a falling box
const box = world.createEntity();

box.addComponent(new PhysicsTransformComponent(
  new FixedVector2(0, 10), // position
  0,                       // rotation
  new FixedVector2(1, 1)   // scale
));

box.addComponent(new RigidBodyComponent(
  RigidBodyType.Dynamic,   // dynamic body
  0.1,                     // linear damping
  0.1,                     // angular damping
  1.0                      // gravity scale
));

box.addComponent(new ColliderComponent({
  type: ColliderType.Box,
  halfWidth: new Fixed(1),
  halfHeight: new Fixed(1)
}, {
  friction: new Fixed(0.3),
  restitution: new Fixed(0.5),
  density: new Fixed(1.0)
}));

// Create static ground
const ground = world.createEntity();

ground.addComponent(new PhysicsTransformComponent(
  new FixedVector2(0, -5)
));

ground.addComponent(new RigidBodyComponent(RigidBodyType.Static));

ground.addComponent(new ColliderComponent({
  type: ColliderType.Box,
  halfWidth: new Fixed(10),
  halfHeight: new Fixed(1)
}));

// Game loop
function gameLoop(deltaTime: number) {
  world.update(deltaTime);
  
  // Get box position for rendering
  const transform = box.getComponent(PhysicsTransformComponent)!;
  console.log(`Box position: ${transform.position.x}, ${transform.position.y}`);
}

setInterval(() => gameLoop(16), 16);

Advanced Usage | 高级用法

Custom Physics Materials | 自定义物理材质

import { PhysicsMaterial } from '@esengine/nova-ecs-physics-core';

// Create bouncy material
const bouncyMaterial: PhysicsMaterial = {
  friction: new Fixed(0.1),
  restitution: new Fixed(0.9),  // Very bouncy
  density: new Fixed(0.5)
};

// Create ice material
const iceMaterial: PhysicsMaterial = {
  friction: new Fixed(0.02),    // Very slippery
  restitution: new Fixed(0.1),
  density: new Fixed(0.8)
};

entity.addComponent(new ColliderComponent(
  { type: ColliderType.Circle, radius: new Fixed(1) },
  bouncyMaterial
));

Collision Detection | 碰撞检测

import { CollisionEventComponent } from '@esengine/nova-ecs-physics-core';

const entity = world.createEntity();
// ... add other components

const collisionEvents = new CollisionEventComponent();

// Handle collision begin
collisionEvents.addCollisionBeginCallback((other) => {
  console.log('Collision started with:', other);
});

// Handle collision end
collisionEvents.addCollisionEndCallback((other) => {
  console.log('Collision ended with:', other);
});

entity.addComponent(collisionEvents);

Raycast | 射线投射

import { RaycastInput } from '@esengine/nova-ecs-physics-core';

const physicsWorld = physicsPlugin.getWorldSystem()?.getPhysicsWorld();

if (physicsWorld) {
  const raycast: RaycastInput = {
    origin: new FixedVector2(0, 10),
    direction: new FixedVector2(0, -1), // Downward
    maxDistance: new Fixed(20)
  };
  
  const results = physicsWorld.raycast(raycast);
  
  for (const result of results) {
    if (result.hit) {
      console.log(`Hit at: ${result.point?.x}, ${result.point?.y}`);
      console.log(`Distance: ${result.distance?.toNumber()}`);
    }
  }
}

Force and Impulse | 力和冲量

// Apply continuous force (like wind)
const rigidBody = entity.getComponent(RigidBodyComponent)!;
rigidBody.applyForce(new FixedVector2(10, 0)); // Rightward force

// Apply instant impulse (like explosion)
rigidBody.applyImpulse(new FixedVector2(0, 50)); // Upward impulse

// Apply force at specific point (creates rotation)
rigidBody.applyForceAtPoint(
  new FixedVector2(10, 0),     // force
  new FixedVector2(0, 1)       // point offset from center
);

Collision Filtering | 碰撞过滤

import { CollisionFilter } from '@esengine/nova-ecs-physics-core';

// Define collision categories
const CATEGORY_PLAYER = 0x0001;
const CATEGORY_ENEMY = 0x0002;
const CATEGORY_WALL = 0x0004;
const CATEGORY_PICKUP = 0x0008;

// Player collides with enemies, walls, and pickups
const playerFilter: CollisionFilter = {
  categoryBits: CATEGORY_PLAYER,
  maskBits: CATEGORY_ENEMY | CATEGORY_WALL | CATEGORY_PICKUP
};

// Enemy collides with player and walls only
const enemyFilter: CollisionFilter = {
  categoryBits: CATEGORY_ENEMY,
  maskBits: CATEGORY_PLAYER | CATEGORY_WALL
};

entity.addComponent(new ColliderComponent(
  { type: ColliderType.Box, halfWidth: new Fixed(1), halfHeight: new Fixed(1) },
  undefined, // Use default material
  playerFilter
));

Configuration | 配置

Plugin Configuration | 插件配置

const physicsPlugin = new Box2DPhysicsPlugin({
  worldConfig: {
    gravity: new FixedVector2(0, -9.81),
    allowSleep: true,
    velocityIterations: 8,      // Higher = more accurate but slower
    positionIterations: 3,      // Higher = more accurate but slower
    timeStep: new Fixed(1/60)
  },
  fixedTimeStep: 1/60,          // Physics time step
  maxSubSteps: 10,              // Maximum physics sub-steps per frame
  enableDebugRender: false,     // Enable debug visualization
  autoCreateSystems: true,      // Automatically create physics systems
  enableCCD: true,              // Continuous collision detection
  enableWarmStarting: true,     // Warm starting for better performance
  enableSubStepping: false      // Sub-stepping for better stability
});

Performance Tips | 性能提示

  1. Use appropriate iteration counts | 使用适当的迭代次数

    • Lower velocityIterations and positionIterations for better performance
    • 降低velocityIterations和positionIterations以获得更好的性能
  2. Enable sleeping | 启用休眠

    • Allow bodies to sleep when not moving to save CPU
    • 允许不移动的物体休眠以节省CPU
  3. Use collision filtering | 使用碰撞过滤

    • Reduce unnecessary collision checks with proper filtering
    • 通过适当的过滤减少不必要的碰撞检查
  4. Optimize collider shapes | 优化碰撞器形状

    • Use simple shapes (box, circle) when possible
    • 尽可能使用简单形状(盒子、圆形)

Supported Features | 支持的功能

  • ✅ Rigid Bodies (Static, Kinematic, Dynamic) | 刚体(静态、运动学、动态)
  • ✅ Colliders (Box, Circle) | 碰撞器(盒子、圆形)
  • ✅ Physics Materials | 物理材质
  • ✅ Collision Events | 碰撞事件
  • ✅ Raycast | 射线投射
  • ✅ AABB Queries | AABB查询
  • ✅ Collision Filtering | 碰撞过滤
  • ✅ Sensors | 传感器
  • ✅ Continuous Collision Detection | 连续碰撞检测
  • ✅ Sleeping | 休眠
  • 🚧 Joints (Planned) | 关节(计划中)
  • 🚧 Polygon Colliders (Planned) | 多边形碰撞器(计划中)
  • 🚧 Debug Rendering (Planned) | 调试渲染(计划中)

Related Projects | 相关项目

License | 许可证

MIT