249 lines
8.5 KiB
Python
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("自定义行为示例设置完成") |