@flare-engine/dynamics

中文文档
0.4.12发布于 2026/11/13Apache-2.0TypeScriptESM + CJS构建来源已验证近 30 天下载 2215

2D 刚性正体: 方向框、 接触多面体、 相继冲压解器

中文使用文档
文档目录6 节
  1. 安装
  2. 使用量
  3. 记录和重播
  4. 睡觉
  5. 限制(v1)
  6. 许可证

@flare-engine/动力学

2D 刚性体动力学取向外方框(OBBs):分离轴+参考/事件面 剪接会构建1-2个点接触多路,一个相继的冲动解析器用 Coulomb摩擦,还原, 和Baumgarte去渗透. @flare-engine/physics 答题 对 这些重叠· ; @flare-engine/dynamics 答题 他们最终会在哪里。两个软件包都取决于 另一段——按场景选取,或并用(physics 用于触发/重叠查询, dynamics 身体实际上相互推压.

安装

bun add @flare-engine/dynamics

使用量

import { addBody, createBody, createWorld, step } from '@flare-engine/dynamics';

const world = createWorld({ gravity: { x: 0, y: 1800 } });

// Static floor: invMass 0, never moves.
addBody(
  world,
  createBody({ position: { x: 0, y: 100 }, half: { x: 500, y: 10 }, static: true }),
);

const box = addBody(
  world,
  createBody({ position: { x: 0, y: -50 }, half: { x: 10, y: 10 } }),
);

// Fixed-timestep loop.
step(world, 1 / 60);
console.log(box.position.y, box.velocity.y);

Body.position 财务报告和审定财务报表 Body.velocity 是可变的平面对象字段- createBody 分配它们 一次,还有 step() 每分一秒都写在书上 这是一个刻意的API合同,不是 监督:它符合引擎的"零分权"风格,让消费者读取或推翻 步骤之间的直接字段(例如,夹住休息速度-见下文限制) 通过一个接入器.

step() 平稳状态下不分配任何内容——每步结构(接触方块、接触) 积分 宽相刮痕缓冲器) 活在由该 World 并被反复使用, 只有在体数增加时才生长.

记录和重播

半隐蔽的欧拉有摩擦和还原 时间是无法逆转的,所以你想要跌倒 刷新、倒转或以另一种速度重放 烤过一次 改为 a Timeline 并读回: 取样. record 取一个写作员的回调而不是一个身体阵列,所以时间线永远不用知道 它记录了什么 until 它的上游在一个呼叫中烘焙, 没有一个记录一个 框架,适合一个时间预算的循环,每个滴答一次. stepUntil(world, dt, { budgetMs: 6, done: isSettled }) 是这个循环: 它步入到 done() 返回时 没错, maxSteps 达到或用完预算(至少一次),并报告 { steps, complete }· ; stepUntilInto 是零分配器形式.

import { createTimeline, createWorld, step } from '@flare-engine/dynamics';

const world = createWorld(); // add a floor and some boxes as above
const dt = 1 / 60;
const timeline = createTimeline(world.bodies.length, dt); // stride 3: x, y, angle
timeline.record(
  (buf, base) => {
    step(world, dt);
    for (let i = 0; i < world.bodies.length; i++) {
      const b = world.bodies[i]!;
      buf[base + i * 3] = b.position.x;
      buf[base + i * 3 + 1] = b.position.y;
      buf[base + i * 3 + 2] = b.angle;
    }
  },
  () => world.bodies.every((b) => Math.abs(b.velocity.y) < 1), // your own settle rule
);

const out = new Float32Array(timeline.elementCount * 3);
timeline.sampleInto(0.5, out); // body i at out[i * 3 ..], lerped between frames

存储为 Float32Array ——回放精度为f64的半字节,角度为: 保持原样: Body.angle 是累积的,从不包起来, 所以一个平地的麻鼠是正确的 穿过多回转的转弯,最短路径的麻风病会解开它们. sampleInto 分配数 没什么,上面的刮伤缓冲器为整个回放服务.

睡觉

睡眠默认关闭(参见限制). createWorld({ sleep }) 选择加入: 速度保持在 linearThreshold (px/s)及其角速度保持在 angularThreshold (弧度/秒)用于 steps 连续步骤的速度被设定为0,被跳过 与其他入睡或静态尸体进行对接试验。 当一个醒了的身体醒来 在前一步上移动的, 当你写它的时候 velocity, (中文(简体) ), angularVelocity, (中文(简体) ), position 或者说 angle,或者当你打电话 wakeBody。 。 。 . isSleeping(world, body) 读取一个正文 indexOf 结束 world.bodies(三); isAtRest(world) 一旦每个活体都睡了 就会变成 这是停止规则 对于一个 stepUntil 烘焙:

import {
  addBody,
  createBody,
  createWorld,
  isAtRest,
  isSleeping,
  stepUntil,
  wakeBody,
} from '@flare-engine/dynamics';

const world = createWorld({
  gravity: { x: 0, y: 1800 },
  sleep: { linearThreshold: 14, angularThreshold: 1.5, steps: 30 },
});
addBody(
  world,
  createBody({ position: { x: 0, y: 100 }, half: { x: 500, y: 10 }, static: true }),
);
const box = addBody(world, createBody({ position: { x: 0, y: 0 }, half: { x: 5, y: 5 } }));

const result = stepUntil(world, 1 / 120, {
  budgetMs: 8,
  maxSteps: 600,
  done: () => isAtRest(world),
});
if (result.complete) console.log(isSleeping(world, box), box.velocity.y); // true 0

wakeBody(world, box); // e.g. after removing the floor from world.bodies

阈值必须清除限制下描述的休息紧张,这取决于身体大小和 dt:在包件本身的测试中(半至5个盒, dt = 1/120休息箱峰约5.8px/s 和 1.12 弧度/秒(角峰平面有 1 / 半宽),因此有 14 / 1.5 个入睡在91 步中, 0.6弧度/s 从未看到连续30个安静的台阶. 在设定值前测量您自己的场景 .

睡觉不会做什么:

  • 没有岛屿. 一个被唤醒的躯体 唤醒了它触摸到的卧底 下一个 步骤,所以一个着陆箱 每步唤醒一叠一层, 沉睡者只被身体所触动,而身体本身正在安顿 (下入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入.
  • 潜伏者不会跟随被移动的静态身体. 在睡匣子下移动地上 框所在; 调用 wakeBody 移动或删除支持后.
  • 将尸体从 world.bodies 唤醒掉入槽中的尸体 没有别的了. 潜伏者,其支撑被移除而未转移 它在中空保持睡眠,直到 wakeBody。 。 。 . 在睡前插入一具尸体同样会唤醒它(在睡后重新入睡) steps 安静的台阶).
  • 一个从未经历过的世界 createWorld (散页副本或 structuredClone 交给 step(a) 被收养时不睡觉; isSleeping 财务报告和审定财务报表 isAtRest 任何动态都是假的 躯体.

限制(v1)

  • 休息的身体不会完全停止 除非你选择睡觉. 一个盒子安放在 地板到达马厩 职位 ——在包件自身的测试情景中,位置移动小于 0.1个单位超过600个进一步步骤——但 velocity 保持小的、有界的振荡(大约2.6个) (在同一情况中)在穿透-斜坡平衡时。 这是天生的 包姆加特偏见相继冲动解析器,不是错误,也不是更大的迭代计数 或调音解想. createWorld({ sleep }) (以上) 将身体速度零 停留在您的阈值下; 休眠-高速大坝保持超出范围.
  • 仅收箱. 没有圆形或多边形形状.
  • 无关节,无CCD(连续相撞探测). 快速移动的瘦身能通地道 在一个步骤内互相穿透.
  • 没有ECS对接. World编号 :Body 是纯数据;如果使用电子数据,则直接输入ECS.
  • 宽相是蛮力 (所有AABB拒绝)——小身体计数的罚款,而不是空间 分区。 在经过之后,没有广泛的阶段.

见 API 规格。 。 。 .

许可证

阿帕奇 - 2.0

版本与发布记录

@flare-engine/dynamics 共发布 14 个版本,首次发布于 2026/08/25;过去 12 个月发布了 14 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.4.12latest2026/11/133 天前
0.4.112026/11/123 天前
0.4.102026/11/087 天前
0.4.82026/11/0610 天前
0.4.72026/11/0411 天前
0.4.62026/10/3115 天前

关于 @flare-engine/dynamics 的常见问题

@flare-engine/dynamics 是什么?

2D 刚性正体: 方向框、 接触多面体、 相继冲压解器

如何安装 @flare-engine/dynamics?

在项目目录运行 npm install @flare-engine/dynamics,或使用 pnpm add / yarn add / bun add。

@flare-engine/dynamics 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@flare-engine/dynamics 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@flare-engine/dynamics 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@flare-engine/dynamics 可以商用吗?

@flare-engine/dynamics 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@flare-engine/dynamics 的下载量有多少?

根据 npm 官方下载统计,@flare-engine/dynamics 在 2026/10/15 – 2026/11/13 这 30 天内被下载 2,215 次,日均约 74 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@flare-engine/dynamics 还在维护吗?

最新版本 0.4.12 发布于 2026/11/13(3 天前);至今共发布 14 个版本,其中过去 12 个月发布了 14 个;首次发布于 2026/08/25。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。