mirror of
https://github.com/motajs/template.git
synced 2026-10-29 04:10:18 +08:00
docs(10-27): U7 修订批次D(事件/图块)
This commit is contained in:
parent
cc3c4e8277
commit
112e46f1e1
@ -74,3 +74,31 @@
|
||||
- U6-22:`enemy-context-and-combat.md` 删去 `setFloor` / `resize` / `bindHero` 的手动置脏操作说明,改为「正常换图流程已处理好」;`getComputedEnemy()` 改为「读取时按需刷新」的说法;「局部刷新与全量重建」由 41 行压到 7 行(约 1/6),只保留「日常自动刷新、少数直接改模板才 `markDirty`、新光环需全量重建、`query()` 登记依赖」四点;收束示例与验证示例删去 `requestRefresh`,边界条目同步。
|
||||
|
||||
**验证:** `node node_modules/prettier/bin/prettier.cjs --write` 三篇文档 → CRLF、单 H1;`cmd /c "pnpm exec tsx docs/.vitepress/init.ts && pnpm docs:build"` 退出 0、`build complete in 18.09s`、无 dead link。
|
||||
|
||||
---
|
||||
|
||||
## 第 2 轮(2026-10-22,待执行)
|
||||
|
||||
| # | 用户意见 | 落点 |
|
||||
|---|----------|------|
|
||||
| U7-01 | 事件视图说法有误:`eventView.set(num)` 不会重置为默认事件,它要求第二个 `event` 参数必填;该注释来源不明,需修正 | `point-and-tile-events.md`(及事件相关) |
|
||||
| U7-02 | 不要在文档里写「模块级复用 / 不要在调用处内联 new」这类说明;用户只是要求改写法,读者不需要知道这些细节 | `custom-range.md` |
|
||||
| U7-03 | `transferToDynamic` 的 `keepEvent` 说明有误:**以引擎方法注释为准**——「不论是否 keepEvent,源图块的图块事件都会被清空」。若注释与实现不一致,按注释写,并**向用户报告**(长期规范 D-72) | `static-vs-dynamic-tiles.md` |
|
||||
| U7-04 | 动态图块的 `mover` 未讲却讲了 `moveBlock`。应先用**引用**指向高级 I 的 mover 文档(不重复讲概念/接口),再讲 `moveBlock`;顺序必须 mover 在前、moveBlock 在后 | `static-vs-dynamic-tiles.md` |
|
||||
| U7-05 | 指令码位宽在高级 II 不需要讲,只提一嘴:99.9% 情况用不完 255 个指令码;如有极小概率超过,参考高级 III 指定文档。细节放高级 III | `custom-replay-command.md` |
|
||||
| U7-06 | 录像的典型例子「选择框」不是让你改成代码示例;原来的代码示例很好,改回去。选择框一般内置 | `custom-replay-command.md` |
|
||||
| U7-07 | `NoPath` 是正常输出,不是错误;被怪物挡着去不了很正常。当前「NoPath 处理建议」不对,只需说明「找不到可行路径」,无需处理 | `pathfinding.md` |
|
||||
| U7-08 | 假定编辑器已完成:不要写「编辑器就位前改文件、就位后用编辑器」。需要编辑器的地方只写「需要编辑器」标识,不讲没有编辑器时怎么做。所有 `.jsonc` 都由编辑器负责,涉及部分先写占位(长期规范 D-73) | 全部 |
|
||||
|
||||
**状态:执行中**(批次 D 已完成 U7-01、U7-03、U7-04;其余待执行)
|
||||
|
||||
### 批次 D(U7-01、U7-03、U7-04)执行记录(2026-10-22)
|
||||
|
||||
- U7-01:`point-and-tile-events.md` 删去「`set(num)` 会重置为默认事件」的错误注释,改为「同一优先级已有事件时覆盖并告警」;正文明确 `ILayerEventView.set(priority, event)` 两个参数都必填、不会顺带恢复默认事件,并说明恢复默认事件应使用 `tile.set(num)` / `tile.restoreDefaultEvents()`。表内与边界条目中的 `set(num)` 统一写作 `tile.set(num)`,避免与事件视图的 `set` 混淆。
|
||||
- U7-03:`static-vs-dynamic-tiles.md` 按 `IMapLayer.transferToDynamic` 的方法注释改写(D-72):`keepEvent` 只决定是否把源静态图块的图块事件复制到动态实例,**不论取值如何,源静态图块的图块事件都会被清空**;删去原「`false` 时源实例完全不被触碰、旧事件仍保留」的不对称说法。`point-and-tile-events.md` 中同一处描述与交叉引用同步修正,避免两篇互相矛盾。
|
||||
- U7-04:`static-vs-dynamic-tiles.md` 在 `moveBlock` 之前新增「移动器 mover」小节,用 D-47 非断链占位 `高级 I · 移动 Mover` 指向待补的高级 I 文档,不重复 mover 的概念与接口;随后才讲 `moveBlock`,并补上 `mover.start()` / `onEnd` 的实际调用顺序。
|
||||
|
||||
**待报告(D-72):** `mapLayer.transferToDynamic` 的方法注释称「不论是否保留,此格的静态图块事件都会被清空」,但当前实现仅在 `keepEvent` 为 `true` 的分支内调用 `staticTile.tileEvent().clear()`;`keepEvent` 为 `false` 时,若该坐标的静态图块实例已存在,其事件不会被清空。现有单测未覆盖「先 `getTile` 再以 `false` 转换」的情形,因此未暴露。文档按注释书写。
|
||||
|
||||
**验证:** `node node_modules/prettier/bin/prettier.cjs --write` 两篇文档 → CRLF、单 H1;`cmd /c "pnpm exec tsx docs/.vitepress/init.ts && pnpm docs:build"` 退出 0、`build complete in 19.04s`、无 dead link。
|
||||
|
||||
|
||||
@ -6,17 +6,17 @@
|
||||
|
||||
## 两种事件的区别
|
||||
|
||||
| 项目 | 点事件 | 图块事件 |
|
||||
| ---------- | --------------------------------------------------------------------- | ------------------------------------ |
|
||||
| 归属 | 坐标 | 图块实例 |
|
||||
| 获取方式 | `layer.event(x, y)`、`layer.getPointEvent(x, y)`、`tile.pointEvent()` | `tile.tileEvent()` |
|
||||
| 换图块后 | 仍留在原坐标 | 由 `set(num)` 恢复为该图块的默认事件 |
|
||||
| 图块移动后 | 不跟随 | 跟随图块实例 |
|
||||
| 典型用途 | 「勇士踩进这一格」「进入这一区域」 | 「可推动的石头自带的事件」 |
|
||||
| 项目 | 点事件 | 图块事件 |
|
||||
| ---------- | --------------------------------------------------------------------- | ----------------------------------------- |
|
||||
| 归属 | 坐标 | 图块实例 |
|
||||
| 获取方式 | `layer.event(x, y)`、`layer.getPointEvent(x, y)`、`tile.pointEvent()` | `tile.tileEvent()` |
|
||||
| 换图块后 | 仍留在原坐标 | 由 `tile.set(num)` 恢复为该图块的默认事件 |
|
||||
| 图块移动后 | 不跟随 | 跟随图块实例 |
|
||||
| 典型用途 | 「勇士踩进这一格」「进入这一区域」 | 「可推动的石头自带的事件」 |
|
||||
|
||||
点事件属于**坐标**。同一坐标换掉图块、清空图块,点事件都还在。`layer.event(x, y)` 按坐标取可写视图;坐标不在地图内时返回 `null`。`layer.getPointEvent(x, y)` 不是视图,它只是 `event(x, y)?.get()` 的简写,返回只读映射,不能用来修改事件。
|
||||
|
||||
图块事件属于**图块实例**。静态图块与动态图块各自持有一个事件视图,通过 `tile.tileEvent()` 读写。图块实例被销毁时,它的事件也随之消失;静态图块转动态、动态图块转静态时是否保留,由转换接口的 `keepEvent` 决定。
|
||||
图块事件属于**图块实例**。静态图块与动态图块各自持有一个事件视图,通过 `tile.tileEvent()` 读写。图块实例被销毁时,它的事件也随之消失。静态图块转动态时,`keepEvent` 决定是否把源实例的事件复制到动态实例;无论是否复制,源静态图块的事件都会被清空。动态图块转静态时,`keepEvent` 决定动态实例的事件是否写回静态图块。
|
||||
|
||||
`tile.pointEvent()` 容易让人误会:它并不拥有事件,只是按图块**当前**的 `locator` 去取那个坐标的点事件视图。动态图块移动后,它读到的是新坐标的点事件,而不是出发地的事件。
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
动态图块移动时,移动器只更新它的 `locator` 与图层索引,不会触碰事件:
|
||||
|
||||
- **点事件不跟随**:事件仍按原坐标缓存。图块离开后,原坐标的点事件还在;新坐标的点事件与它无关。`dynamic.pointEvent()` 只是按新坐标重新查一次视图,所以移动后通常读到空事件。
|
||||
- **图块事件跟随**:事件保存在图块实例自己身上,`locator` 变了,事件视图不变。静态转动态时 `keepEvent` 为 `true`(默认)会把源实例的事件复制过来;动态转静态时同理。
|
||||
- **图块事件跟随**:事件保存在图块实例自己身上,`locator` 变了,事件视图不变。静态转动态时 `keepEvent` 为 `true`(默认)会把源实例的事件复制过来;不论取值如何,源实例的事件在转换后都会被清空。动态转静态时,`keepEvent` 决定是否把事件写回静态图块。
|
||||
|
||||
```ts
|
||||
import { FaceDirection } from '@user/data-common';
|
||||
@ -63,7 +63,7 @@ async function moveTileAndObserveEvents(
|
||||
}
|
||||
```
|
||||
|
||||
注意 `keepEvent` 为 `false` 时,静态图块的事件不会被复制,但源静态图块实例本身也不会被清空。这个不对称行为在[静态图块与动态图块](./static-vs-dynamic-tiles.md)的「双向转换」里有详细说明。
|
||||
`keepEvent` 只决定是否把源静态图块的图块事件复制到动态实例;不论取值如何,源静态图块的图块事件都会被清空。细节见[静态图块与动态图块](./static-vs-dynamic-tiles.md)的「双向转换」。
|
||||
|
||||
## 事件视图接口
|
||||
|
||||
@ -85,7 +85,9 @@ async function moveTileAndObserveEvents(
|
||||
| `clear()` | 清空当前事件 |
|
||||
| `markPure()` | 把当前事件标记为新的参考基准 |
|
||||
|
||||
`set` 的 `event` 参数是**事件 id**,不是事件对象。这个 id 必须已经在 `state.eventStore` 中注册过(`state.eventStore.addEvent(id, event)`);否则执行到这里时找不到对应事件。同一个优先级只能挂一个事件,重复设置会覆盖并告警 code 136。
|
||||
`set` 必须同时给出 `priority` 与 `event` 两个参数,没有只传优先级的写法,它也不会顺带把当前事件恢复为默认事件。`event` 是**事件 id**,不是事件对象。这个 id 必须已经在 `state.eventStore` 中注册过(`state.eventStore.addEvent(id, event)`);否则执行到这里时找不到对应事件。同一个优先级只能挂一个事件,重复设置会覆盖并告警 code 136。
|
||||
|
||||
要恢复图块的默认事件,用 `tile.set(num)` 或 `tile.restoreDefaultEvents()`;事件视图的 `reset()` 回到的是参考基准,不一定是图块的默认事件。
|
||||
|
||||
`ref()` 与 `markPure()` 是样板内部的优化接口:前者暴露参考基准,后者把当前状态设为新的基准,存档压缩与脏标记靠它们工作。一般不要调用,除非你清楚自己在做什么。日常读写只需要 `get`、`set`、`delete`、`clear`。
|
||||
|
||||
@ -136,7 +138,7 @@ function setTileEvent(
|
||||
const tile = layer.getTile(x, y);
|
||||
if (!tile) return;
|
||||
|
||||
// 优先级 10;set(num) 会把它重置为该图块的默认事件
|
||||
// 优先级 10;同一优先级已有事件时覆盖并告警
|
||||
tile.tileEvent().set(10, eventId);
|
||||
console.log(tile.tileEvent().get(10)); // eventId
|
||||
}
|
||||
@ -224,7 +226,7 @@ function verifyEventPersistence(layer: IMapLayer, x: number, y: number): void {
|
||||
|
||||
- **点事件与图块事件不是同一张表**:同一格可以同时有优先级 `5` 的点事件与优先级 `5` 的图块事件,两者互不冲突;冲突只发生在同一个事件视图内部。
|
||||
- **`getPointEvent` 返回只读映射**:它不能修改事件;要写入请用 `layer.event(x, y)` 或 `tile.pointEvent()`。
|
||||
- **`set(num)` 会重置图块事件**:静态图块与动态图块的 `set(num)` 都会调用 `restoreDefaultEvents()`。想保留自定义事件,应在 `set` 之后再挂,或用 `syncTileEvent` 从别的实例复制。
|
||||
- **`tile.set(num)` 会重置图块事件**:静态图块与动态图块的 `set(num)` 都会调用 `restoreDefaultEvents()`。想保留自定义事件,应在 `set` 之后再挂,或用 `syncTileEvent` 从别的实例复制。
|
||||
- **`layer.setBlock` 不会重置图块事件**:它只改图块数字;同一坐标缓存着的静态图块实例会继续持有旧事件。要重置事件,用 `tile.set(num)` 或 `tile.restoreDefaultEvents()`。
|
||||
- **`syncTileEvent` 会覆盖目标**:它先清空目标再复制,目标原有的图块事件不会保留。
|
||||
- **动态图块移动后 `pointEvent()` 读的是新坐标**:想确认出发地的事件,直接用 `layer.getPointEvent(oldX, oldY)`,不要用移动后的图块去反查。
|
||||
|
||||
@ -39,7 +39,7 @@ class StaticTile {
|
||||
| 同格多个 | 每格最多一个 | 可以有多个 |
|
||||
| 转换 | `toDynamic()` | `toStatic()` / `toStaticIfSafe()` |
|
||||
|
||||
`set(num)` 会把图块换成另一个数字,并把**图块事件**重置为该图块定义的默认事件。静态图块与动态图块都是如此;如果你在 `set` 之前挂过自定义图块事件,换图块后需要重新设置。
|
||||
`tile.set(num)` 会把图块换成另一个数字,并把**图块事件**重置为该图块定义的默认事件。静态图块与动态图块都是如此;如果你在 `set` 之前挂过自定义图块事件,换图块后需要重新设置。
|
||||
|
||||
## 创建与获取
|
||||
|
||||
@ -84,12 +84,12 @@ function inspectLayer(layer: IMapLayer): void {
|
||||
3. 用这个数字创建一个动态图块;
|
||||
4. 按 `keepEvent` 决定是否把原静态图块的**图块事件**复制到动态图块。
|
||||
|
||||
`keepEvent` 默认是 `true`。两种取值对源静态图块的影响并不对称:
|
||||
`keepEvent` 默认是 `true`,它只决定是否把原静态图块的**图块事件**复制到动态实例;**不论取值如何,源静态图块的图块事件都会被清空**:
|
||||
|
||||
- `true`:先把源静态图块的图块事件复制到动态实例,再调用 `staticTile.tileEvent().clear()` 清空源实例的事件;
|
||||
- `false`:动态实例按图块定义重建默认事件,但**源静态图块实例完全不被触碰**,它缓存里原来的图块事件仍然保留。
|
||||
- `false`:动态实例按图块定义重建默认事件,源实例的事件同样被清空。
|
||||
|
||||
因此「不保留」不等于「源事件被清空」。之后如果又往这一格写静态图块,`layer.setBlock(num, x, y)` 不会重置该坐标缓存实例的事件(只有 `StaticTile.set(num)` 会调用 `restoreDefaultEvents()`),旧的图块事件就可能被新图块继承。想确保干净,转换后用 `source.tileEvent().clear()` 或 `source.restoreDefaultEvents()` 显式清一次,之后再用 `tile.set(num)` 换图块。
|
||||
因此转换完成后,原坐标缓存的静态图块实例不再持有原来的自定义事件;之后再往这一格写静态图块,也不会带出旧事件。
|
||||
|
||||
```ts
|
||||
import { IMapLayer } from '@user/data-base';
|
||||
@ -144,11 +144,17 @@ async function shiftRight(
|
||||
}
|
||||
```
|
||||
|
||||
### 移动器 mover
|
||||
|
||||
`transferToDynamic` 得到的动态图块已经带有自己的 `mover`,之后的位置变更都由它发起;`step` 只是 mover 上的单步便捷入口。`mover` 的接口、速度与路径配置、`onEnd` 等待等细节属于高级 I 的内容,见 `高级 I · 移动 Mover`,本篇不重复。
|
||||
|
||||
<!-- TODO(advanced-I): 移动 Mover -->
|
||||
|
||||
### moveBlock 简写
|
||||
|
||||
`layer.moveBlock(x, y, direction, count?, time?, keepEvent?)` 是「转动态 → 移动 → 转回静态」的完整简写。它按顺序调用 `transferToDynamic`、`mover.speed(time).step(direction, count)`、等待移动结束、`transferToStatic`。
|
||||
`layer.moveBlock(x, y, direction, count?, time?, keepEvent?)` 是「转动态 → 移动 → 转回静态」的完整简写。它按顺序调用 `transferToDynamic`、`mover.speed(time).step(direction, count)`,再用 `mover.start()` 启动并等待 `onEnd`,最后调用 `transferToStatic`。
|
||||
|
||||
它适合「把一块石头往某个方向推几格」这类简单场景,但无法配置移动过程中的钩子、分段路径或中途转向。需要这些能力时,按上一节手动操作 `mover`,不要用 `moveBlock`。
|
||||
它适合「把一块石头往某个方向推几格」这类简单场景,但无法配置移动过程中的钩子、分段路径或中途转向。需要这些能力时,直接操作 `mover`(见上一节「移动器 mover」),不要用 `moveBlock`。
|
||||
|
||||
### 转换的失败条件
|
||||
|
||||
@ -205,7 +211,7 @@ async function verifyTileConversion(
|
||||
## 边界与注意
|
||||
|
||||
- **动态图块不写回图层数组**:图层数组只保存静态图块数字。判断某一格有没有动态图块要用 `getDynamicTilesAt` / `iterateDynamicTiles`,不要只读 `getBlock`。
|
||||
- **`keepEvent` 为 `false` 时事件不是「丢了」**:目标图块会回到该图块定义的默认事件,这是设计行为,不是转换失败。需要保留自定义事件就显式传 `true`,并在转换前确认源实例的事件已经设置好。
|
||||
- **`keepEvent` 为 `false` 时目标图块回到默认事件**:这是设计行为,不是转换失败。需要保留自定义事件就显式传 `true`,并在转换前确认源实例的事件已经设置好。
|
||||
- **同一格多个动态图块的顺序不保证**:`getDynamicTilesAt` 返回的是集合语义的迭代器;依赖先后顺序时,请先取出数组并自行排序。
|
||||
|
||||
返回[高级 II 导览](./index.md)。
|
||||
|
||||
Loading…
Reference in New Issue
Block a user