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 完成
This commit is contained in:
unanmed 2026-10-19 15:45:48 +08:00
parent 66a75b08ad
commit 3aae27a939
3 changed files with 103 additions and 3 deletions

View File

@ -442,3 +442,24 @@
- 备注:D-48 明确不写「发布前/数量类无关信息」,与 batch 3 U-20 曾写入的「发布前约 100 个」冲突;本批按 D-48 删去该数字表述,仅保留「内置事件集已完整」的视角。
- 结论:中级教程 24 篇的 D-48 实操改写(概念 / 基础 / 战斗 / 其他四组)至此全部覆盖。
---
## 用户循环 · U-03 记录(新增《图块存储》基础接口文档)
**范围:** 用户修订循环第 1 轮 `U-03`——图块数字与图块 id 的区别、为何要区分,需**新增一篇基础接口文档**简述 `TileStore` 基本概念与 `id()` / `num()` 接口。命名与位置已经用户批准:文件名 `tile-store.md`、显示名「图块存储」、置于 `map-tiles.md` 之后、归 `基础接口` 组(8 → 9 条)。
### 逐条处置
| # | 处置 | 改动文件 |
| --- | --- | --- |
| U-03 | 新增 `docs/intermediate/tile-store.md`:①讲清 `state.tileStore`(`ITileStore`)是图块定义的存放处;②解释**图块数字(num)**与**图块 id** 的区别与**为何两者并存**(地图矩阵 / `Uint32Array` 用数字以求紧凑与检索快,id 可读稳定供内容与作者使用,store 内部维护 `id → num`、`num → id` 双向映射并保存默认事件);③按源码逐条列出接口 `getData` / `getType` / `getEvent` / `addTile` / `idToNumber` / `numberToId` / `num` / `id` / `identity`;④D-48 六步实操(id ↔ 数字换算,片段不含 `import`,附标准复制说明);⑤注意项写明未知 token 返回 `undefined`、`identity` 未知返回 `[]`;⑥交叉引用 `map-tiles.md` 与 `hero-items.md`。 | `tile-store.md`(新增) |
| U-03 | `docs/.vitepress/config.ts` 在 `/intermediate/` 的 `基础接口` 组、`地图图块` 之后加入 `{ text: '图块存储', link: '/intermediate/tile-store' }`;`nav`、其它 sidebar 键与既有配置一律未动。 | `config.ts` |
### 校验
- 源码核对:`packages-user/data-common/src/store/types.ts`(`ITileStore` 全部 9 个方法签名、`ITileRawData.num` / `id` / `events` / `type`)、`packages-user/data-common/src/store/tileStore.ts`(`dataMap` / `idMap` / `numMap` / `eventMap` 四表、`num` / `id` / `identity` 的 `undefined` / `[]` 行为)、`packages-user/data-common/src/types.ts`(`IDataCommon.tileStore`)、`src/content/tile.jsonc`(条目 `num` / `id` 形态)。
- 结构门禁:新篇 CRLF、单 H1(`STRUCT-OK`)。
- 格式门禁:prettier(D-45,`endOfLine: crlf`)已对新文件与 `config.ts` 跑过。
- 构建门禁:`cmd /c "pnpm exec tsx docs/.vitepress/init.ts && pnpm docs:build"` → **green**,输出 `build complete`,dead link = 0(侧边栏 `/intermediate/tile-store` 链接可解析)。
- 边界:仅新增 1 篇文档 + 1 条侧边栏;未改任何生产代码;未引入指向 `docs/advanced/` 的真实链接(D-47)。

View File

@ -17,9 +17,7 @@ export default defineConfig({
themeConfig: {
// https://vitepress.dev/reference/default-theme-config
outline: [2, 3],
nav: [
{ text: '中级教程', link: '/intermediate/data-vs-render' }
],
nav: [{ text: '中级教程', link: '/intermediate/data-vs-render' }],
sidebar: {
'/intermediate/': [
{
@ -77,6 +75,10 @@ export default defineConfig({
text: '地图图块',
link: '/intermediate/map-tiles'
},
{
text: '图块存储',
link: '/intermediate/tile-store'
},
{
text: 'Flag 变量',
link: '/intermediate/flags'

View File

@ -0,0 +1,77 @@
# 图块存储
地图上每一格摆的都是一个**图块**,而每种图块在内容层 `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)。