template/docs/intermediate/tile-store.md
unanmed 3aae27a939 docs(10-11): 新增图块存储(TileStore)文档并注册侧边栏
- 新增 docs/intermediate/tile-store.md:讲解 state.tileStore 与图块数字/id 区别,附 D-48 实操
- config.ts 基础接口组加入「图块存储」侧边栏条目(8→9)
- 10-11-READER-REVIEW.md 记录 U-03 完成
2026-10-19 15:45:48 +08:00

78 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 图块存储
地图上每一格摆的都是一个**图块**,而每种图块在内容层 `src/content/tile.jsonc` 里都有一条定义(编号、名字、类型、通行性、默认事件等)。这些定义由 `state.tileStore`(类型 `ITileStore`)统一存放与查询。本篇讲清它存的是什么、**图块数字**与**图块 id** 的区别,以及最常用的几个查询接口。
若你还不熟悉 `state` 从哪来,见[数据端总览](./data-state-overview.md)。
## 图块数字与图块 id
同一个图块有两个「名字」,用途不同:
- **图块数字(num)**:一个整数编号,以内容层 `tile.jsonc` 每个条目的 `num` 字段为准。地图数据里存的都是它——地图矩阵、`Uint32Array` 等一律用数字,因为数字**紧凑、按下标检索快**(一张地图可达成千上万格)。
- **图块 id**:一个稳定的字符串标识(如 `blueShopLeft`),由内容与作者使用,**可读、可长期引用**。
两者必须能互相换算,所以 `state.tileStore` 内部同时保存了两张映射表(`id → num` 与 `num → id`),再加上每个图块数字对应的**默认事件**。于是你写地图时用数字、配置与交流时用 id,随时都能换算。
## 常用接口
| 接口 | 作用 |
| ----------------- | -------------------------------------------------------------------------------- |
| `getData(num)` | 按图块数字取完整原始定义(`ITileRawData`;不存在返回 `null`) |
| `getType(num)` | 按图块数字取图块逻辑类型(`TileType`;不存在返回 `TileType.Unknown`) |
| `getEvent(num)` | 按图块数字取默认事件(`ReadonlyMap`,键为优先级、值为事件 id;无事件返回空 Map) |
| `addTile(data)` | 添加一条图块定义(`num` 或 `id` 冲突时告警并覆盖,一般由加载流程调用) |
| `idToNumber(id)` | 图块 id → 图块数字(不存在返回 `undefined`) |
| `numberToId(num)` | 图块数字 → 图块 id(不存在返回 `undefined`) |
| `num(token)` | 传入数字或 id,统一返回图块数字(id 未知返回 `undefined`) |
| `id(token)` | 传入数字或 id,统一返回图块 id(数字未知返回 `undefined`) |
| `identity(token)` | 传入数字或 id,返回 `[图块数字, 图块 id]`(未知返回空数组 `[]`) |
> 日常写作主要用 `num` / `id` 这一对:传入哪一种都能得到另一种。`idToNumber` / `numberToId` 则是更直白的单向往返写法。
内容层里一条图块定义大致长这样(节选自 `tile.jsonc`):
```jsonc
{
"num": 1,
"id": "blueShopLeft",
"type": 2,
"events": {}
}
```
## 实操:在 id 与数字之间换算
**目标**:已知图块的字符串 id,拿到它对应的图块数字(地图读写用),并验证能反查回同一个 id。
**改哪里**:任何能访问到 `state` 的位置——例如某个事件函数或钩子里。
**复制什么**:
```ts
// 图块 id → 图块数字(地图读写用的都是数字)
const num = state.tileStore.num('blueShopLeft')!;
// 图块数字 → 图块 id(读回可读的名字)
const id = state.tileStore.id(num);
```
> 复制说明:片段已省略 `import`(这里用到的都是 `state` 上的成员,一般无需额外引入);若编辑器提示缺少某个名字,再在顶部补对应的 `import`(详见 [代码基础](./code-basics.md) 的「照抄教程里的代码时,怎么处理 import」)。
**改什么**:把 `'blueShopLeft'` 换成你的图块 id。
**怎么验证**:`num` 应等于内容层 `tile.jsonc` 中该条目 `num` 字段的值;`state.tileStore.id(num)` 应反查回同一个 id。
**注意**:token 未知时换算会返回 `undefined`(`num` / `id`)。`!` 只是告诉编辑器「我确信它存在」,若该 id 并不存在,拿到的就是 `undefined`。要一次拿两个值、并按存在性判断,可以用 `identity`——未知时它返回空数组 `[]`(长度为 0):
```ts
const pair = state.tileStore.identity('blueShopLeft');
if (pair.length === 2) {
const [num, id] = pair; // 已知存在:num 为数字,id 为字符串
}
```
## 与其它篇章的联系
- 地图上读写图块(`setBlock` / `getBlock` 等)用的正是图块数字,见[地图图块](./map-tiles.md);
- 道具接口(如 `addItem`)的 `item` 参数同样接受图块数字或 id,见[勇士道具](./hero-items.md)。