From f660aefa4c7942c9fa139963dbc14148d667ff15 Mon Sep 17 00:00:00 2001 From: MrKBear Date: Fri, 6 May 2022 18:55:31 +0800 Subject: [PATCH] Add avoidance behavior --- source/Behavior/Avoidance.ts | 86 ++++++++++++++++++++++++++++++++++++ source/Behavior/Behavior.ts | 2 + 2 files changed, 88 insertions(+) create mode 100644 source/Behavior/Avoidance.ts diff --git a/source/Behavior/Avoidance.ts b/source/Behavior/Avoidance.ts new file mode 100644 index 0000000..8982e88 --- /dev/null +++ b/source/Behavior/Avoidance.ts @@ -0,0 +1,86 @@ +import { Behavior } from "@Model/Behavior"; +import { Group } from "@Model/Group"; +import { Individual } from "@Model/Individual"; +import { Model } from "@Model/Model"; + +type IAvoidanceBehaviorParameter = { + avoid: "CLG", + strength: "number", + range: "number" +} + +type IAvoidanceBehaviorEvent = {} + +class Avoidance extends Behavior { + + public override behaviorId: string = "Avoidance"; + + public override behaviorName: string = "$Title"; + + public override iconName: string = "FastMode"; + + public override describe: string = "$Intro"; + + public override category: string = "$Interactive"; + + public override parameterOption = { + avoid: { name: "$Avoid", type: "CLG" }, + strength: { type: "number", name: "$Strength", defaultValue: 1, numberMin: 0, numberStep: .1 }, + range: { type: "number", name: "$Range", defaultValue: 4, numberMin: 0, numberStep: .1 } + }; + + public effect = (individual: Individual, group: Group, model: Model, t: number): void => { + + let currentDistant: number = Infinity; + let avoidTarget = undefined as Individual | undefined; + + for (let i = 0; i < this.parameter.avoid.objects.length; i++) { + const targetGroup = this.parameter.avoid.objects[i]; + + targetGroup.individuals.forEach((targetIndividual) => { + + // 排除自己 + if (targetIndividual === individual) return; + let dis = targetIndividual.distanceTo(individual); + + if (dis < currentDistant && dis <= this.parameter.range) { + avoidTarget = targetIndividual; + currentDistant = dis; + } + }); + } + + if (avoidTarget && currentDistant !== Infinity) { + individual.applyForce( + (individual.position[0] - avoidTarget.position[0]) * this.parameter.strength / currentDistant, + (individual.position[1] - avoidTarget.position[1]) * this.parameter.strength / currentDistant, + (individual.position[2] - avoidTarget.position[2]) * this.parameter.strength / currentDistant + ); + } + } + + public override terms: Record> = { + "$Title": { + "ZH_CN": "躲避", + "EN_US": "Avoidance" + }, + "$Intro": { + "ZH_CN": "远离视野范围内最近的躲避目标", + "EN_US": "Stay away from the nearest evasive target in the field of vision" + }, + "$Avoid": { + "ZH_CN": "躲避对象", + "EN_US": "Avoid object" + }, + "$Strength": { + "ZH_CN": "躲避强度", + "EN_US": "Avoidance intensity" + }, + "$Range": { + "ZH_CN": "视野范围", + "EN_US": "Field of vision" + } + }; +} + +export { Avoidance }; \ No newline at end of file diff --git a/source/Behavior/Behavior.ts b/source/Behavior/Behavior.ts index 40b72b5..2ce5ccc 100644 --- a/source/Behavior/Behavior.ts +++ b/source/Behavior/Behavior.ts @@ -7,6 +7,7 @@ import { Tracking } from "@Behavior/Tracking"; import { ContactAttacking } from "@Behavior/ContactAttacking"; import { ContactAssimilate } from "@Behavior/ContactAssimilate"; import { DelayAssimilate } from "@Behavior/DelayAssimilate"; +import { Avoidance } from "@Behavior/Avoidance"; const AllBehaviors: IAnyBehaviorRecorder[] = [ new BehaviorRecorder(Template), @@ -17,6 +18,7 @@ const AllBehaviors: IAnyBehaviorRecorder[] = [ new BehaviorRecorder(ContactAttacking), new BehaviorRecorder(ContactAssimilate), new BehaviorRecorder(DelayAssimilate), + new BehaviorRecorder(Avoidance), ] /**