import { EntitySystem, Entity, Matcher, Time } from '@esengine/ecs-framework'; import { AIComponent, Transform, Health } from '../components'; /** * AI系统 - 处理AI行为和状态机 */ export class AISystem extends EntitySystem { /** 系统处理的实体计数器 */ private processedEntityCount: number = 0; /** 状态转换计数器 */ private stateTransitionCount: number = 0; constructor() { // 处理具有AI组件的实体 super(Matcher.empty().all(AIComponent)); } /** * 处理所有实体 */ protected process(entities: Entity[]): void { const deltaTime = Time.deltaTime; const currentTime = Time.totalTime; this.processedEntityCount = entities.length; for (const entity of entities) { this.processEntity(entity, deltaTime, currentTime); } // 批量处理AI间的交互 this.processAIInteractions(entities); } /** * 处理单个实体 */ private processEntity(entity: Entity, deltaTime: number, currentTime: number): void { const ai = entity.getComponent(AIComponent); const transform = entity.getComponent(Transform); const health = entity.getComponent(Health); if (!ai) return; // 更新感知系统 ai.updatePerception(deltaTime); // 处理状态机 this.updateStateMachine(ai, deltaTime); // 更新行为树 this.updateBehaviorTree(ai, deltaTime); // 处理AI能力(如果有Transform和Health组件) if (transform && health) { this.updateAICapabilities(ai, transform, health, deltaTime); } // 处理记忆衰减 this.updateMemory(ai, deltaTime); } /** * 更新状态机 */ private updateStateMachine(ai: AIComponent, deltaTime: number): void { const currentStateName = ai.currentState; const transitions = ai.stateMachine.transitions.get(currentStateName); if (transitions) { // 按优先级排序转换条件 const sortedTransitions = transitions.sort((a, b) => b.priority - a.priority); for (const transition of sortedTransitions) { if (transition.condition()) { // 执行状态转换 const currentState = ai.stateMachine.states.get(currentStateName); const newState = ai.stateMachine.states.get(transition.targetState); if (currentState && newState) { currentState.exit(); ai.currentState = transition.targetState as any; newState.enter(); this.stateTransitionCount++; break; } } } } } /** * 更新行为树 */ private updateBehaviorTree(ai: AIComponent, deltaTime: number): void { const behaviorTree = ai.config.behaviorTree; const blackboard = behaviorTree.blackboard; // 更新黑板数据 blackboard.set('deltaTime', deltaTime); blackboard.set('currentTime', Date.now()); // 模拟行为树执行 const executionResult = this.executeBehaviorNode(behaviorTree.rootNode, ai); // 记录执行历史 behaviorTree.executionHistory.push({ nodeName: behaviorTree.rootNode.name, startTime: Date.now(), endTime: Date.now() + Math.random() * 10, result: executionResult, data: { deltaTime } }); // 保持历史记录在合理范围内 if (behaviorTree.executionHistory.length > 50) { behaviorTree.executionHistory.shift(); } } /** * 执行行为树节点(模拟) */ private executeBehaviorNode(node: any, ai: AIComponent): 'success' | 'failure' | 'running' { // 简单的行为树执行模拟 switch (node.name) { case 'root': case 'selector': // 选择器节点:尝试执行子节点直到一个成功 for (const child of node.children) { const result = this.executeBehaviorNode(child, ai); if (result === 'success' || result === 'running') { return result; } } return 'failure'; case 'sequence': // 序列节点:按顺序执行所有子节点 for (const child of node.children) { const result = this.executeBehaviorNode(child, ai); if (result === 'failure' || result === 'running') { return result; } } return 'success'; case 'condition': // 条件节点:检查AI状态 return ai.config.personality.intelligence > 0.5 ? 'success' : 'failure'; case 'action': // 动作节点:执行AI行为 return Math.random() > 0.3 ? 'success' : 'running'; default: return 'failure'; } } /** * 更新AI能力 */ private updateAICapabilities(ai: AIComponent, transform: Transform, health: Health, deltaTime: number): void { const capabilities = ai.config.capabilities; // 根据健康状况调整能力 const healthRatio = health.currentHealth / health.maxHealth; const effectiveSpeed = capabilities.movementSpeed * healthRatio; // 更新移动速度 transform.speed = effectiveSpeed; // 根据个性调整行为 if (ai.config.personality.aggression > 0.7 && healthRatio > 0.5) { // 高攻击性且健康状况良好时更主动 ai.currentState = 'chase'; } else if (healthRatio < 0.3) { // 生命值低时逃跑 ai.currentState = 'flee'; } } /** * 更新记忆系统 */ private updateMemory(ai: AIComponent, deltaTime: number): void { const memory = ai.config.memory; const currentTime = Date.now(); // 衰减已知位置的可信度 memory.knownLocations.forEach(location => { const timeSinceVisit = currentTime - location.lastVisited; const decayFactor = Math.exp(-timeSinceVisit / 30000); // 30秒衰减率 location.confidence *= decayFactor; }); // 移除可信度过低的位置 memory.knownLocations = memory.knownLocations.filter(location => location.confidence > 0.1); // 衰减关系信任度 memory.relationships.forEach(relation => { const timeSinceInteraction = currentTime - relation.lastInteraction; if (timeSinceInteraction > 60000) { // 60秒没有交互 relation.trustLevel *= 0.99; // 缓慢衰减 } }); } /** * 处理AI间的交互 */ private processAIInteractions(entities: Entity[]): void { const aiEntities = entities.filter(e => e.getComponent(AIComponent)); for (let i = 0; i < aiEntities.length; i++) { for (let j = i + 1; j < aiEntities.length; j++) { this.processAIPair(aiEntities[i], aiEntities[j]); } } } /** * 处理两个AI实体间的交互 */ private processAIPair(entity1: Entity, entity2: Entity): void { const ai1 = entity1.getComponent(AIComponent); const ai2 = entity2.getComponent(AIComponent); const transform1 = entity1.getComponent(Transform); const transform2 = entity2.getComponent(Transform); if (!ai1 || !ai2 || !transform1 || !transform2) return; // 计算距离 const distance = Math.sqrt( Math.pow(transform1.position.x - transform2.position.x, 2) + Math.pow(transform1.position.y - transform2.position.y, 2) ); // 视线范围内的交互 if (distance <= ai1.config.capabilities.sightRange) { this.handleVisualContact(ai1, ai2, entity1, entity2, distance); } // 听力范围内的交互 if (distance <= ai1.config.capabilities.hearingRange) { this.handleAudioContact(ai1, ai2, distance); } // 创建盟友关系(随机) if (Math.random() < 0.001 && !ai1.allyIds.includes(entity2.id)) { // 0.1%概率每帧 ai1.addAlly(entity2.id); } } /** * 处理视觉接触 */ private handleVisualContact(ai1: AIComponent, ai2: AIComponent, entity1: Entity, entity2: Entity, distance: number): void { const currentTime = Date.now(); // 添加到可见实体列表 const existingEntry = ai1.perception.visibleEntities.find(e => e.entityId === entity2.id); if (existingEntry) { existingEntry.distance = distance; existingEntry.lastSeen = currentTime; existingEntry.componentId = ai2.id; // 使用组件ID避免循环引用 } else { ai1.perception.visibleEntities.push({ entityId: entity2.id, position: entity2.getComponent(Transform)!.position.clone(), distance: distance, angle: Math.atan2( entity2.getComponent(Transform)!.position.y - entity1.getComponent(Transform)!.position.y, entity2.getComponent(Transform)!.position.x - entity1.getComponent(Transform)!.position.x ), lastSeen: currentTime, componentId: ai2.id }); } } /** * 处理音频接触 */ private handleAudioContact(ai1: AIComponent, ai2: AIComponent, distance: number): void { const soundVolume = 1.0 - (distance / ai1.config.capabilities.hearingRange); ai1.perception.audibleSounds.push({ source: ai2.entity.getComponent(Transform)!.position.clone(), volume: soundVolume, type: 'movement', timestamp: Date.now() }); } /** * 系统初始化时调用 */ public initialize(): void { super.initialize(); console.log('🤖 AI系统已启动'); } /** * 获取系统统计信息 */ public getSystemStats(): any { return { processedEntities: this.processedEntityCount, stateTransitions: this.stateTransitionCount, systemName: 'AISystem' }; } }