verify_sync.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. 验证Excel文件与JSON文件的同步状态
  5. """
  6. import json
  7. import pandas as pd
  8. from pathlib import Path
  9. def load_json_data():
  10. """加载JSON数据"""
  11. json_file = Path('../enemies.json')
  12. try:
  13. with open(json_file, 'r', encoding='utf-8') as f:
  14. return json.load(f)
  15. except Exception as e:
  16. print(f"❌ 加载JSON文件失败: {e}")
  17. return None
  18. def load_excel_data():
  19. """加载Excel数据"""
  20. excel_file = Path('敌人配置表.xlsx')
  21. if not excel_file.exists():
  22. print(f"❌ Excel文件不存在: {excel_file}")
  23. return None
  24. try:
  25. # 读取所有工作表
  26. excel_data = pd.read_excel(excel_file, sheet_name=None)
  27. return excel_data
  28. except Exception as e:
  29. print(f"❌ 加载Excel文件失败: {e}")
  30. return None
  31. def verify_basic_config(json_data, excel_data):
  32. """验证基础配置"""
  33. print("\n🔍 验证敌人基础配置...")
  34. json_enemies = {enemy['id']: enemy for enemy in json_data.get('enemies', [])}
  35. excel_basic = excel_data.get('敌人基础配置')
  36. if excel_basic is None:
  37. print("❌ Excel中缺少'敌人基础配置'工作表")
  38. return False
  39. success = True
  40. for _, row in excel_basic.iterrows():
  41. enemy_id = row['敌人ID']
  42. if enemy_id not in json_enemies:
  43. print(f"❌ Excel中的敌人ID '{enemy_id}' 在JSON中不存在")
  44. success = False
  45. continue
  46. json_enemy = json_enemies[enemy_id]
  47. # 验证关键字段
  48. checks = [
  49. ('敌人名称', json_enemy['name']),
  50. ('敌人类型', json_enemy['type']),
  51. ('生命值', json_enemy['stats']['health']),
  52. ('攻击力', json_enemy['stats']['attack']),
  53. ('防御力', json_enemy['stats']['defense']),
  54. ('移动速度', json_enemy['stats']['speed'])
  55. ]
  56. for field, expected in checks:
  57. actual = row[field]
  58. if actual != expected:
  59. print(f"⚠️ {enemy_id} 的 {field}: Excel={actual}, JSON={expected}")
  60. success = False
  61. if success:
  62. print("✅ 敌人基础配置验证通过")
  63. return success
  64. def verify_visual_config(json_data, excel_data):
  65. """验证视觉配置"""
  66. print("\n🎬 验证视觉配置...")
  67. json_enemies = {enemy['id']: enemy for enemy in json_data.get('enemies', [])}
  68. excel_visual = excel_data.get('视觉配置')
  69. if excel_visual is None:
  70. print("❌ Excel中缺少'视觉配置'工作表")
  71. return False
  72. success = True
  73. animation_count = 0
  74. for _, row in excel_visual.iterrows():
  75. enemy_id = row['敌人ID']
  76. if enemy_id not in json_enemies:
  77. continue
  78. json_visual = json_enemies[enemy_id].get('visualConfig', {})
  79. # 验证精灵路径
  80. sprite_path = row['精灵路径']
  81. expected_sprite = json_visual.get('spritePath', '')
  82. if sprite_path != expected_sprite:
  83. print(f"⚠️ {enemy_id} 精灵路径不匹配: Excel={sprite_path}, JSON={expected_sprite}")
  84. success = False
  85. # 检查动画路径格式
  86. if '@EnemyAni' in sprite_path:
  87. animation_count += 1
  88. print(f" ✅ {enemy_id}: {sprite_path}")
  89. else:
  90. print(f" ⚠️ {enemy_id}: 动画路径格式不正确 - {sprite_path}")
  91. success = False
  92. # 验证动画配置
  93. animations = json_visual.get('animations', {})
  94. animation_fields = ['待机动画', '行走动画', '攻击动画', '死亡动画']
  95. animation_keys = ['idle', 'walk', 'attack', 'death']
  96. for field, key in zip(animation_fields, animation_keys):
  97. excel_anim = row[field]
  98. json_anim = animations.get(key, '')
  99. if excel_anim != json_anim:
  100. print(f"⚠️ {enemy_id} {field}不匹配: Excel={excel_anim}, JSON={json_anim}")
  101. success = False
  102. print(f"\n📊 动画配置统计: {animation_count}/11 个敌人配置了EnemyAni动画路径")
  103. if success:
  104. print("✅ 视觉配置验证通过")
  105. return success
  106. def verify_combat_config(json_data, excel_data):
  107. """验证战斗配置"""
  108. print("\n⚔️ 验证战斗配置...")
  109. json_enemies = {enemy['id']: enemy for enemy in json_data.get('enemies', [])}
  110. excel_combat = excel_data.get('战斗配置')
  111. if excel_combat is None:
  112. print("❌ Excel中缺少'战斗配置'工作表")
  113. return False
  114. success = True
  115. attack_types = set()
  116. for _, row in excel_combat.iterrows():
  117. enemy_id = row['敌人ID']
  118. if enemy_id not in json_enemies:
  119. continue
  120. json_combat = json_enemies[enemy_id].get('combat', {})
  121. # 验证攻击类型
  122. attack_type = row['攻击类型']
  123. expected_type = json_combat.get('attackType', 'melee')
  124. attack_types.add(attack_type)
  125. if attack_type != expected_type:
  126. print(f"⚠️ {enemy_id} 攻击类型不匹配: Excel={attack_type}, JSON={expected_type}")
  127. success = False
  128. # 验证武器类型
  129. weapon_type = row['武器类型']
  130. expected_weapon = json_combat.get('weaponType', 'none')
  131. if weapon_type != expected_weapon:
  132. print(f"⚠️ {enemy_id} 武器类型不匹配: Excel={weapon_type}, JSON={expected_weapon}")
  133. success = False
  134. print(f"\n📊 攻击类型统计: {', '.join(sorted(attack_types))}")
  135. if success:
  136. print("✅ 战斗配置验证通过")
  137. return success
  138. def verify_movement_config(json_data, excel_data):
  139. """验证移动配置"""
  140. print("\n🚶 验证移动配置...")
  141. json_enemies = {enemy['id']: enemy for enemy in json_data.get('enemies', [])}
  142. excel_movement = excel_data.get('移动配置')
  143. if excel_movement is None:
  144. print("❌ Excel中缺少'移动配置'工作表")
  145. return False
  146. success = True
  147. move_types = set()
  148. for _, row in excel_movement.iterrows():
  149. enemy_id = row['敌人ID']
  150. if enemy_id not in json_enemies:
  151. continue
  152. json_movement = json_enemies[enemy_id].get('movement', {})
  153. # 验证移动类型
  154. move_type = row['移动类型']
  155. expected_type = json_movement.get('moveType', 'straight')
  156. move_types.add(move_type)
  157. if move_type != expected_type:
  158. print(f"⚠️ {enemy_id} 移动类型不匹配: Excel={move_type}, JSON={expected_type}")
  159. success = False
  160. # 验证移动模式
  161. pattern = row['移动模式']
  162. expected_pattern = json_movement.get('pattern', 'walk_forward')
  163. if pattern != expected_pattern:
  164. print(f"⚠️ {enemy_id} 移动模式不匹配: Excel={pattern}, JSON={expected_pattern}")
  165. success = False
  166. print(f"\n📊 移动类型统计: {', '.join(sorted(move_types))}")
  167. if success:
  168. print("✅ 移动配置验证通过")
  169. return success
  170. def main():
  171. """主函数"""
  172. print("🔍 开始验证Excel与JSON文件的同步状态...")
  173. # 加载数据
  174. json_data = load_json_data()
  175. excel_data = load_excel_data()
  176. if not json_data or not excel_data:
  177. return False
  178. print(f"\n📊 数据概览:")
  179. print(f" JSON敌人数量: {len(json_data.get('enemies', []))}")
  180. print(f" Excel工作表数量: {len(excel_data)}")
  181. print(f" Excel工作表: {', '.join(excel_data.keys())}")
  182. # 执行验证
  183. all_passed = True
  184. all_passed &= verify_basic_config(json_data, excel_data)
  185. all_passed &= verify_visual_config(json_data, excel_data)
  186. all_passed &= verify_combat_config(json_data, excel_data)
  187. all_passed &= verify_movement_config(json_data, excel_data)
  188. # 总结
  189. print("\n" + "="*50)
  190. if all_passed:
  191. print("🎉 验证完成!Excel文件与JSON文件完全同步")
  192. print("\n✅ 同步成功的内容:")
  193. print(" 📋 敌人基础信息 (ID、名称、属性)")
  194. print(" 🎬 动画配置 (@EnemyAni路径和动画状态)")
  195. print(" ⚔️ 战斗配置 (攻击类型、武器、投射物)")
  196. print(" 🚶 移动配置 (移动模式和类型)")
  197. print(" 🔊 音频配置")
  198. print(" 🎯 特殊能力和BOSS配置")
  199. print("\n🎯 Excel配置表现在包含了完整的动画和战斗配置!")
  200. return True
  201. else:
  202. print("❌ 验证失败!发现数据不一致")
  203. return False
  204. if __name__ == '__main__':
  205. success = main()
  206. if not success:
  207. print("\n❌ 验证过程中发现问题,请检查上述错误信息")