""" 音频组件基类 提供音频组件的基础功能和接口 """ from abc import ABC, abstractmethod from typing import Dict, Any, Optional import uuid class AudioComponent(ABC): """ 音频组件基类 提供音频组件的基础功能和接口 """ def __init__(self, plugin, name: str = ""): """ 初始化音频组件 Args: plugin: 3D音频插件实例 name: 组件名称 """ self.plugin = plugin self.name = name if name else f"AudioComponent_{uuid.uuid4()}" self.enabled = True self.properties: Dict[str, Any] = {} @abstractmethod def initialize(self) -> bool: """ 初始化组件 Returns: 是否初始化成功 """ pass @abstractmethod def cleanup(self): """清理组件资源""" pass @abstractmethod def update(self, dt: float): """ 更新组件状态 Args: dt: 时间增量 """ pass def enable(self): """启用组件""" self.enabled = True def disable(self): """禁用组件""" self.enabled = False def is_enabled(self) -> bool: """ 检查组件是否启用 Returns: 是否启用 """ return self.enabled def set_property(self, name: str, value: Any) -> bool: """ 设置属性 Args: name: 属性名 value: 属性值 Returns: 是否设置成功 """ try: self.properties[name] = value return True except Exception: return False def get_property(self, name: str, default: Any = None) -> Any: """ 获取属性 Args: name: 属性名 default: 默认值 Returns: 属性值 """ return self.properties.get(name, default) def remove_property(self, name: str) -> bool: """ 移除属性 Args: name: 属性名 Returns: 是否移除成功 """ if name in self.properties: del self.properties[name] return True return False def get_all_properties(self) -> Dict[str, Any]: """ 获取所有属性 Returns: 属性字典 """ return self.properties.copy() class AudioSourceComponent(AudioComponent): """ 音频源组件 用于为游戏对象添加音频播放功能 """ def __init__(self, plugin, name: str = ""): super().__init__(plugin, name) self.sound_id: Optional[str] = None self.spatial = False self.loop = False self.volume = 1.0 self.attached_object = None def initialize(self) -> bool: """初始化音频源组件""" # 音频源组件在需要时才创建音效 return True def cleanup(self): """清理音频源组件""" if self.sound_id: self.plugin.audio_source_manager.delete_sound(self.sound_id) self.sound_id = None def update(self, dt: float): """更新音频源组件""" if not self.enabled: return # 如果附加到对象,同步位置 if self.attached_object and self.sound_id and self.spatial: pos = self.attached_object.getPos() self.plugin.audio_source_manager.set_sound_position( self.sound_id, (pos.x, pos.y, pos.z)) def load_sound(self, filepath: str, spatial: bool = False, loop: bool = False, volume: float = 1.0) -> bool: """ 加载音频文件 Args: filepath: 音频文件路径 spatial: 是否为3D音效 loop: 是否循环播放 volume: 音量 Returns: 是否加载成功 """ try: # 删除现有音效 if self.sound_id: self.plugin.audio_source_manager.delete_sound(self.sound_id) # 创建新音效 if spatial: pos = (0, 0, 0) if self.attached_object: obj_pos = self.attached_object.getPos() pos = (obj_pos.x, obj_pos.y, obj_pos.z) self.sound_id = self.plugin.audio_source_manager.create_3d_sound( filepath, pos, loop, volume) else: self.sound_id = self.plugin.audio_source_manager.create_2d_sound( filepath, loop, volume) if self.sound_id: self.spatial = spatial self.loop = loop self.volume = volume return True else: return False except Exception as e: print(f"✗ 加载音频文件失败: {e}") return False def play(self) -> bool: """ 播放音效 Returns: 是否播放成功 """ if self.sound_id: return self.plugin.audio_source_manager.play_sound(self.sound_id) return False def stop(self) -> bool: """ 停止音效 Returns: 是否停止成功 """ if self.sound_id: return self.plugin.audio_source_manager.stop_sound(self.sound_id) return False def pause(self) -> bool: """ 暂停音效 Returns: 是否暂停成功 """ if self.sound_id: return self.plugin.audio_source_manager.pause_sound(self.sound_id) return False def resume(self) -> bool: """ 恢复音效 Returns: 是否恢复成功 """ if self.sound_id: return self.plugin.audio_source_manager.resume_sound(self.sound_id) return False def is_playing(self) -> bool: """ 检查音效是否正在播放 Returns: 是否正在播放 """ if self.sound_id: return self.plugin.audio_source_manager.is_sound_playing(self.sound_id) return False def set_volume(self, volume: float) -> bool: """ 设置音量 Args: volume: 音量 (0.0-1.0) Returns: 是否设置成功 """ if self.sound_id: success = self.plugin.audio_source_manager.set_sound_volume(self.sound_id, volume) if success: self.volume = volume return success return False def set_loop(self, loop: bool) -> bool: """ 设置循环模式 Args: loop: 是否循环 Returns: 是否设置成功 """ if self.sound_id: success = self.plugin.audio_source_manager.set_sound_loop(self.sound_id, loop) if success: self.loop = loop return success return False def attach_to_object(self, obj): """ 附加到游戏对象 Args: obj: 游戏对象 """ self.attached_object = obj def detach_from_object(self): """从游戏对象分离""" self.attached_object = None class AudioListenerComponent(AudioComponent): """ 音频听者组件 用于设置音频听者位置和方向 """ def __init__(self, plugin, name: str = ""): super().__init__(plugin, name) self.attached_object = None def initialize(self) -> bool: """初始化音频听者组件""" return True def cleanup(self): """清理音频听者组件""" pass def update(self, dt: float): """更新音频听者组件""" if not self.enabled: return # 如果附加到对象,同步位置和方向 if self.attached_object: pos = self.attached_object.getPos() hpr = self.attached_object.getHpr() self.plugin.set_listener_position((pos.x, pos.y, pos.z)) self.plugin.set_listener_orientation((hpr.x, hpr.y, hpr.z)) def attach_to_object(self, obj): """ 附加到游戏对象 Args: obj: 游戏对象 """ self.attached_object = obj def detach_from_object(self): """从游戏对象分离""" self.attached_object = None class AudioEffectComponent(AudioComponent): """ 音频效果组件 用于为音频源应用效果 """ def __init__(self, plugin, name: str = ""): super().__init__(plugin, name) self.effect_id: Optional[str] = None self.effect_type = "" self.target_sound_id: Optional[str] = None def initialize(self) -> bool: """初始化音频效果组件""" return True def cleanup(self): """清理音频效果组件""" if self.effect_id: self.plugin.audio_effect_processor.delete_effect(self.effect_id) self.effect_id = None def update(self, dt: float): """更新音频效果组件""" if not self.enabled: return def create_effect(self, effect_type: str, parameters: Dict[str, Any]) -> bool: """ 创建音频效果 Args: effect_type: 效果类型 parameters: 效果参数 Returns: 是否创建成功 """ try: # 删除现有效果 if self.effect_id: self.plugin.audio_effect_processor.delete_effect(self.effect_id) # 创建新效果 self.effect_id = self.plugin.audio_effect_processor.create_effect( effect_type, parameters) if self.effect_id: self.effect_type = effect_type return True else: return False except Exception as e: print(f"✗ 创建音频效果失败: {e}") return False def apply_to_sound(self, sound_id: str) -> bool: """ 应用效果到音效 Args: sound_id: 音源ID Returns: 是否应用成功 """ if self.effect_id: success = self.plugin.audio_effect_processor.apply_effect_to_sound( sound_id, self.effect_id) if success: self.target_sound_id = sound_id return success return False def remove_from_sound(self, sound_id: str) -> bool: """ 从音效移除效果 Args: sound_id: 音源ID Returns: 是否移除成功 """ if self.effect_id: success = self.plugin.audio_effect_processor.remove_effect_from_sound( sound_id, self.effect_id) if success and self.target_sound_id == sound_id: self.target_sound_id = None return success return False def set_parameter(self, parameter: str, value: Any) -> bool: """ 设置效果参数 Args: parameter: 参数名 value: 参数值 Returns: 是否设置成功 """ if self.effect_id: return self.plugin.audio_effect_processor.set_effect_parameter( self.effect_id, parameter, value) return False