Files
kunpocc-behaviortree/src/behaviortree/BTNode/BTNode.ts

152 lines
3.6 KiB
TypeScript
Raw Normal View History

2025-09-03 10:54:07 +08:00
import { globalBlackboard, IBlackboard } from "../Blackboard";
import { Status } from "../header";
export interface IBTNode {
readonly children: IBTNode[];
/** 本节点的的黑板引用 */
2025-09-04 14:08:19 +08:00
local: IBlackboard;
2025-09-03 10:54:07 +08:00
/**
*
* @param root
* @param parent
*/
_initialize(root: IBlackboard, parent: IBlackboard): void;
/**
* @internal
*/
_execute(dt: number): Status;
tick(dt: number): Status;
2025-09-03 10:54:07 +08:00
/**
* ,
*/
set<T>(key: string, value: T): void;
get<T>(key: string): T;
/**
*
*/
setRoot<T>(key: string, value: T): void;
getRoot<T>(key: string): T;
/**
*
*/
setGlobal<T>(key: string, value: T): void;
getGlobal<T>(key: string): T;
2025-09-04 14:08:19 +08:00
/** 获取关联的实体 */
getEntity<T>(): T;
2025-09-03 10:54:07 +08:00
}
/**
*
*
*/
export abstract class BTNode implements IBTNode {
public readonly children: IBTNode[];
/** 树根节点的黑板引用 */
protected _root!: IBlackboard;
2025-09-03 10:54:07 +08:00
/** 本节点的的黑板引用 可能等于 _parent */
protected _local!: IBlackboard;
constructor(children?: IBTNode[]) {
this.children = children ? [...children] : [];
}
public _initialize(root: IBlackboard, parent: IBlackboard): void {
this._root = root;
// 在需要的节点中重写创建新的local
this._local = parent;
}
/**
* @internal
*/
public _execute(dt: number): Status {
2025-09-03 10:54:07 +08:00
// 首次执行时初始化
const isRunning = this._local.openNodes.get(this) || false;
if (!isRunning) {
this._local.openNodes.set(this, true);
2025-09-03 10:54:07 +08:00
this.open();
}
// 执行核心逻辑
const status = this.tick(dt);
2025-09-03 10:54:07 +08:00
// 执行完成时清理
if (status !== Status.RUNNING) {
this._local.openNodes.delete(this);
2025-09-03 10:54:07 +08:00
}
return status;
}
/**
*
*
*/
protected open(): void { }
/**
*
*
*/
protected cleanupChild(): void {
const child = this.children[0];
if (child && this._local.openNodes.has(child)) {
this._local.openNodes.delete(child);
}
}
2025-09-03 10:54:07 +08:00
/**
*
*
* @returns
*/
public abstract tick(dt: number): Status;
2025-09-03 10:54:07 +08:00
2025-09-04 14:08:19 +08:00
public getEntity<T>(): T {
return this._local.getEntity();
}
2025-09-03 10:54:07 +08:00
/**
*
*/
public set<T>(key: string, value: T): void {
this._local.set(key, value);
}
public get<T>(key: string): T {
return this._local.get(key);
}
/**
*
*/
public setRoot<T>(key: string, value: T): void {
this._root.set(key, value);
}
public getRoot<T>(key: string): T {
return this._root.get(key);
}
/**
*
*/
public setGlobal<T>(key: string, value: T): void {
globalBlackboard.set(key, value);
}
public getGlobal<T>(key: string): T {
return globalBlackboard.get(key);
}
public get local(): IBlackboard {
return this._local;
}
}