forked from Rowland/EG
285 lines
8.6 KiB
Python
285 lines
8.6 KiB
Python
#!/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() |