2025-06-04 23:10:59 +08:00
|
|
|
import { Blackboard } from "./Blackboard";
|
|
|
|
|
import { BaseNode } from "./BTNode/BaseNode";
|
|
|
|
|
import { createUUID } from "./header";
|
|
|
|
|
import { Ticker } from "./Ticker";
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 行为树
|
|
|
|
|
* 所有节点全部添加到树中
|
|
|
|
|
*/
|
|
|
|
|
export class BehaviorTree {
|
|
|
|
|
/** 行为树ID @internal */
|
|
|
|
|
private _id: string;
|
|
|
|
|
/** 行为树跟节点 @internal */
|
|
|
|
|
private _root: BaseNode;
|
|
|
|
|
/**
|
|
|
|
|
* constructor
|
|
|
|
|
* @param root 根节点
|
|
|
|
|
*/
|
|
|
|
|
constructor(root: BaseNode) {
|
|
|
|
|
this._id = createUUID();
|
|
|
|
|
this._root = root;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 执行
|
|
|
|
|
* @param subject 主体
|
|
|
|
|
* @param blackboard 黑板
|
|
|
|
|
* @param ticker 更新器
|
|
|
|
|
*/
|
|
|
|
|
public tick(subject: any, blackboard: Blackboard, ticker?: Ticker): void {
|
|
|
|
|
ticker = ticker || new Ticker(subject, blackboard, this);
|
|
|
|
|
ticker.openNodes.length = 0;
|
|
|
|
|
this._root._execute(ticker);
|
|
|
|
|
// 上次打开的节点
|
2025-07-15 10:38:59 +08:00
|
|
|
let lastOpenNodes = (blackboard.get("openNodes", this._id) || []) as BaseNode[];
|
2025-06-04 23:10:59 +08:00
|
|
|
// 当前打开的节点
|
|
|
|
|
let currOpenNodes = ticker.openNodes;
|
|
|
|
|
let start = 0;
|
|
|
|
|
for (let i = 0; i < Math.min(lastOpenNodes.length, currOpenNodes.length); i++) {
|
|
|
|
|
start = i + 1;
|
|
|
|
|
if (lastOpenNodes[i] !== currOpenNodes[i]) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 关闭不需要的节点
|
|
|
|
|
for (let i = lastOpenNodes.length - 1; i >= start; i--) {
|
|
|
|
|
lastOpenNodes[i]._close(ticker);
|
|
|
|
|
}
|
|
|
|
|
/* POPULATE BLACKBOARD */
|
|
|
|
|
blackboard.set("openNodes", currOpenNodes, this._id);
|
|
|
|
|
blackboard.set("nodeCount", ticker.nodeCount, this._id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get id(): string {
|
|
|
|
|
return this._id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get root(): BaseNode {
|
|
|
|
|
return this._root;
|
|
|
|
|
}
|
|
|
|
|
}
|