处理装饰节点的非子节点关闭时清理子节点的打开状态

This commit is contained in:
gongxh
2025-10-03 18:49:36 +08:00
parent 9a3e7028d2
commit 249022a300
3 changed files with 23 additions and 11 deletions

View File

@@ -42,6 +42,10 @@ export namespace BT {
defaultValue?: any; defaultValue?: any;
/** 步进 针对数字类型的变更的最小单位 */ /** 步进 针对数字类型的变更的最小单位 */
step?: number, step?: number,
/** 最小值 */
min?: number,
/** 最大值 */
max?: number,
} }
/** /**

View File

@@ -81,9 +81,7 @@ export abstract class BTNode implements IBTNode {
// 执行完成时清理 // 执行完成时清理
if (status !== Status.RUNNING) { if (status !== Status.RUNNING) {
this._local.openNodes.delete(this); this._local.openNodes.delete(this);
this.close();
} }
return status; return status;
} }
@@ -93,6 +91,17 @@ export abstract class BTNode implements IBTNode {
*/ */
protected open(): void { } protected open(): void { }
/**
* 清理子节点的打开状态
* 一般用于装饰节点的非子节点关闭时, 用来清理子节点的打开状态
*/
protected cleanupChild(): void {
const child = this.children[0];
if (child && this._local.openNodes.has(child)) {
this._local.openNodes.delete(child);
}
}
/** /**
* 执行节点逻辑 * 执行节点逻辑
* 子类必须实现此方法 * 子类必须实现此方法
@@ -100,12 +109,6 @@ export abstract class BTNode implements IBTNode {
*/ */
public abstract tick(dt: number): Status; public abstract tick(dt: number): Status;
/**
* 清理节点(执行完成时调用)
* 子类重写此方法进行状态清理
*/
protected close(): void { }
public getEntity<T>(): T { public getEntity<T>(): T {
return this._local.getEntity(); return this._local.getEntity();
} }

View File

@@ -27,7 +27,10 @@ export abstract class ConditionDecorator extends Decorator {
protected abstract isEligible(): boolean; protected abstract isEligible(): boolean;
public tick(dt: number): Status { public tick(dt: number): Status {
return this.isEligible() ? this.children[0]!._execute(dt) : Status.FAILURE; if (this.isEligible()) {
return this.children[0]!._execute(dt);
}
return Status.FAILURE;
} }
} }
@@ -81,6 +84,7 @@ export class LimitTime extends Decorator {
public tick(dt: number): Status { public tick(dt: number): Status {
this._value += dt; this._value += dt;
if (this._value > this._max) { if (this._value > this._max) {
this.cleanupChild();
return Status.FAILURE; return Status.FAILURE;
} }
return this.children[0]!._execute(dt); return this.children[0]!._execute(dt);
@@ -110,6 +114,7 @@ export class LimitTicks extends Decorator {
public tick(dt: number): Status { public tick(dt: number): Status {
this._value++; this._value++;
if (this._value > this._max) { if (this._value > this._max) {
this.cleanupChild();
return Status.FAILURE; return Status.FAILURE;
} }
return this.children[0]!._execute(dt); return this.children[0]!._execute(dt);
@@ -124,7 +129,7 @@ export class LimitTicks extends Decorator {
*/ */
@BT.DecoratorNode("Repeat", { name: "重复节点", group: "基础装饰节点", desc: "重复执行子节点指定次数" }) @BT.DecoratorNode("Repeat", { name: "重复节点", group: "基础装饰节点", desc: "重复执行子节点指定次数" })
export class Repeat extends Decorator { export class Repeat extends Decorator {
@BT.prop({ type: BT.ParamType.int, description: "重复次数", defaultValue: 1 }) @BT.prop({ type: BT.ParamType.int, description: "重复次数", defaultValue: 1, min: 1 })
protected _max: number = 1; protected _max: number = 1;
private _value: number = 0; private _value: number = 0;
@@ -161,7 +166,7 @@ export class Repeat extends Decorator {
*/ */
@BT.DecoratorNode("RepeatUntilFailure", { name: "重复直到失败", group: "基础装饰节点", desc: "重复执行子节点直到失败或达到最大次数" }) @BT.DecoratorNode("RepeatUntilFailure", { name: "重复直到失败", group: "基础装饰节点", desc: "重复执行子节点直到失败或达到最大次数" })
export class RepeatUntilFailure extends Decorator { export class RepeatUntilFailure extends Decorator {
@BT.prop({ type: BT.ParamType.int, description: "最大重试次数", defaultValue: 1 }) @BT.prop({ type: BT.ParamType.int, description: "最大重试次数", defaultValue: 1, min: 1 })
protected _max: number = 1; protected _max: number = 1;
private _value: number = 0; private _value: number = 0;