mirror of
https://github.com/gongxh0901/kunpocc-behaviortree.git
synced 2025-12-26 16:48:56 +00:00
行为树逻辑调整,删除非记忆的选择和顺序节点
This commit is contained in:
@@ -1,66 +0,0 @@
|
|||||||
/**
|
|
||||||
* @Author: Gongxh
|
|
||||||
* @Date: 2025-09-01
|
|
||||||
* @Description: 抽象节点基类
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { IBlackboard } from "../Blackboard";
|
|
||||||
import { BTNode, IBTNode } from "./BTNode";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 叶子节点 基类
|
|
||||||
* 没有子节点
|
|
||||||
*/
|
|
||||||
export abstract class LeafNode extends BTNode {
|
|
||||||
constructor() {
|
|
||||||
super([]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修饰节点 基类
|
|
||||||
* 有且仅有一个子节点
|
|
||||||
*/
|
|
||||||
export abstract class Decorator extends BTNode {
|
|
||||||
constructor(child: IBTNode) {
|
|
||||||
super([child]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 组合节点 基类
|
|
||||||
* 多个子节点
|
|
||||||
*/
|
|
||||||
export abstract class Composite extends BTNode {
|
|
||||||
constructor(...children: IBTNode[]) {
|
|
||||||
super(children);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 数值型修饰节点 基类
|
|
||||||
* 包含最大值和当前值的通用逻辑,适用于所有需要数值计数的修饰节点
|
|
||||||
*/
|
|
||||||
export abstract class NumericDecorator extends Decorator {
|
|
||||||
protected _value: number = 0;
|
|
||||||
protected override open(): void {
|
|
||||||
super.open();
|
|
||||||
this._value = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 记忆修饰节点基类
|
|
||||||
* 只有记忆节点才需要设置局部数据
|
|
||||||
*/
|
|
||||||
export abstract class MemoryComposite extends Composite {
|
|
||||||
public override _initialize(global: IBlackboard, branch: IBlackboard): void {
|
|
||||||
super._initialize(global, branch);
|
|
||||||
this._local = branch.createChild();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override open(): void {
|
|
||||||
super.open();
|
|
||||||
this.set(`__nMemoryRunningIndex`, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,16 @@
|
|||||||
import { BT } from "../BT";
|
import { BT } from "../BT";
|
||||||
import { Status } from "../header";
|
import { Status } from "../header";
|
||||||
import { LeafNode } from "./AbstractNodes";
|
import { BTNode } from "./BTNode";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 叶子节点 基类
|
||||||
|
* 没有子节点
|
||||||
|
*/
|
||||||
|
export abstract class LeafNode extends BTNode {
|
||||||
|
constructor() {
|
||||||
|
super([]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 次数等待节点(无子节点)
|
* 次数等待节点(无子节点)
|
||||||
@@ -56,12 +66,12 @@ export class WaitTime extends LeafNode {
|
|||||||
|
|
||||||
protected override open(): void {
|
protected override open(): void {
|
||||||
super.open();
|
super.open();
|
||||||
this._value = new Date().getTime();
|
this._value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public tick(): Status {
|
public tick(dt: number): Status {
|
||||||
const currTime = new Date().getTime();
|
this._value += dt;
|
||||||
if (currTime - this._value >= this._max * 1000) {
|
if (this._value >= this._max) {
|
||||||
return Status.SUCCESS;
|
return Status.SUCCESS;
|
||||||
}
|
}
|
||||||
return Status.RUNNING;
|
return Status.RUNNING;
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ export interface IBTNode {
|
|||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
_execute(): Status;
|
_execute(dt: number): Status;
|
||||||
tick(): Status;
|
tick(dt: number): Status;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 优先写入自己的黑板数据, 如果没有则写入父节点的黑板数据
|
* 优先写入自己的黑板数据, 如果没有则写入父节点的黑板数据
|
||||||
@@ -67,7 +67,7 @@ export abstract class BTNode implements IBTNode {
|
|||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
public _execute(): Status {
|
public _execute(dt: number): Status {
|
||||||
// 首次执行时初始化
|
// 首次执行时初始化
|
||||||
const isRunning = this._local.openNodes.get(this) || false;
|
const isRunning = this._local.openNodes.get(this) || false;
|
||||||
if (!isRunning) {
|
if (!isRunning) {
|
||||||
@@ -76,7 +76,7 @@ export abstract class BTNode implements IBTNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 执行核心逻辑
|
// 执行核心逻辑
|
||||||
const status = this.tick();
|
const status = this.tick(dt);
|
||||||
|
|
||||||
// 执行完成时清理
|
// 执行完成时清理
|
||||||
if (status !== Status.RUNNING) {
|
if (status !== Status.RUNNING) {
|
||||||
@@ -98,7 +98,7 @@ export abstract class BTNode implements IBTNode {
|
|||||||
* 子类必须实现此方法
|
* 子类必须实现此方法
|
||||||
* @returns 执行状态
|
* @returns 执行状态
|
||||||
*/
|
*/
|
||||||
public abstract tick(): Status;
|
public abstract tick(dt: number): Status;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 清理节点(执行完成时调用)
|
* 清理节点(执行完成时调用)
|
||||||
|
|||||||
@@ -1,9 +1,19 @@
|
|||||||
|
import { IBlackboard } from "../Blackboard";
|
||||||
import { BT } from "../BT";
|
import { BT } from "../BT";
|
||||||
import { Status } from "../header";
|
import { Status } from "../header";
|
||||||
import { Composite, MemoryComposite } from "./AbstractNodes";
|
import { BTNode, IBTNode } from "./BTNode";
|
||||||
import { IBTNode } from "./BTNode";
|
|
||||||
import { WeightDecorator } from "./Decorator";
|
import { WeightDecorator } from "./Decorator";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 组合节点基类
|
||||||
|
* 有多个子节点
|
||||||
|
*/
|
||||||
|
export abstract class Composite extends BTNode {
|
||||||
|
constructor(...children: IBTNode[]) {
|
||||||
|
super(children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 记忆选择节点 从上到下执行
|
* 记忆选择节点 从上到下执行
|
||||||
* 遇到 FAILURE 继续下一个
|
* 遇到 FAILURE 继续下一个
|
||||||
@@ -11,23 +21,29 @@ import { WeightDecorator } from "./Decorator";
|
|||||||
*
|
*
|
||||||
* 遇到 RUNNING 返回 RUNNING 下次从该节点开始
|
* 遇到 RUNNING 返回 RUNNING 下次从该节点开始
|
||||||
*/
|
*/
|
||||||
@BT.CompositeNode("MemSelector", {
|
@BT.CompositeNode("Selector", { name: "选择节点", group: "基础组合节点", desc: "选择节点" })
|
||||||
name: "记忆选择节点",
|
export class Selector extends Composite {
|
||||||
group: "基础组合节点",
|
public override _initialize(global: IBlackboard, branch: IBlackboard): void {
|
||||||
desc: "记住上次运行位置的选择节点,从记忆位置开始执行",
|
super._initialize(global, branch);
|
||||||
})
|
this._local = branch.createChild();
|
||||||
export class MemSelector extends MemoryComposite {
|
}
|
||||||
public tick(): Status {
|
|
||||||
let index = this.get<number>(`__nMemoryRunningIndex`);
|
protected override open(): void {
|
||||||
|
super.open();
|
||||||
|
this.set(`__nRunningIndex`, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public tick(dt: number): Status {
|
||||||
|
let index = this.get<number>(`__nRunningIndex`);
|
||||||
for (let i = index; i < this.children.length; i++) {
|
for (let i = index; i < this.children.length; i++) {
|
||||||
let status = this.children[i]!._execute();
|
let status = this.children[i]!._execute(dt);
|
||||||
if (status === Status.FAILURE) {
|
if (status === Status.FAILURE) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (status === Status.SUCCESS) {
|
if (status === Status.SUCCESS) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
this.set(`__nMemoryRunningIndex`, i);
|
this.set(`__nRunningIndex`, i);
|
||||||
return Status.RUNNING;
|
return Status.RUNNING;
|
||||||
}
|
}
|
||||||
return Status.FAILURE;
|
return Status.FAILURE;
|
||||||
@@ -35,29 +51,35 @@ export class MemSelector extends MemoryComposite {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 记忆顺序节点 从上到下执行
|
* 顺序节点 从上到下执行
|
||||||
* 遇到 SUCCESS 继续下一个
|
* 遇到 SUCCESS 继续下一个
|
||||||
* 遇到 FAILURE 停止迭代 返回 FAILURE 下次重新开始
|
* 遇到 FAILURE 停止迭代 返回 FAILURE 下次重新开始
|
||||||
*
|
*
|
||||||
* 遇到 RUNNING 返回 RUNNING 下次从该节点开始
|
* 遇到 RUNNING 返回 RUNNING 下次从该节点开始
|
||||||
*/
|
*/
|
||||||
@BT.CompositeNode("MemSequence", {
|
@BT.CompositeNode("Sequence", { name: "顺序节点", group: "基础组合节点", desc: "顺序节点" })
|
||||||
name: "记忆顺序节点",
|
export class Sequence extends Composite {
|
||||||
group: "基础组合节点",
|
public override _initialize(global: IBlackboard, branch: IBlackboard): void {
|
||||||
desc: "记住上次运行位置的序列节点,从记忆位置开始执行",
|
super._initialize(global, branch);
|
||||||
})
|
this._local = branch.createChild();
|
||||||
export class MemSequence extends MemoryComposite {
|
}
|
||||||
public tick(): Status {
|
|
||||||
let index = this.get<number>(`__nMemoryRunningIndex`);
|
protected override open(): void {
|
||||||
|
super.open();
|
||||||
|
this.set(`__nRunningIndex`, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public tick(dt: number): Status {
|
||||||
|
let index = this.get<number>(`__nRunningIndex`);
|
||||||
for (let i = index; i < this.children.length; i++) {
|
for (let i = index; i < this.children.length; i++) {
|
||||||
let status = this.children[i]!._execute();
|
let status = this.children[i]!._execute(dt);
|
||||||
if (status === Status.SUCCESS) {
|
if (status === Status.SUCCESS) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (status === Status.FAILURE) {
|
if (status === Status.FAILURE) {
|
||||||
return Status.FAILURE;
|
return Status.FAILURE;
|
||||||
}
|
}
|
||||||
this.set(`__nMemoryRunningIndex`, i);
|
this.set(`__nRunningIndex`, i);
|
||||||
return Status.RUNNING;
|
return Status.RUNNING;
|
||||||
}
|
}
|
||||||
return Status.SUCCESS;
|
return Status.SUCCESS;
|
||||||
@@ -65,24 +87,22 @@ export class MemSequence extends MemoryComposite {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 选择节点 从上到下执行
|
* 并行节点 从上到下执行 全部执行一遍
|
||||||
* 返回第一个不为 FAILURE 的子节点状态
|
* 返回优先级 FAILURE > RUNNING > SUCCESS
|
||||||
* 否则返回 FAILURE
|
|
||||||
*/
|
*/
|
||||||
@BT.CompositeNode("Selector", {
|
@BT.CompositeNode("Parallel", { name: "并行节点", group: "基础组合节点", desc: "同时执行所有子节点,全部成功才返回成功" })
|
||||||
name: "选择节点",
|
export class Parallel extends Composite {
|
||||||
group: "基础组合节点",
|
public tick(dt: number): Status {
|
||||||
desc: "依次执行子节点,直到找到成功或运行中的节点",
|
let result = Status.SUCCESS;
|
||||||
})
|
|
||||||
export class Selector extends Composite {
|
|
||||||
public tick(): Status {
|
|
||||||
for (let i = 0; i < this.children.length; i++) {
|
for (let i = 0; i < this.children.length; i++) {
|
||||||
let status = this.children[i]!._execute();
|
let status = this.children[i]!._execute(dt);
|
||||||
if (status !== Status.FAILURE) {
|
if (result === Status.FAILURE || status === Status.FAILURE) {
|
||||||
return status;
|
result = Status.FAILURE;
|
||||||
|
} else if (status === Status.RUNNING) {
|
||||||
|
result = Status.RUNNING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Status.FAILURE;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +137,7 @@ export class RandomSelector extends Composite {
|
|||||||
return (child instanceof WeightDecorator) ? (child.weight) : 1;
|
return (child instanceof WeightDecorator) ? (child.weight) : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public tick(): Status {
|
public tick(dt: number): Status {
|
||||||
if (this.children.length === 0) {
|
if (this.children.length === 0) {
|
||||||
return Status.FAILURE;
|
return Status.FAILURE;
|
||||||
}
|
}
|
||||||
@@ -139,58 +159,11 @@ export class RandomSelector extends Composite {
|
|||||||
left = mid + 1;
|
left = mid + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const status = this.children[childIndex]!._execute();
|
const status = this.children[childIndex]!._execute(dt);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 顺序节点 从上到下执行
|
|
||||||
* 遇到 SUCCESS 继续下一个
|
|
||||||
* 否则返回子节点状态
|
|
||||||
*/
|
|
||||||
@BT.CompositeNode("Sequence", {
|
|
||||||
name: "顺序节点",
|
|
||||||
group: "基础组合节点",
|
|
||||||
desc: "依次执行所有子节点,全部成功才返回成功",
|
|
||||||
})
|
|
||||||
export class Sequence extends Composite {
|
|
||||||
public tick(): Status {
|
|
||||||
for (let i = 0; i < this.children.length; i++) {
|
|
||||||
let status = this.children[i]!._execute();
|
|
||||||
if (status === Status.SUCCESS) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
return Status.SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 并行节点 从上到下执行 全部执行一遍
|
|
||||||
* 返回优先级 FAILURE > RUNNING > SUCCESS
|
|
||||||
*/
|
|
||||||
@BT.CompositeNode("Parallel", {
|
|
||||||
name: "并行节点",
|
|
||||||
group: "基础组合节点",
|
|
||||||
desc: "同时执行所有子节点,全部成功才返回成功",
|
|
||||||
})
|
|
||||||
export class Parallel extends Composite {
|
|
||||||
public tick(): Status {
|
|
||||||
let result = Status.SUCCESS;
|
|
||||||
for (let i = 0; i < this.children.length; i++) {
|
|
||||||
let status = this.children[i]!._execute();
|
|
||||||
if (result === Status.FAILURE || status === Status.FAILURE) {
|
|
||||||
result = Status.FAILURE;
|
|
||||||
} else if (status === Status.RUNNING) {
|
|
||||||
result = Status.RUNNING;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 并行节点 从上到下执行 全部执行一遍
|
* 并行节点 从上到下执行 全部执行一遍
|
||||||
* 返回优先级 SUCCESS > RUNNING > FAILURE
|
* 返回优先级 SUCCESS > RUNNING > FAILURE
|
||||||
@@ -201,10 +174,10 @@ export class Parallel extends Composite {
|
|||||||
desc: "同时执行所有子节点,任意一个成功即返回成功",
|
desc: "同时执行所有子节点,任意一个成功即返回成功",
|
||||||
})
|
})
|
||||||
export class ParallelAnySuccess extends Composite {
|
export class ParallelAnySuccess extends Composite {
|
||||||
public tick(): Status {
|
public tick(dt: number): Status {
|
||||||
let result = Status.FAILURE;
|
let result = Status.FAILURE;
|
||||||
for (let i = 0; i < this.children.length; i++) {
|
for (let i = 0; i < this.children.length; i++) {
|
||||||
let status = this.children[i]!._execute();
|
let status = this.children[i]!._execute(dt);
|
||||||
if (result === Status.SUCCESS || status === Status.SUCCESS) {
|
if (result === Status.SUCCESS || status === Status.SUCCESS) {
|
||||||
result = Status.SUCCESS;
|
result = Status.SUCCESS;
|
||||||
} else if (status === Status.RUNNING) {
|
} else if (status === Status.RUNNING) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Status } from "../header";
|
import { Status } from "../header";
|
||||||
import { Decorator, LeafNode } from "./AbstractNodes";
|
import { LeafNode } from "./Action";
|
||||||
|
|
||||||
/** 条件叶子节点 */
|
/** 条件叶子节点 */
|
||||||
export abstract class Condition extends LeafNode {
|
export abstract class Condition extends LeafNode {
|
||||||
@@ -19,16 +19,3 @@ export abstract class Condition extends LeafNode {
|
|||||||
return this.isEligible() ? Status.SUCCESS : Status.FAILURE;
|
return this.isEligible() ? Status.SUCCESS : Status.FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 条件装饰节点 */
|
|
||||||
export abstract class ConditionDecorator extends Decorator {
|
|
||||||
/**
|
|
||||||
* 判断是否满足条件
|
|
||||||
* @returns 是否满足条件
|
|
||||||
*/
|
|
||||||
protected abstract isEligible(): boolean;
|
|
||||||
|
|
||||||
public tick(): Status {
|
|
||||||
return this.isEligible() ? this.children[0]!._execute() : Status.FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,8 +6,30 @@
|
|||||||
|
|
||||||
import { BT } from "../BT";
|
import { BT } from "../BT";
|
||||||
import { Status } from "../header";
|
import { Status } from "../header";
|
||||||
import { Decorator, NumericDecorator } from "./AbstractNodes";
|
import { BTNode, IBTNode } from "./BTNode";
|
||||||
import { IBTNode } from "./BTNode";
|
|
||||||
|
/**
|
||||||
|
* 修饰节点 基类
|
||||||
|
* 有且仅有一个子节点
|
||||||
|
*/
|
||||||
|
export abstract class Decorator extends BTNode {
|
||||||
|
constructor(child: IBTNode) {
|
||||||
|
super([child]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 条件装饰节点基类 */
|
||||||
|
export abstract class ConditionDecorator extends Decorator {
|
||||||
|
/**
|
||||||
|
* 判断是否满足条件
|
||||||
|
* @returns 是否满足条件
|
||||||
|
*/
|
||||||
|
protected abstract isEligible(): boolean;
|
||||||
|
|
||||||
|
public tick(dt: number): Status {
|
||||||
|
return this.isEligible() ? this.children[0]!._execute(dt) : Status.FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 结果反转节点
|
* 结果反转节点
|
||||||
@@ -15,14 +37,10 @@ import { IBTNode } from "./BTNode";
|
|||||||
* 第一个Child Node节点, 返回 FAILURE, 本Node向自己的Parent Node也返回 SUCCESS
|
* 第一个Child Node节点, 返回 FAILURE, 本Node向自己的Parent Node也返回 SUCCESS
|
||||||
* 第一个Child Node节点, 返回 SUCCESS, 本Node向自己的Parent Node也返回 FAILURE
|
* 第一个Child Node节点, 返回 SUCCESS, 本Node向自己的Parent Node也返回 FAILURE
|
||||||
*/
|
*/
|
||||||
@BT.DecoratorNode("Inverter", {
|
@BT.DecoratorNode("Inverter", { name: "反转器", group: "基础装饰节点", desc: "反转子节点的执行结果,成功变失败,失败变成功" })
|
||||||
name: "反转器",
|
|
||||||
group: "基础装饰节点",
|
|
||||||
desc: "反转子节点的执行结果,成功变失败,失败变成功",
|
|
||||||
})
|
|
||||||
export class Inverter extends Decorator {
|
export class Inverter extends Decorator {
|
||||||
public tick(): Status {
|
public tick(dt: number): Status {
|
||||||
const status = this.children[0]!._execute();
|
const status = this.children[0]!._execute(dt);
|
||||||
|
|
||||||
if (status === Status.SUCCESS) {
|
if (status === Status.SUCCESS) {
|
||||||
return Status.FAILURE;
|
return Status.FAILURE;
|
||||||
@@ -40,15 +58,12 @@ export class Inverter extends Decorator {
|
|||||||
* 规定时间内, 根据Child Node的结果, 本节点向自己的父节点也返回相同的结果
|
* 规定时间内, 根据Child Node的结果, 本节点向自己的父节点也返回相同的结果
|
||||||
* 超时后, 直接返回 FAILURE
|
* 超时后, 直接返回 FAILURE
|
||||||
*/
|
*/
|
||||||
@BT.DecoratorNode("LimitTime", {
|
@BT.DecoratorNode("LimitTime", { name: "时间限制器", group: "基础装饰节点", desc: "限制子节点执行时间,超时返回失败" })
|
||||||
name: "时间限制器",
|
export class LimitTime extends Decorator {
|
||||||
group: "基础装饰节点",
|
|
||||||
desc: "限制子节点执行时间,超时返回失败",
|
|
||||||
})
|
|
||||||
export class LimitTime extends NumericDecorator {
|
|
||||||
@BT.prop({ type: BT.ParamType.float, description: "最大时间(秒)", defaultValue: 1 })
|
@BT.prop({ type: BT.ParamType.float, description: "最大时间(秒)", defaultValue: 1 })
|
||||||
protected _max: number = 1;
|
protected _max: number = 1;
|
||||||
|
|
||||||
|
private _value: number = 0;
|
||||||
/**
|
/**
|
||||||
* 时间限制节点
|
* 时间限制节点
|
||||||
* @param child 子节点
|
* @param child 子节点
|
||||||
@@ -60,15 +75,15 @@ export class LimitTime extends NumericDecorator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected override open(): void {
|
protected override open(): void {
|
||||||
this._value = Date.now();
|
this._value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public tick(): Status {
|
public tick(dt: number): Status {
|
||||||
const currentTime = Date.now();
|
this._value += dt;
|
||||||
if (currentTime - this._value > this._max * 1000) {
|
if (this._value > this._max) {
|
||||||
return Status.FAILURE;
|
return Status.FAILURE;
|
||||||
}
|
}
|
||||||
return this.children[0]!._execute();
|
return this.children[0]!._execute(dt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,25 +92,27 @@ export class LimitTime extends NumericDecorator {
|
|||||||
* 必须且只能包含一个子节点
|
* 必须且只能包含一个子节点
|
||||||
* 次数超过后, 直接返回失败; 次数未超过, 返回子节点状态
|
* 次数超过后, 直接返回失败; 次数未超过, 返回子节点状态
|
||||||
*/
|
*/
|
||||||
@BT.DecoratorNode("LimitTicks", {
|
@BT.DecoratorNode("LimitTicks", { name: "次数限制器", group: "基础装饰节点", desc: "限制子节点执行次数,超过次数返回失败" })
|
||||||
name: "次数限制器",
|
export class LimitTicks extends Decorator {
|
||||||
group: "基础装饰节点",
|
|
||||||
desc: "限制子节点执行次数,超过次数返回失败",
|
|
||||||
})
|
|
||||||
export class LimitTicks extends NumericDecorator {
|
|
||||||
@BT.prop({ type: BT.ParamType.int, description: "最大次数", defaultValue: 1 })
|
@BT.prop({ type: BT.ParamType.int, description: "最大次数", defaultValue: 1 })
|
||||||
protected _max: number = 1;
|
protected _max: number = 1;
|
||||||
|
|
||||||
|
private _value: number = 0;
|
||||||
constructor(child: IBTNode, max: number = 1) {
|
constructor(child: IBTNode, max: number = 1) {
|
||||||
super(child);
|
super(child);
|
||||||
this._max = max;
|
this._max = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
public tick(): Status {
|
protected override open(): void {
|
||||||
|
this._value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public tick(dt: number): Status {
|
||||||
this._value++;
|
this._value++;
|
||||||
if (this._value > this._max) {
|
if (this._value > this._max) {
|
||||||
return Status.FAILURE;
|
return Status.FAILURE;
|
||||||
}
|
}
|
||||||
return this.children[0]!._execute();
|
return this.children[0]!._execute(dt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,21 +122,24 @@ export class LimitTicks extends NumericDecorator {
|
|||||||
* 子节点是成功或失败,累加计数
|
* 子节点是成功或失败,累加计数
|
||||||
* 次数超过之后返回子节点状态,否则返回 RUNNING
|
* 次数超过之后返回子节点状态,否则返回 RUNNING
|
||||||
*/
|
*/
|
||||||
@BT.DecoratorNode("Repeat", {
|
@BT.DecoratorNode("Repeat", { name: "重复节点", group: "基础装饰节点", desc: "重复执行子节点指定次数" })
|
||||||
name: "重复节点",
|
export class Repeat extends Decorator {
|
||||||
group: "基础装饰节点",
|
|
||||||
desc: "重复执行子节点指定次数",
|
|
||||||
})
|
|
||||||
export class Repeat extends NumericDecorator {
|
|
||||||
@BT.prop({ type: BT.ParamType.int, description: "重复次数", defaultValue: 1 })
|
@BT.prop({ type: BT.ParamType.int, description: "重复次数", defaultValue: 1 })
|
||||||
protected _max: number = 1;
|
protected _max: number = 1;
|
||||||
|
|
||||||
|
private _value: number = 0;
|
||||||
constructor(child: IBTNode, max: number = 1) {
|
constructor(child: IBTNode, max: number = 1) {
|
||||||
super(child);
|
super(child);
|
||||||
this._max = max;
|
this._max = max;
|
||||||
}
|
}
|
||||||
public tick(): Status {
|
|
||||||
|
protected override open(): void {
|
||||||
|
this._value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public tick(dt: number): Status {
|
||||||
// 执行子节点
|
// 执行子节点
|
||||||
const status = this.children[0]!._execute();
|
const status = this.children[0]!._execute(dt);
|
||||||
// 如果子节点完成(成功或失败),增加计数
|
// 如果子节点完成(成功或失败),增加计数
|
||||||
if (status === Status.SUCCESS || status === Status.FAILURE) {
|
if (status === Status.SUCCESS || status === Status.FAILURE) {
|
||||||
this._value++;
|
this._value++;
|
||||||
@@ -139,20 +159,23 @@ export class Repeat extends NumericDecorator {
|
|||||||
*
|
*
|
||||||
* 子节点成功 计数+1
|
* 子节点成功 计数+1
|
||||||
*/
|
*/
|
||||||
@BT.DecoratorNode("RepeatUntilFailure", {
|
@BT.DecoratorNode("RepeatUntilFailure", { name: "重复直到失败", group: "基础装饰节点", desc: "重复执行子节点直到失败或达到最大次数" })
|
||||||
name: "重复直到失败",
|
export class RepeatUntilFailure extends Decorator {
|
||||||
group: "基础装饰节点",
|
|
||||||
desc: "重复执行子节点直到失败或达到最大次数",
|
|
||||||
})
|
|
||||||
export class RepeatUntilFailure extends NumericDecorator {
|
|
||||||
@BT.prop({ type: BT.ParamType.int, description: "最大重试次数", defaultValue: 1 })
|
@BT.prop({ type: BT.ParamType.int, description: "最大重试次数", defaultValue: 1 })
|
||||||
protected _max: number = 1;
|
protected _max: number = 1;
|
||||||
|
|
||||||
|
private _value: number = 0;
|
||||||
constructor(child: IBTNode, max: number = 1) {
|
constructor(child: IBTNode, max: number = 1) {
|
||||||
super(child);
|
super(child);
|
||||||
this._max = max;
|
this._max = max;
|
||||||
}
|
}
|
||||||
public tick(): Status {
|
|
||||||
const status = this.children[0]!._execute();
|
protected override open(): void {
|
||||||
|
this._value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public tick(dt: number): Status {
|
||||||
|
const status = this.children[0]!._execute(dt);
|
||||||
if (status === Status.FAILURE) {
|
if (status === Status.FAILURE) {
|
||||||
return Status.FAILURE;
|
return Status.FAILURE;
|
||||||
}
|
}
|
||||||
@@ -174,21 +197,24 @@ export class RepeatUntilFailure extends NumericDecorator {
|
|||||||
*
|
*
|
||||||
* 子节点失败, 计数+1
|
* 子节点失败, 计数+1
|
||||||
*/
|
*/
|
||||||
@BT.DecoratorNode("RepeatUntilSuccess", {
|
@BT.DecoratorNode("RepeatUntilSuccess", { name: "重复直到成功", group: "基础装饰节点", desc: "重复执行子节点直到成功或达到最大次数" })
|
||||||
name: "重复直到成功",
|
export class RepeatUntilSuccess extends Decorator {
|
||||||
group: "基础装饰节点",
|
|
||||||
desc: "重复执行子节点直到成功或达到最大次数",
|
|
||||||
})
|
|
||||||
export class RepeatUntilSuccess extends NumericDecorator {
|
|
||||||
@BT.prop({ type: BT.ParamType.int, description: "最大重试次数", defaultValue: 1, step: 1 })
|
@BT.prop({ type: BT.ParamType.int, description: "最大重试次数", defaultValue: 1, step: 1 })
|
||||||
protected _max: number = 1;
|
protected _max: number = 1;
|
||||||
|
|
||||||
|
private _value: number = 0;
|
||||||
constructor(child: IBTNode, max: number = 1) {
|
constructor(child: IBTNode, max: number = 1) {
|
||||||
super(child);
|
super(child);
|
||||||
this._max = max;
|
this._max = max;
|
||||||
}
|
}
|
||||||
public tick(): Status {
|
|
||||||
|
protected override open(): void {
|
||||||
|
this._value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public tick(dt: number): Status {
|
||||||
// 执行子节点
|
// 执行子节点
|
||||||
const status = this.children[0]!._execute();
|
const status = this.children[0]!._execute(dt);
|
||||||
if (status === Status.SUCCESS) {
|
if (status === Status.SUCCESS) {
|
||||||
return Status.SUCCESS;
|
return Status.SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -206,11 +232,7 @@ export class RepeatUntilSuccess extends NumericDecorator {
|
|||||||
/**
|
/**
|
||||||
* 权重装饰节点
|
* 权重装饰节点
|
||||||
*/
|
*/
|
||||||
@BT.DecoratorNode("WeightDecorator", {
|
@BT.DecoratorNode("WeightDecorator", { name: "权重装饰器", group: "基础装饰节点", desc: "权重装饰节点" })
|
||||||
name: "权重装饰器",
|
|
||||||
group: "基础装饰节点",
|
|
||||||
desc: "权重装饰节点",
|
|
||||||
})
|
|
||||||
export class WeightDecorator extends Decorator {
|
export class WeightDecorator extends Decorator {
|
||||||
@BT.prop({ type: BT.ParamType.int, description: "权重", defaultValue: 1, step: 1 })
|
@BT.prop({ type: BT.ParamType.int, description: "权重", defaultValue: 1, step: 1 })
|
||||||
private _weight: number;
|
private _weight: number;
|
||||||
@@ -221,8 +243,8 @@ export class WeightDecorator extends Decorator {
|
|||||||
this._weight = weight || 1;
|
this._weight = weight || 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public tick(): Status {
|
public tick(dt: number): Status {
|
||||||
return this.children[0]!._execute();
|
return this.children[0]!._execute(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public get weight(): number {
|
public get weight(): number {
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ export class BehaviorTree<T> {
|
|||||||
/**
|
/**
|
||||||
* 执行行为树
|
* 执行行为树
|
||||||
*/
|
*/
|
||||||
public tick(): Status {
|
public tick(dt: number): Status {
|
||||||
return this._root._execute();
|
return this._root._execute(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { BehaviorTree } from "./BehaviorTree";
|
|||||||
import { BT } from "./BT";
|
import { BT } from "./BT";
|
||||||
import { IBTNode } from "./BTNode/BTNode";
|
import { IBTNode } from "./BTNode/BTNode";
|
||||||
|
|
||||||
interface INodeConfig {
|
export interface INodeConfig {
|
||||||
id: string,
|
id: string,
|
||||||
className: string,
|
className: string,
|
||||||
parameters: Record<string, any>,
|
parameters: Record<string, any>,
|
||||||
|
|||||||
@@ -2,14 +2,12 @@
|
|||||||
/** 行为树 */
|
/** 行为树 */
|
||||||
export { BehaviorTree } from "./behaviortree/BehaviorTree";
|
export { BehaviorTree } from "./behaviortree/BehaviorTree";
|
||||||
export { Blackboard } from "./behaviortree/Blackboard";
|
export { Blackboard } from "./behaviortree/Blackboard";
|
||||||
export { } from "./behaviortree/BT";
|
|
||||||
export * from "./behaviortree/BTNode/AbstractNodes";
|
|
||||||
export * from "./behaviortree/BTNode/Action";
|
export * from "./behaviortree/BTNode/Action";
|
||||||
export { IBTNode } from "./behaviortree/BTNode/BTNode";
|
export { IBTNode } from "./behaviortree/BTNode/BTNode";
|
||||||
export * from "./behaviortree/BTNode/Composite";
|
export * from "./behaviortree/BTNode/Composite";
|
||||||
export * from "./behaviortree/BTNode/Condition";
|
export * from "./behaviortree/BTNode/Condition";
|
||||||
export * from "./behaviortree/BTNode/Decorator";
|
export * from "./behaviortree/BTNode/Decorator";
|
||||||
export { createBehaviorTree } from "./behaviortree/Factory";
|
export { createBehaviorTree, INodeConfig } from "./behaviortree/Factory";
|
||||||
export { Status } from "./behaviortree/header";
|
export { Status } from "./behaviortree/header";
|
||||||
|
|
||||||
// 导出装饰器内容
|
// 导出装饰器内容
|
||||||
|
|||||||
Reference in New Issue
Block a user