mirror of
https://github.com/motajs/template.git
synced 2026-09-12 09:48:49 +08:00
refactor: 按审查意见调整寻路模块与开发规范
This commit is contained in:
parent
489e3de106
commit
622008f67c
4
dev.md
4
dev.md
@ -73,7 +73,7 @@
|
|||||||
- 公共方法、接口必须在**源头处**(多数情况下为 `interface`)添加 `jsDoc` 注释;其他常用成员、方法、类型也必须添加注释(含义极为明确或极少使用的可例外,但建议全部添加)。接口中每个方法之间必须添加空行,成员之间应根据成员功能添加换行。
|
- 公共方法、接口必须在**源头处**(多数情况下为 `interface`)添加 `jsDoc` 注释;其他常用成员、方法、类型也必须添加注释(含义极为明确或极少使用的可例外,但建议全部添加)。接口中每个方法之间必须添加空行,成员之间应根据成员功能添加换行。
|
||||||
- 继承或 `implements` 而来的 API(方法、成员等),若注释说明无需变更,则**不应重复添加** `jsDoc` 注释。
|
- 继承或 `implements` 而来的 API(方法、成员等),若注释说明无需变更,则**不应重复添加** `jsDoc` 注释。
|
||||||
- 不对构造器添加注释。若构造器使用了属性声明语法(`constructor(public prop: T)`)且成员需要说明,可仅对该成员添加参数注释,不写构造器描述。**在这种情况下**建议避免在构造器中使用属性声明语法,将成员单独声明并在构造器中赋值。此条建议**并非**要求不使用构造器的属性声明语法,而是仅在这一情况下不建议使用,常规情况下推荐使用此语法来缩短代码长度并提高可读性。
|
- 不对构造器添加注释。若构造器使用了属性声明语法(`constructor(public prop: T)`)且成员需要说明,可仅对该成员添加参数注释,不写构造器描述。**在这种情况下**建议避免在构造器中使用属性声明语法,将成员单独声明并在构造器中赋值。此条建议**并非**要求不使用构造器的属性声明语法,而是仅在这一情况下不建议使用,常规情况下推荐使用此语法来缩短代码长度并提高可读性。
|
||||||
- 长文件可使用 `#region` / `#endregion` 分段以支持折叠。
|
- 长文件可使用 `#region` / `#endregion` 分段以支持折叠,分区应以功能进行划分,即这个 region 负责某个功能,而不是按照修饰符等内容划分。
|
||||||
- TODO 使用 `// TODO:` 或 `// todo:` 格式。
|
- TODO 使用 `// TODO:` 或 `// todo:` 格式。
|
||||||
- 单行注释的 `//` 与注释内容之间留一个空格;不允许出现非 jsDoc 的多行注释,如需多行注释,使用多个单行注释代替。
|
- 单行注释的 `//` 与注释内容之间留一个空格;不允许出现非 jsDoc 的多行注释,如需多行注释,使用多个单行注释代替。
|
||||||
- 注释合理换行:考虑中文字符较宽,建议每 40–60 个字符在标点符号后换行,不要频繁换行,每行长度应差不多,不要过短也不要过长,不允许在句中换行;参数注释换行后保持对齐。
|
- 注释合理换行:考虑中文字符较宽,建议每 40–60 个字符在标点符号后换行,不要频繁换行,每行长度应差不多,不要过短也不要过长,不允许在句中换行;参数注释换行后保持对齐。
|
||||||
@ -115,6 +115,8 @@
|
|||||||
- 换行使用 `CRLF` 格式。
|
- 换行使用 `CRLF` 格式。
|
||||||
- 不得将一个对象上的函数声明为一个临时变量/常量,哪怕其没有 `this` 指向问题。
|
- 不得将一个对象上的函数声明为一个临时变量/常量,哪怕其没有 `this` 指向问题。
|
||||||
- 通常情况下,一个文件应只包含一个类,但如果一个类仅是另一个类的依赖,或一个类的长度远远小于另一个类等特殊情况时,允许将多个类放在同一个文件中。
|
- 通常情况下,一个文件应只包含一个类,但如果一个类仅是另一个类的依赖,或一个类的长度远远小于另一个类等特殊情况时,允许将多个类放在同一个文件中。
|
||||||
|
- 私有方法应该放到调用之的方法之前,同时保证其处在合理的 region 内。
|
||||||
|
- 对象的非空判断用 `!obj`,字面量的非空判断用 `!isNil(value)`。
|
||||||
|
|
||||||
## 双端分离
|
## 双端分离
|
||||||
|
|
||||||
|
|||||||
@ -55,14 +55,13 @@ export class PathfindingFinder implements IPathfinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取进入指定位置节点的损失,损失值非有限数或负数时
|
* 获取进入指定位置节点的损失,损失值为负数时抛出警告并按损失 1 处理
|
||||||
* 告警并按默认损失 1 处理
|
|
||||||
* @param block 位置信息
|
* @param block 位置信息
|
||||||
*/
|
*/
|
||||||
private getNodeCost(block: ILayerLocation): number {
|
private getNodeCost(block: ILayerLocation): number {
|
||||||
if (!this.cost) return 1;
|
if (!this.cost) return 1;
|
||||||
const value = this.cost(block);
|
const value = this.cost(block);
|
||||||
if (!Number.isFinite(value) || value < 0) {
|
if (value < 0) {
|
||||||
logger.warn(174);
|
logger.warn(174);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -70,8 +69,7 @@ export class PathfindingFinder implements IPathfinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在有向图上执行最小损失搜索,
|
* 在有向图上执行最小损失搜索,终端节点仅可作为路径终点,不可作为中间节点
|
||||||
* 终端节点仅可作为路径终点,不可作为中间节点
|
|
||||||
* @param graph 寻路有向图
|
* @param graph 寻路有向图
|
||||||
* @param start 寻路起始位置
|
* @param start 寻路起始位置
|
||||||
* @param target 寻路目标位置
|
* @param target 寻路目标位置
|
||||||
|
|||||||
@ -91,7 +91,7 @@ export class PathfindingGraphBuilder implements IPathfindingGraphBuilder {
|
|||||||
const width = layer.width;
|
const width = layer.width;
|
||||||
const height = layer.height;
|
const height = layer.height;
|
||||||
const floorId = this.resolveFloorId();
|
const floorId = this.resolveFloorId();
|
||||||
const state: IDataCommon = layer.state;
|
const state = layer.state;
|
||||||
const blocks: (ILayerLocation | null)[] = new Array(
|
const blocks: (ILayerLocation | null)[] = new Array(
|
||||||
width * height
|
width * height
|
||||||
).fill(null);
|
).fill(null);
|
||||||
|
|||||||
@ -34,10 +34,6 @@ export class PathfindingSystem implements IPathfindingSystem {
|
|||||||
this.policy = policy;
|
this.policy = policy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 未绑定移动器时告警并返回空数组
|
|
||||||
* @param target 目标坐标
|
|
||||||
*/
|
|
||||||
getPath(target: ITileLocator): IPathfindingStep[] {
|
getPath(target: ITileLocator): IPathfindingStep[] {
|
||||||
const mover = this.mover;
|
const mover = this.mover;
|
||||||
if (isNil(mover)) {
|
if (isNil(mover)) {
|
||||||
@ -49,8 +45,7 @@ export class PathfindingSystem implements IPathfindingSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按指定移动方式启动寻路移动,返回控制器包装。
|
* 按指定移动方式启动寻路移动,返回控制器包装。已有移动进行中时返回 `null`
|
||||||
* 已有移动进行中时返回 `null`
|
|
||||||
* @param path 寻路步骤序列
|
* @param path 寻路步骤序列
|
||||||
* @param teleport 是否瞬移
|
* @param teleport 是否瞬移
|
||||||
*/
|
*/
|
||||||
@ -64,7 +59,7 @@ export class PathfindingSystem implements IPathfindingSystem {
|
|||||||
if (current && !current.controller.done) return null;
|
if (current && !current.controller.done) return null;
|
||||||
|
|
||||||
if (teleport) {
|
if (teleport) {
|
||||||
const last = path[path.length - 1];
|
const last = path.at(-1)!;
|
||||||
mover.tp(last.to.x, last.to.y);
|
mover.tp(last.to.x, last.to.y);
|
||||||
} else {
|
} else {
|
||||||
for (const step of path) {
|
for (const step of path) {
|
||||||
@ -72,7 +67,6 @@ export class PathfindingSystem implements IPathfindingSystem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 移动器移动中时启动失败,对应已有移动进行中的契约
|
|
||||||
const controller = mover.start();
|
const controller = mover.start();
|
||||||
if (!controller) return null;
|
if (!controller) return null;
|
||||||
const result: IPathfindingController = { controller, path };
|
const result: IPathfindingController = { controller, path };
|
||||||
@ -89,10 +83,11 @@ export class PathfindingSystem implements IPathfindingSystem {
|
|||||||
teleportTo(target: ITileLocator): IPathfindingController | null {
|
teleportTo(target: ITileLocator): IPathfindingController | null {
|
||||||
const path = this.getPath(target);
|
const path = this.getPath(target);
|
||||||
if (path.length === 0) return null;
|
if (path.length === 0) return null;
|
||||||
if (isNil(this.policy) || this.policy(path)) {
|
if (!this.policy || this.policy(path)) {
|
||||||
return this.startMove(path, false);
|
return this.startMove(path, false);
|
||||||
|
} else {
|
||||||
|
return this.startMove(path, true);
|
||||||
}
|
}
|
||||||
return this.startMove(path, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async interrupt(): Promise<void> {
|
async interrupt(): Promise<void> {
|
||||||
|
|||||||
@ -13,6 +13,8 @@ import {
|
|||||||
IObjectMover
|
IObjectMover
|
||||||
} from '@user/data-common';
|
} from '@user/data-common';
|
||||||
|
|
||||||
|
//#region 寻路系统
|
||||||
|
|
||||||
export interface IPathfindingStep {
|
export interface IPathfindingStep {
|
||||||
/** 移动方向 */
|
/** 移动方向 */
|
||||||
readonly dir: FaceDirection;
|
readonly dir: FaceDirection;
|
||||||
@ -105,14 +107,12 @@ export interface IPathfindingSystem extends IDataBaseExtended {
|
|||||||
/**
|
/**
|
||||||
* 逐步寻路至目标位置,触发途经事件
|
* 逐步寻路至目标位置,触发途经事件
|
||||||
* @param target 目标坐标
|
* @param target 目标坐标
|
||||||
* @returns 移动控制器。无法寻路、无路径或已有移动进行中时返回 `null`
|
|
||||||
*/
|
*/
|
||||||
moveTo(target: ITileLocator): IPathfindingController | null;
|
moveTo(target: ITileLocator): IPathfindingController | null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 瞬移至目标位置。瞬移前经回退策略判定,判定需要回退则自动退为逐步寻路
|
* 瞬移至目标位置。瞬移前经回退策略判定,判定需要回退则自动退为逐步寻路
|
||||||
* @param target 目标坐标
|
* @param target 目标坐标
|
||||||
* @returns 移动控制器;无法寻路、无路径或已有移动进行中时返回 `null`
|
|
||||||
*/
|
*/
|
||||||
teleportTo(target: ITileLocator): IPathfindingController | null;
|
teleportTo(target: ITileLocator): IPathfindingController | null;
|
||||||
|
|
||||||
@ -122,6 +122,10 @@ export interface IPathfindingSystem extends IDataBaseExtended {
|
|||||||
interrupt(): Promise<void>;
|
interrupt(): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region 路径图
|
||||||
|
|
||||||
export interface IPathGraphEdge {
|
export interface IPathGraphEdge {
|
||||||
/** 本条边对应的移动方向 */
|
/** 本条边对应的移动方向 */
|
||||||
readonly dir: FaceDirection;
|
readonly dir: FaceDirection;
|
||||||
@ -156,19 +160,19 @@ export interface IPathGraph {
|
|||||||
export interface IPathfindingGraphBuilder {
|
export interface IPathfindingGraphBuilder {
|
||||||
/**
|
/**
|
||||||
* 绑定地图状态对象,用于解析图层所属楼层 id
|
* 绑定地图状态对象,用于解析图层所属楼层 id
|
||||||
* @param maps 地图状态对象,传入 `null` 解绑
|
* @param maps 地图状态对象
|
||||||
*/
|
*/
|
||||||
useMapState(maps: IMapState | null): void;
|
useMapState(maps: IMapState | null): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绑定构建有向图所用的地图图层
|
* 绑定构建有向图所用的地图图层
|
||||||
* @param layer 地图图层对象,传入 `null` 解绑
|
* @param layer 地图图层对象
|
||||||
*/
|
*/
|
||||||
useMapLayer(layer: IMapLayer | null): void;
|
useMapLayer(layer: IMapLayer | null): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注入判定边可行性的通行性谓词
|
* 注入判定边可行性的通行性谓词
|
||||||
* @param predicate 通行性谓词,传入 `null` 解绑
|
* @param predicate 通行性谓词
|
||||||
*/
|
*/
|
||||||
usePassPredicate(predicate: IPassPredicate | null): void;
|
usePassPredicate(predicate: IPassPredicate | null): void;
|
||||||
|
|
||||||
@ -179,9 +183,9 @@ export interface IPathfindingGraphBuilder {
|
|||||||
useDirGroup(group: number): void;
|
useDirGroup(group: number): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建有向图。图层未绑定时告警并返回空图,
|
* 构建有向图。图层未绑定时告警并返回空图,不包含任何节点与边
|
||||||
* 不包含任何节点与边
|
|
||||||
* @returns 构建的有向图
|
|
||||||
*/
|
*/
|
||||||
build(): IPathGraph;
|
build(): IPathGraph;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|||||||
@ -239,6 +239,6 @@
|
|||||||
"171": "Event id '$1' not found in event store, event will be skipped.",
|
"171": "Event id '$1' not found in event store, event will be skipped.",
|
||||||
"172": "Event returned non-boolean value '$1' during reduction. JavaScript short-circuit semantics will be used.",
|
"172": "Event returned non-boolean value '$1' during reduction. JavaScript short-circuit semantics will be used.",
|
||||||
"173": "Pathfinding input is invalid or a required binding (map state, map layer) is missing. An empty result will be returned.",
|
"173": "Pathfinding input is invalid or a required binding (map state, map layer) is missing. An empty result will be returned.",
|
||||||
"174": "Pathfinding cost function returned a non-finite or negative value. Default cost 1 will be used instead."
|
"174": "Pathfinding cost function returned a negative value. Default cost 1 will be used instead."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user