""" 事件处理器模块 负责处理游戏事件并触发相应的触觉反馈 """ import time from typing import Dict, Any, List, Optional, Callable import threading class HapticEventHandler: """ 触觉事件处理器 负责处理游戏事件并触发相应的触觉反馈 """ def __init__(self, plugin): """ 初始化触觉事件处理器 Args: plugin: 触觉反馈系统插件实例 """ self.plugin = plugin self.enabled = False self.initialized = False # 事件映射配置 self.event_mapping = { # 游戏事件到触觉效果的映射 'player_jump': { 'effect': 'impulse', 'intensity': 0.6, 'frequency': 40.0, 'duration': 0.1, 'device': 'feet' }, 'player_land': { 'effect': 'rumble', 'intensity': 0.8, 'frequency': 30.0, 'duration': 0.2, 'device': 'feet' }, 'player_take_damage': { 'effect': 'explosion', 'intensity': 1.0, 'frequency': 50.0, 'duration': 0.5, 'device': 'body' }, 'player_heal': { 'effect': 'pulse', 'intensity': 0.5, 'frequency': 25.0, 'duration': 0.3, 'device': 'chest' }, 'weapon_fire': { 'effect': 'click', 'intensity': 0.7, 'frequency': 80.0, 'duration': 0.05, 'device': 'hands' }, 'weapon_reload': { 'effect': 'buzz', 'intensity': 0.4, 'frequency': 35.0, 'duration': 0.4, 'device': 'hands' }, 'enemy_hit': { 'effect': 'click', 'intensity': 0.5, 'frequency': 60.0, 'duration': 0.08, 'device': 'hands' }, 'enemy_death': { 'effect': 'explosion', 'intensity': 0.9, 'frequency': 45.0, 'duration': 0.6, 'device': 'body' }, 'pickup_item': { 'effect': 'pulse', 'intensity': 0.3, 'frequency': 20.0, 'duration': 0.2, 'device': 'hands' }, 'door_open': { 'effect': 'buzz', 'intensity': 0.3, 'frequency': 15.0, 'duration': 0.3, 'device': 'hands' }, 'door_close': { 'effect': 'click', 'intensity': 0.4, 'frequency': 25.0, 'duration': 0.1, 'device': 'hands' }, 'explosion': { 'effect': 'explosion', 'intensity': 1.0, 'frequency': 35.0, 'duration': 1.0, 'device': 'body' }, 'ui_button_click': { 'effect': 'click', 'intensity': 0.3, 'frequency': 100.0, 'duration': 0.05, 'device': 'hands' }, 'ui_button_hover': { 'effect': 'soft_rumble', 'intensity': 0.1, 'frequency': 10.0, 'duration': 0.1, 'device': 'hands' } } # 事件优先级配置 self.event_priority = { 'player_take_damage': 100, 'explosion': 90, 'enemy_death': 80, 'player_land': 70, 'weapon_fire': 60, 'player_jump': 50, 'enemy_hit': 40, 'pickup_item': 30, 'door_open': 20, 'door_close': 20, 'ui_button_click': 10, 'ui_button_hover': 5, 'player_heal': 40, 'weapon_reload': 30 } # 事件队列 self.event_queue = [] self.event_queue_lock = threading.Lock() # 事件抑制配置 self.event_suppression = { 'enable_suppression': True, 'suppression_time': 0.1, # 秒 'suppressed_events': set() } # 事件组合配置 self.event_combination = { 'enable_combination': True, 'combination_window': 0.5, # 秒 'max_combined_events': 5 } # 状态跟踪 self.event_state = { 'last_event_time': {}, 'combined_events': [], 'active_events': {} } # 统计信息 self.stats = { 'events_received': 0, 'events_processed': 0, 'events_suppressed': 0, 'events_combined': 0, 'haptic_effects_triggered': 0 } # 回调函数 self.event_callbacks = { 'event_received': [], 'event_processed': [], 'event_suppressed': [], 'event_combined': [] } print("✓ 触觉事件处理器已创建") def initialize(self) -> bool: """ 初始化触觉事件处理器 Returns: 是否初始化成功 """ try: self.initialized = True print("✓ 触觉事件处理器初始化完成") return True except Exception as e: print(f"✗ 触觉事件处理器初始化失败: {e}") import traceback traceback.print_exc() return False def enable(self) -> bool: """ 启用触觉事件处理器 Returns: 是否启用成功 """ try: if not self.initialized: print("✗ 触觉事件处理器未初始化") return False self.enabled = True print("✓ 触觉事件处理器已启用") return True except Exception as e: print(f"✗ 触觉事件处理器启用失败: {e}") import traceback traceback.print_exc() return False def disable(self): """禁用触觉事件处理器""" try: self.enabled = False print("✓ 触觉事件处理器已禁用") except Exception as e: print(f"✗ 触觉事件处理器禁用失败: {e}") import traceback traceback.print_exc() def finalize(self): """清理触觉事件处理器资源""" try: self.disable() self.event_mapping.clear() self.event_queue.clear() self.event_state.clear() self.event_callbacks.clear() self.initialized = False print("✓ 触觉事件处理器资源已清理") except Exception as e: print(f"✗ 触觉事件处理器资源清理失败: {e}") import traceback traceback.print_exc() def update(self, dt: float): """ 更新触觉事件处理器状态 Args: dt: 时间增量 """ try: if not self.enabled: return # 处理事件队列 self._process_event_queue() # 更新事件状态 self._update_event_state() except Exception as e: print(f"✗ 触觉事件处理器更新失败: {e}") import traceback traceback.print_exc() def _process_event_queue(self): """处理事件队列""" try: with self.event_queue_lock: if not self.event_queue: return # 获取事件并清空队列 events_to_process = self.event_queue[:] self.event_queue.clear() # 处理每个事件 for event in events_to_process: self._process_event(event) except Exception as e: print(f"✗ 事件队列处理失败: {e}") def _update_event_state(self): """更新事件状态""" try: current_time = time.time() # 清理过期的抑制事件 suppression_time = self.event_suppression['suppression_time'] expired_suppressions = [ event_type for event_type, timestamp in self.event_suppression['suppressed_events'] if current_time - timestamp > suppression_time ] for event_type in expired_suppressions: self.event_suppression['suppressed_events'].discard(event_type) # 清理过期的组合事件 combination_window = self.event_combination['combination_window'] self.event_state['combined_events'] = [ event for event in self.event_state['combined_events'] if current_time - event.get('timestamp', 0) <= combination_window ] except Exception as e: print(f"✗ 事件状态更新失败: {e}") def handle_event(self, event_type: str, event_data: Dict[str, Any] = None) -> bool: """ 处理事件 Args: event_type: 事件类型 event_data: 事件数据 Returns: 是否处理成功 """ try: if not self.enabled: return False # 创建事件对象 event = { 'type': event_type, 'data': event_data or {}, 'timestamp': time.time(), 'priority': self.event_priority.get(event_type, 50) } # 添加到事件队列 with self.event_queue_lock: self.event_queue.append(event) # 触发事件接收回调 self._trigger_event_callback('event_received', { 'event': event }) self.stats['events_received'] += 1 return True except Exception as e: print(f"✗ 事件处理失败: {e}") return False def _process_event(self, event: Dict[str, Any]): """ 处理单个事件 Args: event: 事件对象 """ try: event_type = event['type'] event_data = event['data'] timestamp = event['timestamp'] # 检查事件抑制 if self.event_suppression['enable_suppression']: if event_type in [e[0] for e in self.event_suppression['suppressed_events']]: # 事件被抑制 self.stats['events_suppressed'] += 1 # 触发抑制回调 self._trigger_event_callback('event_suppressed', { 'event': event }) return # 添加到抑制列表 self.event_suppression['suppressed_events'].add((event_type, timestamp)) # 检查事件组合 if self.event_combination['enable_combination']: self._handle_event_combination(event) # 处理事件映射 if event_type in self.event_mapping: self._trigger_haptic_effect(event_type, event_data) # 触发事件处理回调 self._trigger_event_callback('event_processed', { 'event': event }) self.stats['events_processed'] += 1 except Exception as e: print(f"✗ 单个事件处理失败: {e}") def _handle_event_combination(self, event: Dict[str, Any]): """ 处理事件组合 Args: event: 事件对象 """ try: current_time = time.time() combination_window = self.event_combination['combination_window'] # 添加到组合事件列表 self.event_state['combined_events'].append(event) # 保持列表大小 if len(self.event_state['combined_events']) > self.event_combination['max_combined_events']: self.event_state['combined_events'].pop(0) # 检查是否达到组合条件 if len(self.event_state['combined_events']) >= 3: # 检查时间窗口 oldest_event = self.event_state['combined_events'][0] if current_time - oldest_event['timestamp'] <= combination_window: # 触发组合事件回调 self._trigger_event_callback('event_combined', { 'events': self.event_state['combined_events'].copy() }) self.stats['events_combined'] += 1 # 清空组合事件列表 self.event_state['combined_events'].clear() except Exception as e: print(f"✗ 事件组合处理失败: {e}") def _trigger_haptic_effect(self, event_type: str, event_data: Dict[str, Any]): """ 触发触觉效果 Args: event_type: 事件类型 event_data: 事件数据 """ try: if not self.plugin.haptic_manager: return # 获取效果配置 effect_config = self.event_mapping.get(event_type) if not effect_config: return # 提取效果参数 effect_type = effect_config['effect'] intensity = effect_config['intensity'] frequency = effect_config['frequency'] duration = effect_config['duration'] device_type = effect_config.get('device') # 获取设备ID device_id = None if device_type and self.plugin.device_manager: devices = self.plugin.device_manager.get_devices_by_type(device_type) if devices: device_id = devices[0]['id'] # 应用事件数据中的参数覆盖 if 'intensity' in event_data: intensity *= event_data['intensity'] if 'frequency' in event_data: frequency *= event_data['frequency'] if 'duration' in event_data: duration *= event_data['duration'] # 播放触觉效果 effect_id = self.plugin.haptic_manager.play_effect( effect_type=effect_type, device_id=device_id, intensity=intensity, duration=duration, frequency=frequency, parameters={ 'event_type': event_type, 'event_data': event_data } ) if effect_id >= 0: self.stats['haptic_effects_triggered'] += 1 print(f"✓ 触觉效果已触发: {event_type} -> {effect_type}") except Exception as e: print(f"✗ 触觉效果触发失败: {e}") def register_event_mapping(self, event_type: str, effect_config: Dict[str, Any]) -> bool: """ 注册事件映射 Args: event_type: 事件类型 effect_config: 效果配置 Returns: 是否注册成功 """ try: self.event_mapping[event_type] = effect_config print(f"✓ 事件映射已注册: {event_type}") return True except Exception as e: print(f"✗ 事件映射注册失败: {e}") return False def unregister_event_mapping(self, event_type: str) -> bool: """ 注销事件映射 Args: event_type: 事件类型 Returns: 是否注销成功 """ try: if event_type in self.event_mapping: del self.event_mapping[event_type] print(f"✓ 事件映射已注销: {event_type}") return True else: print(f"✗ 事件映射不存在: {event_type}") return False except Exception as e: print(f"✗ 事件映射注销失败: {e}") return False def set_event_priority(self, event_type: str, priority: int) -> bool: """ 设置事件优先级 Args: event_type: 事件类型 priority: 优先级值 Returns: 是否设置成功 """ try: self.event_priority[event_type] = priority print(f"✓ 事件优先级已设置: {event_type} = {priority}") return True except Exception as e: print(f"✗ 事件优先级设置失败: {e}") return False def set_event_suppression(self, config: Dict[str, Any]) -> bool: """ 设置事件抑制配置 Args: config: 配置字典 Returns: 是否设置成功 """ try: self.event_suppression.update(config) print(f"✓ 事件抑制配置已更新: {self.event_suppression}") return True except Exception as e: print(f"✗ 事件抑制配置设置失败: {e}") return False def set_event_combination(self, config: Dict[str, Any]) -> bool: """ 设置事件组合配置 Args: config: 配置字典 Returns: 是否设置成功 """ try: self.event_combination.update(config) print(f"✓ 事件组合配置已更新: {self.event_combination}") return True except Exception as e: print(f"✗ 事件组合配置设置失败: {e}") return False def get_event_mapping(self) -> Dict[str, Dict[str, Any]]: """ 获取事件映射 Returns: 事件映射字典 """ return self.event_mapping.copy() def get_event_priority(self) -> Dict[str, int]: """ 获取事件优先级 Returns: 事件优先级字典 """ return self.event_priority.copy() def get_event_suppression_config(self) -> Dict[str, Any]: """ 获取事件抑制配置 Returns: 配置字典 """ return self.event_suppression.copy() def get_event_combination_config(self) -> Dict[str, Any]: """ 获取事件组合配置 Returns: 配置字典 """ return self.event_combination.copy() def _trigger_event_callback(self, callback_type: str, data: Dict[str, Any]): """ 触发事件回调 Args: callback_type: 回调类型 data: 回调数据 """ try: if callback_type in self.event_callbacks: for callback in self.event_callbacks[callback_type]: try: callback(data) except Exception as e: print(f"✗ 事件回调执行失败: {e}") except Exception as e: print(f"✗ 事件回调触发失败: {e}") def register_event_callback(self, callback_type: str, callback: Callable): """ 注册事件回调 Args: callback_type: 回调类型 callback: 回调函数 """ try: if callback_type in self.event_callbacks: self.event_callbacks[callback_type].append(callback) print(f"✓ 事件回调已注册: {callback_type}") else: print(f"✗ 无效的回调类型: {callback_type}") except Exception as e: print(f"✗ 事件回调注册失败: {e}") def unregister_event_callback(self, callback_type: str, callback: Callable): """ 注销事件回调 Args: callback_type: 回调类型 callback: 回调函数 """ try: if callback_type in self.event_callbacks: if callback in self.event_callbacks[callback_type]: self.event_callbacks[callback_type].remove(callback) print(f"✓ 事件回调已注销: {callback_type}") except Exception as e: print(f"✗ 事件回调注销失败: {e}") def get_stats(self) -> Dict[str, int]: """ 获取统计信息 Returns: 统计信息字典 """ return self.stats.copy() def reset_stats(self): """重置统计信息""" try: self.stats = { 'events_received': 0, 'events_processed': 0, 'events_suppressed': 0, 'events_combined': 0, 'haptic_effects_triggered': 0 } print("✓ 事件处理器统计信息已重置") except Exception as e: print(f"✗ 事件处理器统计信息重置失败: {e}")