EG/plugins/user/swarm_intelligence/examples/custom_behavior.py
2025-12-12 16:16:15 +08:00

249 lines
8.5 KiB
Python

"""
自定义行为示例
演示如何创建自定义的群体行为
"""
from panda3d.core import Vec3
import math
class CustomBehaviorExample:
"""
自定义行为示例类
"""
def __init__(self, swarm_manager):
self.swarm_manager = swarm_manager
def create_leadership_behavior(self, leader_count=3):
"""
创建领导行为
指定几个成员作为领导者,其他成员跟随领导者
"""
print(f"创建领导行为,设置{leader_count}个领导者...")
# 重置群体
self.swarm_manager.reset()
# 标记领导者
for i, member in enumerate(self.swarm_manager.members):
if i < leader_count:
member['is_leader'] = True
# 设置领导者颜色(实际应用中可能需要修改材质)
if 'node' in member:
member['node'].setColor(0, 1, 0, 1) # 绿色表示领导者
else:
member['is_leader'] = False
if 'node' in member:
member['node'].setColor(1, 1, 1, 1) # 白色表示跟随者
# 配置参数
self.swarm_manager.config.set("cohesion_weight", 1.0)
self.swarm_manager.config.set("separation_weight", 1.5)
self.swarm_manager.config.set("alignment_weight", 0.8)
print("领导行为创建完成")
def create_flocking_with_leaders(self, member):
"""
为跟随者成员实现跟随领导者的行为
"""
# 查找领导者邻居
leaders = [m for m in self.swarm_manager.members if m.get('is_leader', False)]
if not leaders:
return Vec3(0, 0, 0)
# 计算到领导者的平均方向
direction = Vec3(0, 0, 0)
for leader in leaders:
if leader != member: # 排除自己
dir_to_leader = leader['position'] - member['position']
distance = dir_to_leader.length()
if distance > 0:
# 距离越近,跟随力越小(避免碰撞)
direction += dir_to_leader.normalized() / (distance / 10.0)
return direction.normalized()
def create_attraction_behavior(self, attractor_position, attraction_strength=1.0):
"""
创建吸引力行为
向指定位置吸引群体成员
"""
print(f"创建吸引力行为,吸引点: {attractor_position}")
# 设置吸引点
self.attractor_position = attractor_position
self.attraction_strength = attraction_strength
# 启用吸引行为
self.swarm_manager.config.set("attraction_enabled", True)
print("吸引力行为创建完成")
def calculate_attraction_force(self, member):
"""
计算吸引力
"""
if not hasattr(self, 'attractor_position'):
return Vec3(0, 0, 0)
direction = self.attractor_position - member['position']
distance = direction.length()
if distance > 0:
# 归一化方向并应用强度
force = direction.normalized() * self.attraction_strength
# 距离越近,力量越小
force *= 1.0 / (distance / 10.0)
return force
return Vec3(0, 0, 0)
def create_repulsion_behavior(self, repulsor_position, repulsion_strength=1.0, radius=20.0):
"""
创建排斥力行为
从指定位置推开群体成员
"""
print(f"创建排斥力行为,排斥点: {repulsor_position}")
# 设置排斥点
self.repulsor_position = repulsor_position
self.repulsion_strength = repulsion_strength
self.repulsion_radius = radius
# 启用排斥行为
self.swarm_manager.config.set("repulsion_enabled", True)
print("排斥力行为创建完成")
def calculate_repulsion_force(self, member):
"""
计算排斥力
"""
if not hasattr(self, 'repulsor_position'):
return Vec3(0, 0, 0)
direction = member['position'] - self.repulsor_position
distance = direction.length()
# 只在一定范围内施加排斥力
if 0 < distance < self.repulsion_radius:
# 归一化方向并应用强度
force = direction.normalized() * self.repulsion_strength
# 距离越近,力量越大
force *= (self.repulsion_radius - distance) / self.repulsion_radius
return force
return Vec3(0, 0, 0)
def create_sine_wave_behavior(self, amplitude=5.0, frequency=0.5):
"""
创建正弦波行为
群体成员沿正弦波路径移动
"""
print("创建正弦波行为...")
self.sine_amplitude = amplitude
self.sine_frequency = frequency
self.sine_offset = 0.0
# 启用正弦波行为
self.swarm_manager.config.set("sine_wave_enabled", True)
print("正弦波行为创建完成")
def update_sine_wave_behavior(self, dt):
"""
更新正弦波行为
"""
if hasattr(self, 'sine_offset'):
self.sine_offset += dt * self.sine_frequency
def calculate_sine_wave_force(self, member):
"""
计算正弦波力
"""
if not hasattr(self, 'sine_offset'):
return Vec3(0, 0, 0)
# 基于成员的Y坐标计算期望的Z坐标
expected_z = math.sin(member['position'].y * 0.1 + self.sine_offset) * self.sine_amplitude
# 计算向期望位置的力
desired_z = expected_z - member['position'].z
force = Vec3(0, 0, desired_z)
return force.normalized() * 0.5 # 应用适当的力量
def create_formation_behavior(self, formation_type="custom"):
"""
创建自定义队形行为
"""
print(f"创建自定义队形行为: {formation_type}")
self.formation_type = formation_type
# 启用队形行为
self.swarm_manager.config.set("custom_formation_enabled", True)
print("自定义队形行为创建完成")
def calculate_formation_force(self, member):
"""
计算队形力
"""
if not hasattr(self, 'formation_type'):
return Vec3(0, 0, 0)
# 根据队形类型计算期望位置
target_position = Vec3(0, 0, 0)
if self.formation_type == "spiral":
# 螺旋队形
if 'index' in member:
index = member['index']
angle = index * 0.5
radius = 5.0 + index * 0.2
target_position = Vec3(
math.cos(angle) * radius,
math.sin(angle) * radius,
index * 0.5
)
elif self.formation_type == "grid":
# 网格队形
if 'index' in member:
index = member['index']
grid_size = int(math.sqrt(len(self.swarm_manager.members)))
x = (index % grid_size) - grid_size/2
y = (index // grid_size) - grid_size/2
target_position = Vec3(x * 3, y * 3, 0)
# 计算向期望位置的力
if target_position.length() > 0:
direction = target_position - member['position']
return direction.normalized() * 0.8
return Vec3(0, 0, 0)
def run_custom_behavior_example(swarm_manager):
"""
运行自定义行为示例
"""
print("=== 自定义行为示例 ===")
# 创建自定义行为示例
custom_behavior = CustomBehaviorExample(swarm_manager)
# 创建领导行为
custom_behavior.create_leadership_behavior(2)
# 创建吸引力行为
attractor_pos = Vec3(20, 20, 15)
custom_behavior.create_attraction_behavior(attractor_pos, 1.5)
# 创建排斥力行为
repulsor_pos = Vec3(-10, -10, 10)
custom_behavior.create_repulsion_behavior(repulsor_pos, 2.0, 15.0)
print("自定义行为示例设置完成")