# @flare-engine/dynamics 中文文档

规范地址：https://npmcn.com/package/%40flare-engine/dynamics/

版本：0\.4\.12
npm 元数据更新时间：2026-11-12T19:45:51.688Z
中文译文更新时间：2026-11-14T22:52:20.123Z
软件包许可：Apache-2\.0

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40flare-engine/dynamics
原文对照：https://npmcn.com/package/%40flare-engine/dynamics/?lang=original
项目主页：https://github.com/grzott/flare-engine#readme
源码仓库：https://github.com/grzott/flare-engine

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：214 kB，12 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=20
- 运行依赖：1 个
- 首次发布：2026-08-25T11:20:06.525Z
- 最新版本发布：2026-11-12T19:45:51.251Z
- 近 30 天下载量：2215（2026-10-15 至 2026-11-13，npm 官方下载统计）
- 已发布版本数：14（近 12 个月 14 个）

## 中文简介

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

## 安装

```sh
npm install @flare-engine/dynamics
```

也可以使用：`pnpm add @flare-engine/dynamics`、`yarn add @flare-engine/dynamics`、`bun add @flare-engine/dynamics`

## README

# @flare-engine/动力学

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

## 安装

```sh
bun add @flare-engine/dynamics
```

## 使用量

```ts
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` 是零分配器形式.

```ts
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` 烘焙:

```ts
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 规格](https://github.com/grzott/flare-engine/blob/main/docs/design/api-specs.md#flare-enginedynamics--8kb-gzip)。 。 。 .

## 许可证

阿帕奇 - 2.0

## 常见问题

### @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 和提交记录判断。

