# @adatechnology/game-interactables 中文文档

规范地址：https://npmcn.com/package/%40adatechnology/game-interactables/

版本：0\.2\.17
npm 元数据更新时间：2026-11-06T05:13:55.364Z
中文译文更新时间：2026-11-06T07:56:16.136Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40adatechnology/game-interactables
原文对照：https://npmcn.com/package/%40adatechnology/game-interactables/?lang=original
项目主页：https://github.com/Andersonfrfilho/adatechnology-game-kit#readme
源码仓库：https://github.com/Andersonfrfilho/adatechnology-game-kit

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

- 包体积（解压后）：455 kB，8 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：1 个
- 首次发布：2026-10-23T15:06:50.572Z
- 最新版本发布：2026-11-06T05:13:54.911Z
- 近 30 天下载量：4044（2026-10-05 至 2026-11-03，npm 官方下载统计）
- 已发布版本数：20（近 12 个月 20 个）

## 中文简介

交互式世界物体的可移动部件、带有可取物品的容器、电网、燃料、逻辑管道、座位、软音量、效果、镜像和损坏.

## 安装

```sh
npm install @adatechnology/game-interactables
```

也可以使用：`pnpm add @adatechnology/game-interactables`、`yarn add @adatechnology/game-interactables`、`bun add @adatechnology/game-interactables`

## README

# @ adatech/ game- 交互

交互式世界物体的可移动部件(门、抽屉、盖子、接头等)、可取物品的容器和 确定性掠夺,逻辑电网(仪表、电路、插座、开关、装置)、燃料(气瓶、木炭)、逻辑水网, 座椅和床位,柔软的体积会摇动而不会被挡住,效果会释放出出弹器,镜像,相撞和损坏.

包裹什么也不画. 内容包描述对象为 `ObjectSpec` 数据(参见 `src/types.ts`),主持人将其添加到一个 `World`,电话 `update(dt)` 每个框架和绘制世界报告(部分形式、活性发射器、镜子、相撞器、摇摆等). `three` 无需.

## 安装

```sh
pnpm add @adatechnology/game-interactables
```

没有捆绑的浏览器( 全局为 `GameInteractables`:

```html
<script src="https://unpkg.com/@adatechnology/game-interactables/dist/index.global.js"></script>
<script>
  const world = GameInteractables.createWorld({ seed: 'level-1' })
</script>
```

## 使用量

```ts
import { createWorld, poseOf, type ObjectSpec } from '@adatechnology/game-interactables'

const world = createWorld({
  locale: 'en',
  seed: 'level-1',
  items: { can: { id: 'can', category: 'food', size: [0.07, 0.11, 0.07], weight: 0.4, stack: 6 } },
  loot: { pantry: { fill: 0.7, entries: [{ type: 'can', weight: 1, qty: [1, 3] }] } },
  strings: { en: { 'prompt.door.closed': 'Open {name}', 'prompt.door.open': 'Close {name}', 'type.cupboard': 'cupboard' } },
  onEvent: (e) => console.log(e),
})

const cupboard: ObjectSpec = {
  type: 'cupboard',
  parts: [{ id: 'door', pivot: [-0.4, 0, 0.3], motion: { kind: 'hinge', angle: -Math.PI / 2 }, sweep: [-0.4, 0.3, 0.4, 1.1], label: 'prompt.door' }],
  containers: [{ id: 'main', access: 'door', volume: { center: [0, 0.5, 0], half: [0.4, 0.4, 0.25] }, slots: [{ pos: [0, 0.1, 0], max: [0.3, 0.3, 0.3] }], loot: 'pantry' }],
}
world.add('kitchen_cupboard', cupboard, { x: 2, y: 0, z: -1, ry: Math.PI })

// once, after placing objects next to walls: the door never opens through them
world.fitSweep('kitchen_cupboard', 'door', (x, z) => isWall(x, z))

// every frame
world.update(dt)
const look = world.target({ x: cam.x, y: cam.y, z: cam.z, yaw, pitch }) // best interaction or null
if (look) hud.show(look.label) // "Open cupboard"
if (pressedUse && look) look.act()

// drawing a part: pose is relative to the part's pivot
for (const o of world.objects()) {
  for (const p of o.spec.parts ?? []) {
    const pose = poseOf(p.motion, world.partT(o.id, p.id)) // { position, rotation: { axis, angle }, scale }
  }
}
```

坐标在某一个 spec中是局部到对象: 前为 `+z`,起源于地上脚印的中心,米. `Transform.ry` 旋转 周围 `+y` 喜欢 `three.js` (单位:千美元)`+z` 转向 `+x` 以正角度表示). 视图 `yaw` 照相机惯例: `-z`。 。 。 .

## 行为

-   **部件** 向目标前进 `motion.speed` (默认为2.5 t/s). `requires` 在另一部分未打开时, 不要打开并关闭 拿着那个(门后一个抽屉关上门). `fitSweep(object, part, blocked)` 扫描样本 `sweep` 矩形(将叶子旋转为轴,将叶子翻译为幻灯片), 返回最大保险箱 `t` (当一部分宣布) `bounds`,整个闭塞-pose slab都是通过运动移动的,所以叶子厚度,轴向偏移和水平轴向计数),并永远将部分夹住. 部分算作打开 `t >= 0.5` (或被夹住的限度的90%). 共享的部件 a `group` 一起移动 : `setPart` 或切换到任何成员都会设定所有成员的目标(盲窗、幕板).
-   **默认互动**: 当一个 spec 不存在时 `interactions`,世界产生它们。 标签部件给 `toggle_part`; 容器无 访问部分给定 `open_container`; 设备、开关、固定装置、燃烧器(和 `ignite` 页:1 `needsIgnition`),气阀和座椅得到 匹配动作。 明确 `interactions` 替换衍生的。 药是 `part.<id>`, (中文(简体) ), `open.<container>`, (中文(简体) ), `device.<id>`, (中文(简体) ), `channel.<id>`, (中文(简体) ), `switch.<id>`, (中文(简体) ), `fixture.<id>`, (中文(简体) ), `burner.<id>`, (中文(简体) ), `ignite.<id>`, (中文(简体) ), `fuel.<id>`, (中文(简体) ), `seat.<id>`; 全世界 `object:interactionId`。 。 。 .
-   **标签**:世界抬头看 `<label>.open|.closed` (部件、阀门、容器)或 `<label>.on|.off` (装置、固定装置、燃烧器, 开关) `<label>`,然后是引擎默认值(`prompt.open`, (中文(简体) ), `prompt.turn_on`(中文(简体) ). `{name}` 改为: `type.<type>` 或人类化 类型编号。 标签从不带"E:"等密钥提示;主机会自加.
-   **有结构的提示**: 每一个 `Interactable` 还有 `verb` ("开口")并 `noun` ("冰箱")所以一个主机可以分别样式 (单位:千美元)`object` 是自有对象的 ID。 条目 `<key>.verb` 编号 : `<key>.object` 在语言中获胜;否则标签的第一个词是动词, 其余的名词,一个单词提示使用对象的类型名作为名词.
-   **可用性**数字 : `Interactable.available` 与一个 `reason` (一个本地密钥 : `requires_open`, (中文(简体) ), `no_power`, (中文(简体) ), `locked` 何时 `canInteract` 拒绝, `already_lit`, (中文(简体) ), `needs_ignition`, (中文(简体) ), `turn_on_first`· ; `world.t(reason)` 是文本),而不能使用交互.
-   **目标**数字 : `target(eye, { reach = 1.8, cone = 0.45, filter?, kinds?, includeUnavailable? })` 按距离和角度对视图的分数 向上转 无法获得的相互作用(闭合容器) `take`编号 :`read`,错误的一半 `ignite`,一个部分门由 `requires`跳过(...) 除非 `includeUnavailable`· ; `kinds` 限制动作类型和 `filter` 这是任何上游。 硬线灯(装置) `kind: 'lamp'` 带有 `circuit`,没有 `plug`,没有 `part`获得 **没有** 衍生相互作用:交换机和 `setDevice` 驱动它,所以它永远不会偷 交互键.
-   **从代码驱动状态**数字 : `setDevice(object, device, on)`, (中文(简体) ), `setFixture(object, fixture, on)` 财务报告和审定财务报表 `setBurner(object, burner, on)` 做点什么 切换的, `device`编号 :`fixture`编号 :`burner` 事件, `no_power` ),并当国家不变时保持安静.
-   **对撞机**数字 : `colliders({ merge: true, gap = 0.02, slack = 0.1 })` 同一物体相重叠或相邻的固定框(相同) 旋转),当合并框最多添加时 `slack` 额外音量; 门相撞者保持相隔. `mergeColliders(list, opts)` 导出为 列表中已经列出.
-   **集装箱**: 内容来自 `contents` 或有决定力的掠夺物 `seed + object id + container id`。当一个项的大小适合一个槽 是在槽内 `max` (宽度和深度可以互换). `take` 需要打开容器,物品可以摘取和发出 `pickup`。 。 。 .
-   **权力**数字 : `grid`,每个回路的断路器(默认),套接字(可选在回路上)和插入套接字的设备(`auto` = 最近的免费 2米内插座,遍及全世界)或硬接通回路. `powered = grid && breaker && socket found`打开但 无动力继续,报告 `powered: false` 并发出 `no_power` 留言。 切换到列出的设备( S)`object:device` 或当地身份证明). 这个 `toggle_breaker` 动作( e)`{ do: 'toggle_breaker', circuit, part? }`)从断面板上翻转一个回路,镜像可选摇滚乐 `part` (t = 1起;拒绝时,该部分由 `PartSpec.requires`,例如闭合面板门)并使用提示符 `prompt.breaker_on|off` (单位:千美元)`{circuit}` 是动作的 `name` 或电路编号).
-   **燃料**:燃烧器需要燃料,对于有阀门的瓶子,阀门会打开. `fuel: 'auto'` =2米以内最近的气体来源。 气体被消耗 被点燃时; 熄灭或关闭阀门会熄灭火焰, 当阀门打开时,一个没有燃气灯的气把手会自己打开。 木炭需求 `ignite`烧到空出 `toggle_burner` 把它拿出来. 起火后,固体燃料20 s的烟雾排放器逐渐消失.
-   **水费**: 油罐车(`capacity`, (中文(简体) ), `level`, (中文(简体) ), `rainArea`),一个默认的罐体,固定装置在运行和供应时会流动. 与 `options.waterSupply`固定装置 画出它(`flow / 60 * dt` 升,一分刷 `volume` 一次). 干燥固定装置保持"上" 但报告 `flowing: false`。 。 。 . 一个设备 `fixture: '<fixtureId>'` (相同的物体,例如洗衣机内接器) 固定的驱动器:在设备打开和 电源,当它关闭或失去电源时停止,没有自己的相互作用.
-   **刚性互动**数字 : `InteractionSpec.requires = { object, part }` (world-wide object id) 仅允许交互,而其中 部分打开( o)`t >= 0.5`: `target` 跳过它 `act` 否则拒绝(柜子门后有气阀).
-   **席位**:每个座位一个演员. `sit` 返回世界眼睛的位置和方向, `stand` 返回世界退出点.
-   **软音量** 永远不要挡住,永远不要相撞. `push(pos, radius, vel)` 挥之以去;他们靠被拦住的泉水安顿下来。 风又加一 小型吞噬力。 A 类 `panel` 带有 `part` 从前面推入时打开.
-   **损害**数字 : `hp` 每个目标。 燃料爆炸后被摧毁的气体源(`radius = 2 + level / 5`和空地;一个被损坏的坦克一次泄漏 下水道; 玻璃只是一个事件.
-   **保存/装入**数字 : `serialize()` 简洁的JSON; `load()` 将其恢复到一个添加了相同对象的世界。 擦拭限制( E)`fitSweep`已经 未保存, 装入后再次调用 .

## API 密码

```ts
createWorld(options?: WorldOptions): World
```

`WorldOptions`数字 : `locale`, (中文(简体) ), `strings`, (中文(简体) ), `items`, (中文(简体) ), `loot`, (中文(简体) ), `seed`, (中文(简体) ), `grid`, (中文(简体) ), `rain`, (中文(简体) ), `wind`, (中文(简体) ), `waterSupply`, (中文(简体) ), `onEvent`, (中文(简体) ), `canInteract`。 。 。 .

| 组 | 成员 |
| --- | --- |
| 对象 | `add(id, spec, transform)`, (中文(简体) ), `remove(id)`, (中文(简体) ), `get(id)`, (中文(简体) ), `objects()` |
| 框架 | `update(dt)` |
| 互动 | `interactables()`, (中文(简体) ), `target(eye, TargetOptions)`, (中文(简体) ), `act(id, actor?)` |
| 部件 | `partT`, (中文(简体) ), `setPart(object, part, target, instant?)`, (中文(简体) ), `fitSweep(object, part, blocked)` |
| 驱动 | `setDevice(object, device, on)`, (中文(简体) ), `setFixture(object, fixture, on)`, (中文(简体) ), `setBurner(object, burner, on)` |
| 集装箱 | `contents`, (中文(简体) ), `accessible`, (中文(简体) ), `take`, (中文(简体) ), `put`, (中文(简体) ), `slotPosition` |
| 权力 | `power.grid`, (中文(简体) ), `setGrid`, (中文(简体) ), `setBreaker`, (中文(简体) ), `breaker`, (中文(简体) ), `isPowered`, (中文(简体) ), `isOn`, (中文(简体) ), `pluggedInto`, (中文(简体) ), `channel` |
| 燃料 | `fuelLevel(object, fuel)`, (中文(简体) ), `isLit(object, burner)` |
| 水费 | `water.setDefaultTank`, (中文(简体) ), `level`, (中文(简体) ), `refill`, (中文(简体) ), `setRain`, (中文(简体) ), `isFlowing` |
| 席位 | `sit`, (中文(简体) ), `stand`, (中文(简体) ), `seatOf` |
| 软 | `push`, (中文(简体) ), `sway`, (中文(简体) ), `setWind` |
| 绘制 | `emitters()`, (中文(简体) ), `mirrors(eye, maxDistance?, count?)`, (中文(简体) ), `colliders({ merge? })` |
| 损害 | `damage(object, target, amount, kind?)`, (中文(简体) ), `hp(object, target)` |
| 文本 | `t(key, vars?)`, (中文(简体) ), `setLocale(locale)` |
| 保存 | `serialize()`, (中文(简体) ), `load(state)` |

独立助手 : `rng(seed)`, (中文(简体) ), `generateLoot(tables, tableId, slots, seed, items)`, (中文(简体) ), `poseOf(motion, t)`, (中文(简体) ), `localToWorld(transform, v)`, (中文(简体) ), `worldToLocal`, (中文(简体) ), `rotY`, (中文(简体) ), `rotateAxis`, (中文(简体) ), `fitsSize`, (中文(简体) ), `fitsSlot`, (中文(简体) ), `resolveStrings(locale, extra)`, (中文(简体) ), `locales`, (中文(简体) ), `format`, (中文(简体) ), `pickLocale`。 。 。 .

`poseOf(motion, t)` 返回时 `{ position, rotation: { axis, angle }, scale }` 相对于该部分的支点:轴,摇杆和拐杆旋转, 幻灯片翻译 `axis * distance * t`缩放 `axis`。 。 。 .

## 活动

`onEvent` 收到每个更改 :

| `type` | 字段 |
| --- | --- |
| `part` | `object`, (中文(简体) ), `part`, (中文(简体) ), `t`, (中文(简体) ), `target` (在一个新目标上,再次到达) |
| `pickup` | `object`, (中文(简体) ), `container`, (中文(简体) ), `slot`, (中文(简体) ), `stack`, (中文(简体) ), `actor` |
| `device` | `object`, (中文(简体) ), `device`, (中文(简体) ), `on`, (中文(简体) ), `powered`, (中文(简体) ), `channel?` |
| `switch` | `object`, (中文(简体) ), `switch`, (中文(简体) ), `on` |
| `fixture` | `object`, (中文(简体) ), `fixture`, (中文(简体) ), `on`, (中文(简体) ), `flowing` |
| `burner` | `object`, (中文(简体) ), `burner`, (中文(简体) ), `on`, (中文(简体) ), `lit` |
| `seat` | `object`, (中文(简体) ), `seat`, (中文(简体) ), `actor`, (中文(简体) ), `seated` |
| `damage` | `object`, (中文(简体) ), `target`, (中文(简体) ), `hp`, (中文(简体) ), `destroyed` |
| `explosion` | `object`, (中文(简体) ), `pos`, (中文(简体) ), `radius` |
| `leak` | `object`, (中文(简体) ), `target`, (中文(简体) ), `pos` |
| `message` | `key`, (中文(简体) ), `text` (当地化): `no_power`, (中文(简体) ), `no_gas`, (中文(简体) ), `no_water`, (中文(简体) ), `locked`, (中文(简体) ), `empty`, (中文(简体) ), `full`,或项目文本密钥 `read` |
| `power` | `grid` |
| `container` | `object`, (中文(简体) ), `container`, (中文(简体) ), `open` (一个打开的架子是"打开") |

## 语言

引擎级别字符串存在于 `en` 财务报告和审定财务报表 `pt-BR`数字 : `prompt.open`, (中文(简体) ), `prompt.close`, (中文(简体) ), `prompt.turn_on`, (中文(简体) ), `prompt.turn_off`, (中文(简体) ), `prompt.take`, (中文(简体) ), `prompt.sit`, (中文(简体) ), `prompt.lie_down`, (中文(简体) ), `prompt.get_up`, (中文(简体) ), `prompt.light`, (中文(简体) ), `prompt.change_channel`, (中文(简体) ), `prompt.read`, (中文(简体) ), `prompt.open_valve`, (中文(简体) ), `prompt.close_valve` 编辑 上面的信息。 内容包通过 `options.strings`;未知的密钥会倒回英文,再倒回密钥本身.

## 销毁

光谱带标签 共享破坏 SDK, `@adatechnology/game-destruction`;此软件包不依赖它,只存储平面标识.

-   `PartSpec.destruction`数字 : `{ material, joint?, piece?, explodes?, contains? }`。 。 。 . `material` 是一个 SDK 材料 id (`steel`, (中文(简体) ), `mdf`, (中文(简体) ), `glass`... `joint` sDK联合型(`screw`, (中文(简体) ), `bolt`, (中文(简体) ), `nail`, (中文(简体) ), `weld`, (中文(简体) ), `glue`, (中文(简体) ), `hinge`, (中文(简体) ), `clip`, (中文(简体) ), `tie`, (中文(简体) ), `mortar`, (中文(简体) ), `fused`, (中文(简体) ), `stem`, (中文(简体) ), `piece` 何为部分(`door`, (中文(简体) ), `drawer`, (中文(简体) ), `lid`(......) (中文(简体) ). `explodes` 财务报告和审定财务报表 `contains` 形状和SDK一样 `PartSpec`。 。 。 .
-   `ObjectSpec.destruction`:静态体的同名标记(所有不是可移动的部分).

主机从标记和路线打出SDK部件,向SDK起火并起爆. `DamageSpec` 财务报告和审定财务报表 `world.damage` 被贬损:它们继续工作,但没有新的特性.

## 葡萄牙

运行时间 sem 渲染器 para objetos interativos do mundo: portas, grattas e tampas que se movem, 收受者 com itens e roble deminístico por emente, rede elétrica lógica (医疗,电路, tomadas, 中继器, aparelhos), combustível (botijão de gás, carvão), rede de água lógica, assentos e camas, supers macios (cortinas, folhagem) que balançam sem blopear, issorers de efetos, espelhos, colisores e dano. 中国植物物种信息数据库.

```ts
const world = createWorld({ locale: 'pt-BR', seed: 'fase-1' })
world.add('armario', especificacao, { x: 2, y: 0, z: -1, ry: Math.PI })
world.update(dt)
const alvo = world.target({ x, y, z, yaw, pitch }) // ex.: "Abrir armário"
alvo?.act()
```

(原始内容存档于2018-10-21) (英语). O pacote não desenha nada: você informationa o `ObjectSpec` (dados),查马 `update(dt)` 一个卡达四分卫 o desenha o que o mundo reportar. 维基百科中的相关条目: 克多克多克多克多克多克多克多克多克多克多克多克多克多克多克多克多克 Os textos do (英语) (英语) 发动机(`Abrir`, (中文(简体) ), `Ligar`, (中文(简体) ), `Sem energia`, (中文(简体) ), `Sem gás`, (中文(简体) ), `Sem água`. . . . . . `pt-BR`; os pacotes de conteúdo 亩地centam as suas chaves em `strings`。 。 。 .

## 销毁代表

过 `destruction: { hitPart }` (形状 `DestructionWorld.hitPart` 从 `@adatechnology/game-destruction`,不依赖它) `createWorld` 财务报告和审定财务报表 `world.damage` 把它当作一个 `blunt` (单位:千美元)`explosive` 页:1 `gas`, (中文(简体) ), `slash` 页:1 `fabric`击出 `energy: amount`世界停止了自己的账簿管理 `world.hp` 返回时 `null`没有它,堕落者 `DamageSpec` 行为不变.

## 常见问题

### @adatechnology/game-interactables 是什么？

交互式世界物体的可移动部件、带有可取物品的容器、电网、燃料、逻辑管道、座位、软音量、效果、镜像和损坏\.

### 如何安装 @adatechnology/game-interactables？

在项目目录运行 npm install @adatechnology/game-interactables，或使用 pnpm add / yarn add / bun add。

### @adatechnology/game-interactables 支持 TypeScript 吗？

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

### @adatechnology/game-interactables 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @adatechnology/game-interactables 可以商用吗？

@adatechnology/game-interactables 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @adatechnology/game-interactables 的下载量有多少？

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

### @adatechnology/game-interactables 还在维护吗？

最新版本 0\.2\.17 发布于 2026/11/06（今天）；至今共发布 20 个版本，其中过去 12 个月发布了 20 个；首次发布于 2026/10/23。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

