Add ant behavior #54

Merged
MrKBear merged 8 commits from dev-mrkbear into master 2022-05-12 20:23:21 +08:00
2 changed files with 44 additions and 5 deletions
Showing only changes of commit da493bc6ae - Show all commits

View File

@ -6,7 +6,8 @@ import { Model } from "@Model/Model";
type IContactAttackingBehaviorParameter = { type IContactAttackingBehaviorParameter = {
target: "CLG", target: "CLG",
success: "number", success: "number",
range: "number" range: "number",
assimilate: "CG",
} }
type IContactAttackingBehaviorEvent = {} type IContactAttackingBehaviorEvent = {}
@ -26,7 +27,8 @@ class ContactAttacking extends Behavior<IContactAttackingBehaviorParameter, ICon
public override parameterOption = { public override parameterOption = {
target: { type: "CLG", name: "$Target" }, target: { type: "CLG", name: "$Target" },
range: { type: "number", name: "$Range", defaultValue: .05, numberMin: 0, numberStep: .01 }, range: { type: "number", name: "$Range", defaultValue: .05, numberMin: 0, numberStep: .01 },
success: { type: "number", name: "$Success", defaultValue: 90, numberMin: 0, numberMax: 100, numberStep: 5 } success: { type: "number", name: "$Success", defaultValue: 90, numberMin: 0, numberMax: 100, numberStep: 5 },
assimilate: { type: "CG", name: "$Assimilate"}
}; };
public effect = (individual: Individual, group: Group, model: Model, t: number): void => { public effect = (individual: Individual, group: Group, model: Model, t: number): void => {
@ -46,6 +48,10 @@ class ContactAttacking extends Behavior<IContactAttackingBehaviorParameter, ICon
// 成功判定 // 成功判定
if (Math.random() * 100 < this.parameter.success) { if (Math.random() * 100 < this.parameter.success) {
targetIndividual.die(); targetIndividual.die();
if (this.parameter.assimilate?.objects) {
individual.transfer(this.parameter.assimilate.objects);
}
} }
} }
}); });
@ -72,6 +78,10 @@ class ContactAttacking extends Behavior<IContactAttackingBehaviorParameter, ICon
"$Intro": { "$Intro": {
"ZH_CN": "攻击进入共进范围的目标群个体", "ZH_CN": "攻击进入共进范围的目标群个体",
"EN_US": "Attack the target group and individual entering the range" "EN_US": "Attack the target group and individual entering the range"
},
"$Assimilate": {
"ZH_CN": "同化",
"EN_US": "Assimilate"
} }
}; };
} }

View File

@ -7,6 +7,7 @@ type ITrackingBehaviorParameter = {
target: "CLG", target: "CLG",
strength: "number", strength: "number",
range: "number", range: "number",
angle: "number",
lock: "boolean" lock: "boolean"
} }
@ -28,12 +29,23 @@ class Tracking extends Behavior<ITrackingBehaviorParameter, ITrackingBehaviorEve
target: { type: "CLG", name: "$Target" }, target: { type: "CLG", name: "$Target" },
lock: { type: "boolean", name: "$Lock", defaultValue: false }, lock: { type: "boolean", name: "$Lock", defaultValue: false },
range: { type: "number", name: "$Range", defaultValue: 4, numberMin: 0, numberStep: .1 }, range: { type: "number", name: "$Range", defaultValue: 4, numberMin: 0, numberStep: .1 },
angle: { type: "number", name: "$Angle", defaultValue: 180, numberMin: 0, numberMax: 360, numberStep: 5 },
strength: { type: "number", name: "$Strength", defaultValue: 1, numberMin: 0, numberStep: .1 } strength: { type: "number", name: "$Strength", defaultValue: 1, numberMin: 0, numberStep: .1 }
}; };
private target: Individual | undefined = undefined; private target: Individual | undefined = undefined;
private currentDistant: number = Infinity; private currentDistant: number = Infinity;
private angle2Vector(v1: number[], v2: number[]): number {
return Math.acos(
(v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]) /
(
(v1[0] ** 2 + v1[1] ** 2 + v1[2] ** 2) ** 0.5 *
(v2[0] ** 2 + v2[1] ** 2 + v2[2] ** 2) ** 0.5
)
) * 180 / Math.PI;
}
private searchTarget(individual: Individual) { private searchTarget(individual: Individual) {
for (let i = 0; i < this.parameter.target.objects.length; i++) { for (let i = 0; i < this.parameter.target.objects.length; i++) {
@ -46,8 +58,21 @@ class Tracking extends Behavior<ITrackingBehaviorParameter, ITrackingBehaviorEve
let dis = targetIndividual.distanceTo(individual); let dis = targetIndividual.distanceTo(individual);
if (dis < this.currentDistant && dis <= this.parameter.range) { if (dis < this.currentDistant && dis <= this.parameter.range) {
this.target = targetIndividual;
this.currentDistant = dis; // 计算目标方位
const targetDir = [
targetIndividual.position[0] - individual.position[0],
targetIndividual.position[1] - individual.position[1],
targetIndividual.position[2] - individual.position[2]
];
// 计算角度
const angle = this.angle2Vector(individual.velocity, targetDir);
if (angle < (this.parameter.angle ?? 360) / 2) {
this.target = targetIndividual;
this.currentDistant = dis;
}
} }
}); });
@ -150,7 +175,11 @@ class Tracking extends Behavior<ITrackingBehaviorParameter, ITrackingBehaviorEve
"$Interactive": { "$Interactive": {
"ZH_CN": "交互", "ZH_CN": "交互",
"EN_US": "Interactive" "EN_US": "Interactive"
} },
"$Angle": {
"ZH_CN": "可视角度",
"EN_US": "Viewing angle"
}
}; };
} }