EG/demo/script_system_demo.py
2025-07-10 09:19:51 +08:00

285 lines
8.6 KiB
Python
Raw 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.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
脚本系统演示
展示如何使用脚本系统创建、加载、挂载和管理脚本
"""
import sys
import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from main import MyWorld
def test_script_system():
"""测试脚本系统的所有功能"""
print("=== 脚本系统演示开始 ===\n")
# 创建世界实例
world = MyWorld()
# 1. 启动脚本系统
print("1. 启动脚本系统")
world.startScriptSystem()
print()
# 2. 创建测试脚本
print("2. 创建测试脚本")
script_path1 = world.createScript("test_rotation", "basic")
script_path2 = world.createScript("test_movement", "movement")
print(f"创建的脚本文件:")
print(f" - {script_path1}")
print(f" - {script_path2}")
print()
# 3. 加载脚本
print("3. 加载脚本")
world.loadAllScripts()
# 显示可用脚本
available_scripts = world.getAvailableScripts()
print(f"可用脚本: {available_scripts}")
print()
# 4. 创建测试对象
print("4. 创建测试对象")
test_object1 = world.render.attachNewNode("TestObject1")
test_object1.setPos(0, 10, 0)
test_object2 = world.render.attachNewNode("TestObject2")
test_object2.setPos(5, 10, 0)
print(f"创建测试对象: {test_object1.getName()}, {test_object2.getName()}")
print()
# 5. 为对象添加脚本
print("5. 为对象添加脚本")
if "ExampleScript" in available_scripts:
script_comp1 = world.addScript(test_object1, "ExampleScript")
print(f"{test_object1.getName()} 添加 ExampleScript")
if "TestRotation" in available_scripts:
script_comp2 = world.addScript(test_object2, "TestRotation")
print(f"{test_object2.getName()} 添加 TestRotation")
print()
# 6. 查看脚本信息
print("6. 查看脚本信息")
for script_name in available_scripts:
script_info = world.getScriptInfo(script_name)
if script_info:
print(f"脚本: {script_name}")
print(f" 文档: {script_info.get('doc', '')}")
print(f" 文件: {script_info.get('file', '')}")
print(f" 方法: {script_info.get('methods', [])}")
print()
# 7. 检查对象上的脚本
print("7. 检查对象上的脚本")
scripts_on_obj1 = world.getScripts(test_object1)
scripts_on_obj2 = world.getScripts(test_object2)
print(f"{test_object1.getName()} 上的脚本数量: {len(scripts_on_obj1)}")
for script_comp in scripts_on_obj1:
script_name = script_comp.script_instance.__class__.__name__
print(f" - {script_name} (启用: {script_comp.enabled})")
print(f"{test_object2.getName()} 上的脚本数量: {len(scripts_on_obj2)}")
for script_comp in scripts_on_obj2:
script_name = script_comp.script_instance.__class__.__name__
print(f" - {script_name} (启用: {script_comp.enabled})")
print()
# 8. 列出所有脚本状态
print("8. 脚本系统整体状态")
world.listAllScripts()
# 9. 模拟运行一段时间(让脚本执行)
print("9. 模拟脚本运行5秒")
print("观察控制台输出...")
import time
start_time = time.time()
# 手动调用几次更新来模拟游戏循环
for i in range(10):
# 模拟脚本更新
dt = 0.5 # 假设每次0.5秒
for script_comp in world.script_manager.engine.script_components:
if not script_comp._started:
script_comp.start()
script_comp.update(dt)
time.sleep(0.5)
print(f" 更新 {i+1}/10 完成")
print()
# 10. 脚本控制演示
print("10. 脚本控制演示")
if scripts_on_obj1:
script_comp = scripts_on_obj1[0]
print(f"禁用脚本: {script_comp.script_instance.__class__.__name__}")
script_comp.set_enabled(False)
time.sleep(1)
print(f"重新启用脚本: {script_comp.script_instance.__class__.__name__}")
script_comp.set_enabled(True)
print()
# 11. 移除脚本
print("11. 移除脚本")
if scripts_on_obj1:
script_name = scripts_on_obj1[0].script_instance.__class__.__name__
success = world.removeScript(test_object1, script_name)
print(f"{test_object1.getName()} 移除 {script_name}: {'成功' if success else '失败'}")
print()
# 12. 热重载演示
print("12. 热重载演示")
print("热重载功能已启用修改scripts目录中的.py文件会自动重新加载")
print("当前热重载状态:", "启用" if world.script_manager.hot_reload_enabled else "禁用")
print()
# 13. 清理
print("13. 清理和停止")
world.stopScriptSystem()
print("=== 脚本系统演示完成 ===")
def create_custom_script_example():
"""创建自定义脚本示例"""
print("\n=== 创建自定义脚本示例 ===")
# 确保scripts目录存在
scripts_dir = "scripts"
if not os.path.exists(scripts_dir):
os.makedirs(scripts_dir)
# 创建一个更复杂的示例脚本
custom_script_content = '''#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Custom Script - 自定义复杂脚本示例
展示脚本的高级功能
"""
from core.script_system import ScriptBase
import math
class CustomScript(ScriptBase):
"""自定义脚本类 - 展示高级功能"""
def __init__(self):
super().__init__()
self.time = 0.0
self.amplitude = 2.0 # 振幅
self.frequency = 1.0 # 频率
self.original_pos = None
self.rotation_speed = 45.0 # 旋转速度(度/秒)
def start(self):
"""脚本开始时调用"""
self.log("CustomScript 开始运行!")
if self.transform:
self.original_pos = self.transform.getPos()
self.log(f"记录原始位置: {self.original_pos}")
def update(self, dt):
"""每帧更新 - 实现复杂的运动模式"""
if not self.transform or not self.original_pos:
return
self.time += dt
# 正弦波运动 + 旋转
offset_y = math.sin(self.time * self.frequency) * self.amplitude
offset_z = math.cos(self.time * self.frequency * 0.5) * self.amplitude * 0.5
# 更新位置
new_pos = (
self.original_pos.x,
self.original_pos.y + offset_y,
self.original_pos.z + offset_z
)
self.transform.setPos(*new_pos)
# 旋转
current_h = self.transform.getH()
new_h = current_h + self.rotation_speed * dt
self.transform.setH(new_h)
# 每5秒输出一次状态
if int(self.time) % 5 == 0 and int(self.time * 10) % 10 == 0:
self.log(f"运行时间: {self.time:.1f}s, 位置: {new_pos}")
def on_destroy(self):
"""脚本销毁时调用"""
self.log("CustomScript 被销毁")
# 恢复原始位置
if self.transform and self.original_pos:
self.transform.setPos(self.original_pos)
self.log("已恢复原始位置")
def on_enable(self):
"""脚本启用时调用"""
self.log("CustomScript 被启用")
def on_disable(self):
"""脚本禁用时调用"""
self.log("CustomScript 被禁用")
'''
script_path = os.path.join(scripts_dir, "custom_script.py")
with open(script_path, 'w', encoding='utf-8') as f:
f.write(custom_script_content)
print(f"✓ 创建自定义脚本: {script_path}")
return script_path
def usage_examples():
"""使用示例"""
print("\n=== 脚本系统使用示例 ===")
print("""
# 基本使用流程:
1. 启动脚本系统
world.startScriptSystem()
2. 创建脚本文件
script_path = world.createScript("my_script", "basic")
3. 加载脚本
world.loadAllScripts()
4. 为对象添加脚本
my_object = world.render.attachNewNode("MyObject")
world.addScript(my_object, "MyScript")
5. 管理脚本
scripts = world.getScripts(my_object)
world.removeScript(my_object, "MyScript")
# 高级功能:
- 热重载:修改脚本文件会自动重新加载
- 脚本调试:通过控制台查看脚本状态
- 脚本模板:支持多种脚本模板
- 生命周期管理完整的start/update/destroy循环
""")
if __name__ == "__main__":
# 创建自定义脚本示例
create_custom_script_example()
# 运行演示
test_script_system()
# 显示使用示例
usage_examples()