diff --git a/source/Behavior/BoundaryConstraint.ts b/source/Behavior/BoundaryConstraint.ts index d047173..d77b3d5 100644 --- a/source/Behavior/BoundaryConstraint.ts +++ b/source/Behavior/BoundaryConstraint.ts @@ -57,7 +57,6 @@ class BoundaryConstraint extends Behavior> = { diff --git a/source/Behavior/Tracking.ts b/source/Behavior/Tracking.ts index d1e457e..0c6bc22 100644 --- a/source/Behavior/Tracking.ts +++ b/source/Behavior/Tracking.ts @@ -5,7 +5,9 @@ import { Model } from "@Model/Model"; type ITrackingBehaviorParameter = { target: "LG", - strength: "number" + strength: "number", + range: "number", + lock: "boolean" } type ITrackingBehaviorEvent = {} @@ -24,12 +26,15 @@ class Tracking extends Behavior { - let target: Individual | undefined; - let currentDistant: number = Infinity; + private target: Individual | undefined = undefined; + private currentDistant: number = Infinity; + + private searchTarget(individual: Individual) { for (let i = 0; i < this.parameter.target.objects.length; i++) { const targetGroup = this.parameter.target.objects[i]; @@ -40,19 +45,79 @@ class Tracking extends Behavior { + + this.clearTarget(); + + if (this.parameter.lock) { + + let isValidTarget = false; + this.target = individual.getData("Tracking.lock.target"); + + if (this.target) { + + // 校验目标所在的群是否仍是目标 + let isInTarget = false; + for (let i = 0; i < this.parameter.target.objects.length; i++) { + if (this.parameter.target.objects[i].equal(this.target.group)) { + isInTarget = true; + break; + } + } + + // 如果还在目标范围内,校验距离 + if (isInTarget) { + let dis = individual.distanceTo(this.target); + + // 校验成功 + if (dis <= this.parameter.range) { + this.currentDistant = dis; + isValidTarget = true; + } + } + } + + // 如果目标无效,尝试搜索新的目标 + if (!isValidTarget) { + + this.clearTarget(); + this.searchTarget(individual); + + // 如果成功搜索,缓存目标 + if (this.target && this.currentDistant && this.currentDistant !== Infinity) { + individual.setData("Tracking.lock.target", this.target); + } + + // 搜索失败,清除目标 + else { + individual.setData("Tracking.lock.target", undefined); + } + } + } + + else { + this.searchTarget(individual); + } + + if (this.target && this.currentDistant && this.currentDistant !== Infinity) { individual.applyForce( - (target.position[0] - individual.position[0]) * this.parameter.strength, - (target.position[1] - individual.position[1]) * this.parameter.strength, - (target.position[2] - individual.position[2]) * this.parameter.strength + (this.target.position[0] - individual.position[0]) * this.parameter.strength / this.currentDistant, + (this.target.position[1] - individual.position[1]) * this.parameter.strength / this.currentDistant, + (this.target.position[2] - individual.position[2]) * this.parameter.strength / this.currentDistant ); } } @@ -66,6 +131,14 @@ class Tracking extends Behavior