EG/plugins/user/particle_system/plugin.py
2025-12-12 16:16:15 +08:00

411 lines
14 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
粒子系统插件主文件
"""
from plugins.plugin_manager import BasePlugin
from .core.particle_manager import ParticleManager
from .editor.particle_editor import ParticleEditor
from .tools.performance_monitor import PerformanceMonitor
from .editor.preset_manager import PresetManager
class Plugin(BasePlugin):
"""
粒子系统插件
提供完整的3D粒子特效功能
"""
def __init__(self, plugin_manager, name):
super().__init__(plugin_manager, name)
self.config = {
"version": "1.0.0",
"author": "EG Team",
"description": "高性能3D粒子系统插件支持火焰、烟雾、爆炸等多种特效"
}
# 核心组件
self.particle_manager = None
self.particle_editor = None
self.performance_monitor = None
self.preset_manager = None
# GUI元素
self.gui_elements = []
# 事件处理器
self.event_handlers = {}
# 插件状态
self.is_initialized = False
self.is_enabled = False
def initialize(self) -> bool:
"""
初始化插件
"""
try:
if self.is_initialized:
return True
print(f"初始化粒子系统插件: {self.name}")
# 初始化粒子管理器
self.particle_manager = ParticleManager(self.plugin_manager.world)
# 初始化性能监控器
self.performance_monitor = PerformanceMonitor(self.particle_manager)
# 初始化粒子编辑器
self.particle_editor = ParticleEditor(
self.plugin_manager.world,
self.particle_manager
)
# 初始化预设管理器
self.preset_manager = PresetManager()
self.is_initialized = True
print("✓ 粒子系统插件初始化完成")
return True
except Exception as e:
print(f"✗ 粒子系统插件初始化失败: {e}")
return False
def enable(self) -> bool:
"""
启用插件
"""
if not super().enable():
return False
if self.is_enabled:
return True
try:
print(f"启用粒子系统插件: {self.name}")
# 启用粒子管理器
if self.particle_manager:
self.particle_manager.enable()
# 注册事件处理器
self._register_event_handlers()
# 创建GUI界面
self._create_gui()
# 启动性能监控
if self.performance_monitor:
self.performance_monitor.start()
self.is_enabled = True
print("✓ 粒子系统插件启用成功")
return True
except Exception as e:
print(f"✗ 粒子系统插件启用失败: {e}")
return False
def disable(self) -> bool:
"""
禁用插件
"""
if not super().disable():
return False
if not self.is_enabled:
return True
try:
print(f"禁用粒子系统插件: {self.name}")
# 停止性能监控
if self.performance_monitor:
self.performance_monitor.stop()
# 清理GUI界面
self._cleanup_gui()
# 移除事件处理器
self._unregister_event_handlers()
# 禁用粒子管理器
if self.particle_manager:
self.particle_manager.disable()
self.is_enabled = False
print("✓ 粒子系统插件禁用成功")
return True
except Exception as e:
print(f"✗ 粒子系统插件禁用失败: {e}")
return False
def finalize(self):
"""
清理插件资源
"""
print(f"清理粒子系统插件资源: {self.name}")
# 清理所有组件
if self.particle_editor:
self.particle_editor.cleanup()
self.particle_editor = None
if self.performance_monitor:
self.performance_monitor.cleanup()
self.performance_monitor = None
if self.particle_manager:
self.particle_manager.cleanup()
self.particle_manager = None
if self.preset_manager:
self.preset_manager = None
self.is_initialized = False
self.is_enabled = False
def _register_event_handlers(self):
"""
注册事件处理器
"""
world = self.plugin_manager.world
# 粒子系统控制快捷键
self.event_handlers['f5'] = self.toggle_particle_editor
self.event_handlers['f6'] = self.toggle_performance_monitor
self.event_handlers['f7'] = self.create_test_particles
self.event_handlers['f8'] = self.clear_all_particles
self.event_handlers['f9'] = self.create_fire_effect
self.event_handlers['f10'] = self.create_smoke_effect
self.event_handlers['f11'] = self.create_explosion_effect
self.event_handlers['f12'] = self.create_water_effect
# 注册事件
for event, handler in self.event_handlers.items():
world.accept(event, handler)
world.accept(event.upper(), handler) # 同时注册大写事件
def _unregister_event_handlers(self):
"""
移除事件处理器
"""
world = self.plugin_manager.world
for event in self.event_handlers.keys():
world.ignore(event)
world.ignore(event.upper())
self.event_handlers.clear()
def _create_gui(self):
"""
创建GUI界面
"""
try:
world = self.plugin_manager.world
# 检查是否有GUI管理器
if not hasattr(world, 'gui_manager') or not world.gui_manager:
print("⚠ GUI管理器不可用跳过GUI创建")
return
gui_manager = world.gui_manager
# 创建粒子系统控制面板
panel_button = gui_manager.createGUIButton(
pos=(0.02, 0, 0.95),
text="粒子系统",
size=0.06
)
self.gui_elements.append(panel_button)
# 创建快速效果按钮
effects = [
("火焰 [F9]", self.create_fire_effect),
("烟雾 [F10]", self.create_smoke_effect),
("爆炸 [F11]", self.create_explosion_effect),
("水花 [F12]", self.create_water_effect),
("测试 [F7]", self.create_test_particles),
("清除 [F8]", self.clear_all_particles)
]
for i, (name, callback) in enumerate(effects):
button = gui_manager.createGUIButton(
pos=(0.02, 0, 0.88 - i * 0.07),
text=name,
size=0.05
)
self.gui_elements.append(button)
world.accept(f"particle_effect_{name}", callback)
# 创建工具按钮
tools = [
("编辑器 [F5]", self.toggle_particle_editor),
("性能监控 [F6]", self.toggle_performance_monitor)
]
for i, (name, callback) in enumerate(tools):
button = gui_manager.createGUIButton(
pos=(0.02, 0, 0.40 - i * 0.07),
text=name,
size=0.05
)
self.gui_elements.append(button)
except Exception as e:
print(f"⚠ GUI创建失败: {e}")
def _cleanup_gui(self):
"""
清理GUI界面
"""
try:
world = self.plugin_manager.world
if hasattr(world, 'gui_manager') and world.gui_manager:
gui_manager = world.gui_manager
# 删除所有GUI元素
for element in self.gui_elements:
gui_manager.deleteGUIElement(element)
self.gui_elements.clear()
except Exception as e:
print(f"⚠ GUI清理失败: {e}")
# 事件处理方法
def toggle_particle_editor(self):
"""切换粒子编辑器显示"""
if self.particle_editor:
self.particle_editor.toggle_visibility()
def toggle_performance_monitor(self):
"""切换性能监控器显示"""
if self.performance_monitor:
self.performance_monitor.toggle_display()
def create_test_particles(self):
"""创建测试粒子"""
if self.particle_manager:
self.particle_manager.create_test_effect()
def clear_all_particles(self):
"""清除所有粒子"""
if self.particle_manager:
self.particle_manager.clear_all_particles()
def create_fire_effect(self):
"""创建火焰效果"""
if self.particle_manager:
self.particle_manager.create_fire_effect()
def create_smoke_effect(self):
"""创建烟雾效果"""
if self.particle_manager:
self.particle_manager.create_smoke_effect()
def create_explosion_effect(self):
"""创建爆炸效果"""
if self.particle_manager:
self.particle_manager.create_explosion_effect()
def create_water_effect(self):
"""创建水花效果"""
if self.particle_manager:
self.particle_manager.create_water_effect()
def create_magic_effect(self):
"""创建魔法效果"""
if self.particle_manager:
self.particle_manager.create_magic_effect()
def create_snow_effect(self):
"""创建雪花效果"""
if self.particle_manager:
self.particle_manager.create_snow_effect()
def get_info(self) -> dict:
"""
获取插件信息
"""
info = super().get_info()
info.update({
"version": self.config.get("version", "1.0.0"),
"author": self.config.get("author", "EG Team"),
"description": self.config.get("description", "粒子系统插件"),
"particle_count": self.particle_manager.get_particle_count() if self.particle_manager else 0,
"active_emitters": self.particle_manager.get_emitter_count() if self.particle_manager else 0,
"is_enabled": self.is_enabled,
"is_initialized": self.is_initialized
})
return info
# 高级功能接口
def load_preset(self, preset_name: str):
"""加载预设效果"""
if self.preset_manager and self.particle_manager:
config = self.preset_manager.get_preset_config(preset_name)
if config:
# 在摄像机前方创建效果
camera_pos = self.plugin_manager.world.camera.getPos()
camera_forward = self.plugin_manager.world.camera.getNetTransform().getMat().getRow3(1)
position = camera_pos + camera_forward * 5
self.particle_manager.create_emitter(
config.get('emitter_type', 'default'),
position,
config
)
print(f"✓ 加载预设: {preset_name}")
else:
print(f"✗ 预设未找到: {preset_name}")
def save_current_as_preset(self, preset_name: str, description: str = ""):
"""保存当前效果为预设"""
if self.preset_manager and self.particle_editor:
config = self.particle_editor.get_current_config()
if config:
success = self.preset_manager.save_preset(
preset_name,
config,
description
)
if success:
print(f"✓ 保存预设: {preset_name}")
else:
print(f"✗ 保存预设失败: {preset_name}")
else:
print("✗ 没有可保存的配置")
def list_presets(self):
"""列出所有预设"""
if self.preset_manager:
presets = self.preset_manager.list_presets()
print("可用预设:")
for preset in presets:
print(f" - {preset}")
return presets
return []
def set_global_time_scale(self, scale: float):
"""设置全局时间缩放"""
if self.particle_manager:
self.particle_manager.set_global_time_scale(scale)
def set_max_particles(self, max_count: int):
"""设置最大粒子数"""
if self.particle_manager:
self.particle_manager.set_max_particles(max_count)
def set_emit_rate_multiplier(self, multiplier: float):
"""设置发射速率倍增器"""
if self.particle_manager:
self.particle_manager.set_emit_rate_multiplier(multiplier)
def set_particle_size_multiplier(self, multiplier: float):
"""设置粒子尺寸倍增器"""
if self.particle_manager:
self.particle_manager.set_particle_size_multiplier(multiplier)